# 饲喂标准管理 — 技术方案

> 依据：`饲喂标准管理功能需求.md`（同目录）。状态机、知识库语义与《养殖标准管理技术方案》对齐；本文仅给出**饲喂标准管理**本模块的库表与接口约定，与其它业务模块实现相互独立。

---

## 1. 技术架构

| 项 | 说明 |
| --- | --- |
| **后端** | RuoYi **v3.9.2**（**springboot2** 分支）：JDK 8、Spring Boot 2.x、Spring MVC、MyBatis、Druid |
| **数据库** | MySQL **5.7.39**，InnoDB，`utf8mb4` |
| **前端** | 若依 Vue2（与分支配套，路由与权限按项目惯例配置） |
| **文件** | 复用 RuoYi 上传（`/common/upload` 等）；表内存 URL、存储路径、正文原始文件名；**不入库**文件大小 |
| **知识库** | HTTP 调用知识库后台管理服务；URL、鉴权、具体路径见《知识库接口对接说明》，调用时机与操作类型语义与养殖标准方案 **§4.2** 一致（添加 / 删除 / 下架可见性） |

**分层**：`Controller`（校验、权限、`AjaxResult`/`TableDataInfo`）→ `Service`（状态机、事务、知识库编排、删文件）→ `Mapper`/XML → `domain`。

**一致性（摘要）**

- 修改：**仅** `publish_status=0` 且 `kb_sync_status=0`；**不**自动推库（已同步须先移出）。  
- **下架**：`publish_status=0`，`kb_sync_status=1`，保留 `kb_doc_id`；知识库侧**不删条目**，仅结束对外可见/检索。  
- **移出**：通知知识库删除后，`kb_sync_status=0`，清空 `kb_doc_id`。  
- **删除**：`kb_sync_status=0` 可直接删；`publish_status=0` 且 `kb_sync_status=1` 须先移出或接口内联动删库条目后再删本地。

---

## 2. 数据库设计

### 2.1 表 `biz_feeding_standard`

| 字段 | 类型 | 非空 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| `id` | `bigint(20)` | Y | 自增 | 主键 |
| `standard_name` | `varchar(64)` | Y | — | 标准名称（需求 1～20 字符） |
| `standard_type` | `varchar(32)` | Y | — | 资讯类别编码，见 **2.2** |
| `introduction` | `varchar(200)` | N | NULL | 简介，选填 |
| `content_file_url` | `varchar(512)` | Y | — | 正文附件访问 URL |
| `content_file_path` | `varchar(512)` | Y | — | 正文存储路径（若依上传 `fileName` 等） |
| `content_file_name` | `varchar(256)` | Y | — | 正文原始文件名（展示/下载名） |
| `cover_file_url` | `varchar(512)` | N | NULL | 封面 URL，选填 |
| `cover_file_path` | `varchar(512)` | N | NULL | 封面存储路径，选填 |
| `publish_status` | `tinyint(4)` | Y | `0` | `0` 未发布，`1` 已发布 |
| `kb_sync_status` | `tinyint(4)` | Y | `0` | `0` 未同步，`1` 已同步 |
| `kb_doc_id` | `varchar(128)` | N | NULL | 知识库文档 ID |
| `publish_time` | `datetime` | N | NULL | 发布时间 |
| `offline_time` | `datetime` | N | NULL | 下架时间 |
| `create_by` / `create_time` / `update_by` / `update_time` | 若依惯例 | — | — | — |
| `remark` | `varchar(500)` | N | NULL | 备注 |

**索引**：`PRIMARY KEY (id)`；`KEY idx_create_time (create_time)`；`KEY idx_type (standard_type)`；`KEY idx_pub_kb (publish_status, kb_sync_status)`。

**合法组合（应用层强校验）**：仅 `(publish_status, kb_sync_status) ∈ {(0,0),(0,1),(1,1)}`；禁止 `(1,0)` 等非法组合落库。

**DDL 示例**

```sql
CREATE TABLE `biz_feeding_standard` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `standard_name` varchar(64) NOT NULL COMMENT '标准名称（业务1～20字符）',
  `standard_type` tinyint(4) NOT NULL COMMENT '1饲养配方 2牦牛投喂',
  `introduction` varchar(200) DEFAULT NULL COMMENT '简介',
  `content_file_url` varchar(512) NOT NULL COMMENT '正文附件URL',
  `content_file_path` varchar(512) NOT NULL COMMENT '正文存储路径',
  `content_file_name` varchar(256) NOT NULL COMMENT '正文原始文件名',
  `cover_file_url` varchar(512) DEFAULT NULL COMMENT '封面URL',
  `cover_file_path` varchar(512) DEFAULT NULL COMMENT '封面存储路径',
  `publish_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0未发布 1已发布',
  `kb_sync_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0未同步 1已同步',
  `kb_doc_id` varchar(128) DEFAULT NULL COMMENT '知识库文档ID',
  `publish_time` datetime DEFAULT NULL COMMENT '发布时间',
  `offline_time` datetime DEFAULT NULL COMMENT '下架时间',
  `create_by` varchar(64) DEFAULT '' COMMENT '创建者',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_by` varchar(64) DEFAULT '' COMMENT '更新者',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `remark` varchar(500) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`),
  KEY `idx_create_time` (`create_time`),
  KEY `idx_type` (`standard_type`),
  KEY `idx_pub_kb` (`publish_status`,`kb_sync_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='饲喂标准';
```

### 2.2 标准类型与资讯类别

- **数据来源**：`GET /category/informationCategory/children?parentCode=001&categoryType=2`；响应字段 `code`（编码）、`name`（展示名）。
- **落库值**：`standard_type` 存编码（如 `001005`）。
- **校验**：`FeedingStandardTypeValidator`；非法编码返回「标准类型无效，请选择资讯类别中的类型」。

| 编码（示例） | 名称 |
| --- | --- |
| `001005` | 饲料配方 |
| `001006` | 牦牛投喂 |

**存量库迁移**：执行 `sql/biz_feeding_standard_alter_standard_type.sql`（`1`→`001005`，`2`→`001006`）。

### 2.3 其它枚举常量（后端建议）

| 字段 | 值 | 含义 |
| --- | --- | --- |
| `publish_status` | `0` | 未发布 |
| | `1` | 已发布 |
| `kb_sync_status` | `0` | 未同步 |
| | `1` | 已同步 |

---

## 3. 接口设计

统一响应：RuoYi `AjaxResult`（`code` / `msg` / `data`）或分页 `TableDataInfo`。区分参数错误、状态非法、文件非法、知识库失败等 `msg`/业务码。

**权限标识（示例）**：`feeding:standard:list|query|add|edit|remove|syncKb|removeKb|publish|offline`

**Base Path（示例）**：`/feeding/standard`（与项目 `context-path`、模块前缀对齐）

| # | 说明 | Method | URI | 权限 | 要点 |
| --- | --- | --- | --- | --- | --- |
| 3.1 | 分页列表 | GET | `/feeding/standard/list` | `feeding:standard:list` | Query：`pageNum`（默认 1）、`pageSize`（默认 **20**）、`keyword`（名称/简介 OR 模糊）、`standardType`（精确，可空）；排序 `create_time DESC, id DESC`；行内含双维状态、`contentFileName` 等 |
| 3.2 | 详情 | GET | `/feeding/standard/{id}` | `feeding:standard:query` | 返回全字段；下载走 `/common/download` 或鉴权直链 |
| 3.3 | 新增 | POST | `/feeding/standard` | `feeding:standard:add` | Body：`standardName`、`standardType`、`introduction`（可空）、`contentFileUrl`、`contentFilePath`、`contentFileName`、`coverFileUrl`、`coverFilePath`（可空）；落库 `publish_status=0`，`kb_sync_status=0` |
| 3.4 | 修改 | PUT | `/feeding/standard` | `feeding:standard:edit` | Body 含 `id`；**仅** `publish_status=0` 且 `kb_sync_status=0`；**不**自动推库（已同步不可改，须先移出） |
| 3.5 | 删除 | DELETE | `/feeding/standard/{ids}` | `feeding:standard:remove` | `publish_status=1` 禁止；`kb_sync_status=0` 允许；`0+1` 须先移出或本接口内联动删知识库再删本地；删物理文件 + 通知知识库删除 |
| 3.6 | 同步知识库 | POST | `/feeding/standard/syncKb/{id}` | `feeding:standard:syncKb` | 前置 `publish_status=0` 且 `kb_sync_status=0`；成功则 `kb_sync_status=1`，写入 `kb_doc_id` |
| 3.7 | 移出知识库 | POST | `/feeding/standard/removeKb/{id}` | `feeding:standard:removeKb` | 前置 `publish_status=0` 且 `kb_sync_status=1`；成功则 `kb_sync_status=0`，清空 `kb_doc_id` |
| 3.8 | 发布 | POST | `/feeding/standard/publish/{id}` | `feeding:standard:publish` | 前置 `publish_status=0` 且 `kb_sync_status=1`；按需调知识库「发布可见」；本地 `publish_status=1`，`publish_time=now()` |
| 3.9 | 下架 | POST | `/feeding/standard/offline/{id}` | `feeding:standard:offline` | 前置 `publish_status=1`；调知识库「对外下架」（非移出）；本地 `publish_status=0`，`kb_sync_status=1`，保留 `kb_doc_id`，`offline_time=now()` |

**校验（摘要）**：名称长度 1～20；`standard_type` 非空且为资讯类别有效编码（**2.2**）；简介 ≤50 字；正文后缀白名单 **`pdf`/`md`/`doc`/`docx`/`xls`/`xlsx`/`pptx`** 与 ≤30MB；封面后缀 **`jpg`/`jpeg`/`png`** 与 ≤10MB；服务端对 MIME/后缀二次校验（`FeedingStandardRules.isContentExtensionAllowed`）。

---

## 4. 知识库交互与附件（摘录）

- **变更通知**（同步、移出、发布、下架、删除联动）：报文语义、操作类型（添加/删除/可见性）及流程顺序与《养殖标准管理技术方案》**§4.2** 一致；业务侧可通过扩展字段或文档类型区分「饲喂标准」与「养殖标准」，具体以对端约定为准。  
- **提示词查询**：用户提问走知识库查询接口，不经饲喂标准 CRUD 转发；说明见养殖标准方案 **§4.3**。  
- **上传**：先 `/common/upload` 取 `url`、`fileName`（path）、`originalFilename`（映射 `content_file_name`）；**修改替换附件**成功后删除旧 `content_file_path` / `cover_file_path` 对应物理文件，避免残留。

---

## 5. 交付清单（勾选）

- [ ] `biz_feeding_standard` DDL / 菜单按钮权限 SQL  
- [ ] Domain / Mapper / Service / Controller  
- [ ] `KbAdminClient` 复用或按饲喂维度扩展配置（与养殖标准共用对接时可抽取公共模块）  
- [ ] 集成测试：同步、发布、下架、移出、删除及非法状态拦截；**已同步修改被拒绝**  
