# 设备实施作业标准管理 — 前端技术方案

> 依据：`设备实施作业标准管理技术方案.md`（同目录，下称**总方案**）。本文描述 **Vue 管理端页面**、**接口封装**、**权限字**、**交互与校验**与总方案 **§2 / §3** 的对应关系；库表、状态机与知识库编排以后端总方案为准。

---

## 1. 技术架构

| 项 | 说明 |
| --- | --- |
| **工程** | 若依 **RuoYi-Vue** 前端（Vue **2.x** + **Element UI** + **Vue Router** + **Vuex**） |
| **页面路径** | `ruoyi-ui/src/views/breedingStandards/equipmentOperation/index.vue` |
| **组件名** | `EquipmentOperationStandard` |
| **布局参考** | `ruoyi-ui/src/views/breedingStandards/breedingManage/index.vue`（双 `el-card`：查询区 + 表格区；新增/编辑弹窗 + 查看弹窗） |
| **HTTP** | `@/utils/request` 封装 Axios，自动拼接 `VUE_APP_BASE_API`、携带 `Authorization` |
| **时间格式化** | 全局 `parseTime`（若依 `utils/ruoyi` 注入） |
| **分页** | 公共组件 `pagination`，与列表 `TableDataInfo` 的 `total`、`rows` 对齐 |

**与总方案关系**：列表/详情/写操作均调用总方案 **§3** 所列 REST；行内操作显隐与 `publish_status`、`kb_sync_status` 合法组合一致（总方案 **§2.1** 合法组合）。

---

## 2. 源码与路由

| 类型 | 路径 |
| --- | --- |
| 页面 | `ruoyi-ui/src/views/breedingStandards/equipmentOperation/index.vue` |
| API 模块 | `ruoyi-ui/src/api/breedingStandards/equipmentWorkStandard.js` |

**菜单（若依后台配置）**

| 配置项 | 建议值 |
| --- | --- |
| 组件路径 | `breedingStandards/equipmentOperation/index`（与 `views` 下相对路径一致，无前缀 `@/`） |
| 路由名 | 自定，不与现有路由冲突即可 |
| 权限标识 | 与 **§5** 表一致，子菜单按钮 SQL 与总方案交付清单对齐 |

---

## 3. 页面结构

### 3.1 查询区（首卡片）

| UI | 绑定/说明 |
| --- | --- |
| 关键词 | `queryParams.keyword`，占位「名称或简介模糊查询」，回车触发搜索；与后端实体检索字段 `keyword` 对应 |
| 标准类型 | `queryParams.standardType`，下拉可清空；选项在 `created` 中调用 **§7.1** 接口动态加载 |
| 搜索 | `handleQuery`：`pageNum = 1` 后 `getList` |
| 重置 | `resetQuery`：清空 `keyword`、`standardType`，`resetForm('queryForm')` 后再查询 |
| 新增 | `v-hasPermi="['equipment:workStandard:add']"` → `handleAdd` |

### 3.2 列表区（次卡片）

| 列 | 数据来源 | 备注 |
| --- | --- | --- |
| 标准名称 | `standardName` | `show-overflow-tooltip` |
| 标准类型 | `standardType` | `typeLabel(code)`：由 `standardTypeOptions`（**§6.1**）按编码映射名称 |
| 简介 | `introduction` | — |
| 正文附件 | `contentFileUrl` / `contentFileName` | `el-link` 新窗口打开 |
| 上架状态 | `publishStatus` | `publishStatusText` |
| 知识库同步 | `kbSyncStatus` | `kbSyncStatusText` |
| 发布日期 | `publishTime` | `parseTime(..., '{y}-{m}-{d}')`，空为「—」 |
| 创建时间 | `createTime` | `parseTime` 完整格式 |
| 操作 | 多个 `el-button type="text"` | 权限 + 行状态双条件，见 **§5** |

**分页**：`pageNum`、`pageSize` 默认 **1 / 20**，与总方案 **§3.1** 一致；`v-show="total > 0"`。

### 3.3 新增 / 编辑弹窗

| 字段 | 表单控件 | 校验（前端） |
| --- | --- | --- |
| `standardName` | 输入框，`maxlength=20`，字数统计 | 必填；长度 **1～20**（与总方案 **§3** 校验摘要一致） |
| `standardType` | 下拉 | 必填；选项来自 `listInformationCategoryChildren('001', 3)`，`value`=`code`，`label`=`name` |
| `introduction` | 多行文本，`maxlength=50` | 选填；最多 **50** 字 |
| 正文附件 | `el-upload` → `/common/upload` | 必填（以 `contentFilePath` 为校验 prop）；后缀白名单、≤**30MB**、文件名不含英文逗号 |
| 封面 | `picture-card` 上传，最多 1 张 | 选填；`jpg/jpeg/png`、≤**10MB** |

**编辑态**：仅当详情返回 `publishStatus === 0` 且 `kbSyncStatus === 0` 时允许修改表单字段及替换/删除正文与封面（`canEditFormRow`）；与总方案 **§3.4**「仅未发布未同步可改」一致。已同步记录点击编辑时提示 `ruleSyncedNoEdit`，不打开弹窗。

**提交 Body（小驼峰）**

| 键 | 说明 |
| --- | --- |
| `standardName` / `standardType` / `introduction` | 与总方案 **§3.3 / §3.4** 一致；`introduction` 可省略或 `undefined` |
| `contentFileUrl` / `contentFilePath` / `contentFileName` | 上传成功回写 |
| `coverFileUrl` / `coverFilePath` | 可选 |
| `id` | 仅修改时携带 |

弹窗标题：`[新增]设备实施作业标准` / `[编辑]设备实施作业标准`。

### 3.4 查看弹窗

调 `GET /equipment/workStandard/{id}` 拉全量展示：标准名称、类型、简介、正文链接、封面（`image-preview`）、上架状态、知识库同步、发布时间、下架时间。

---

## 4. 上传与鉴权

| 项 | 说明 |
| --- | --- |
| 上传地址 | `VUE_APP_BASE_API + '/common/upload'` |
| 请求头 | `Authorization: Bearer <token>`（`@/utils/auth` `getToken`） |
| 成功回调 | `code === 200` 时取 `url`、`fileName`、`originalFilename`（正文名优先 `originalFilename`，否则取本地 `file.name`） |
| 失败 | `on-error` 关闭 loading 并 `msgError` |

**正文后缀（需求/服务端）**：`pdf`、`md`、`doc`、`docx`、`xls`、`xlsx`、`pptx`（`EquipmentWorkStandardRules`）。**说明**：当前页面 `contentFileExts` 暂未同步调整，**保存以服务端校验为准**。物理文件删除、知识库联动由**后端**在修改/删除等接口内完成（总方案 **§4**），前端不直接调用知识库 HTTP。

---

## 5. 操作按钮与权限

权限字与总方案 **§3** 一致；按钮同时受 **`v-hasPermi`** 与 **行状态方法** 控制。

| 按钮 | 权限标识 | 显示条件（与行数据） |
| --- | --- | --- |
| 查看 | `equipment:workStandard:query` | 有权限即显 |
| 同步知识库 | `equipment:workStandard:syncKb` | `publishStatus === 0` 且 `kbSyncStatus === 0` |
| 移出知识库 | `equipment:workStandard:removeKb` | `publishStatus === 0` 且 `kbSyncStatus === 1` |
| 编辑 | `equipment:workStandard:edit` | `publishStatus === 0` 且 `kbSyncStatus === 0`（与总方案 **§3.4** 一致） |
| 删除 | `equipment:workStandard:remove` | `publishStatus === 0` 且 `kbSyncStatus === 0` |
| 发布 | `equipment:workStandard:publish` | `publishStatus === 0` 且 `kbSyncStatus === 1` |
| 下架 | `equipment:workStandard:offline` | `publishStatus === 1` |

**说明**：`(publishStatus, kbSyncStatus) = (1, 0)` 为非法组合，前端不单独分支；若后端脏数据，以接口 `msg` 为准。

**二次确认**：同步、移出、删除、发布、下架均使用 `this.$modal.confirm`；下架说明与总方案「下架 vs 移出」语义一致。

---

## 6. 枚举与展示映射

### 6.1 `standardType`（标准类型）

页面维护 `standardTypeOptions: []`，`created` 调用 `loadStandardTypeOptions()`：

```javascript
import { listInformationCategoryChildren } from '@/api/category/informationCategory'
// listInformationCategoryChildren('001', 3) → data[]，项字段 code、name
```

列表/详情展示：`typeLabel(code)` 在 `standardTypeOptions` 中查找 `item.code === code` 后取 `item.name`；找不到时回退 **存量迁移** 映射 `LEGACY_STANDARD_TYPE_LABELS`（`1`～`4` → 国际化 `breedingStd.eqp.type1`～`type4`，对应总方案 **§2.2** 迁移脚本 `1`→`001007` … `4`→`001010`）；仍无则回显编码。

| 编码（示例） | 界面文案 |
| --- | --- |
| `001007` | 设备操作 |
| `001008` | 设备保养 |
| `001009` | 设备排障 |
| `001010` | 设备维修 |

### 6.2 `publishStatus`（上架状态）

| 值 | 界面文案 |
| --- | --- |
| `0` | 未发布 |
| `1` | 已发布 |

### 6.3 `kbSyncStatus`（知识库同步）

| 值 | 界面文案 |
| --- | --- |
| `0` | 未同步 |
| `1` | 已同步 |

---

## 7. API 模块与后端 URI 对应

### 7.1 标准类型选项（资讯类别）

文件：`ruoyi-ui/src/api/category/informationCategory.js`

| 方法 | HTTP | URI | 参数 / 响应 |
| --- | --- | --- | --- |
| `listInformationCategoryTree` | GET | `/category/informationCategory/tree` | Query 可选 `categoryType`；`data[]` 项字段 `code`、`name`、`categoryType`、`children` |
| `listInformationCategoryChildren` | GET | `/category/informationCategory/children` | `parentCode=001`，`categoryType=3`；`data[]` 项字段 `code`、`name` |

### 7.2 设备实施作业标准 CRUD

文件：`ruoyi-ui/src/api/breedingStandards/equipmentWorkStandard.js`。请求/响应字段采用 **小驼峰**（与 `BizEquipmentWorkStandard` 及 Jackson 序列化一致）。

| 方法（导出） | HTTP | URI |
| --- | --- | --- |
| `listEquipmentWorkStandard` | GET | `/equipment/workStandard/list` |
| `getEquipmentWorkStandard` | GET | `/equipment/workStandard/{id}` |
| `addEquipmentWorkStandard` | POST | `/equipment/workStandard` |
| `updateEquipmentWorkStandard` | PUT | `/equipment/workStandard` |
| `delEquipmentWorkStandard` | DELETE | `/equipment/workStandard/{ids}` |
| `syncKbEquipmentWorkStandard` | POST | `/equipment/workStandard/syncKb/{id}` |
| `removeKbEquipmentWorkStandard` | POST | `/equipment/workStandard/removeKb/{id}` |
| `publishEquipmentWorkStandard` | POST | `/equipment/workStandard/publish/{id}` |
| `offlineEquipmentWorkStandard` | POST | `/equipment/workStandard/offline/{id}` |

**列表查询参数**：`pageNum`、`pageSize`、`keyword`、`standardType`（与页面 `queryParams` 一致）。

---

## 8. 错误与交互约定

| 场景 | 前端行为 |
| --- | --- |
| 列表/表单接口非 200 | 走全局 `request` 拦截器提示（若依默认） |
| 标准类型选项加载失败 | `loadStandardTypeOptions` 捕获异常，`msgError(errStdTypeLoad)`，下拉为空 |
| 已同步记录点编辑 | `msgWarning(ruleSyncedNoEdit)`，不请求详情 |
| 已发布记录点编辑 | `msgWarning(rulePublishedNoEdit)` |
| 上传失败 | `msgError`，关闭 loading |
| 删除 | 单行传 `id` 至 `delEquipmentWorkStandard`（与总方案 `{ids}` 兼容） |

不在前端重复实现知识库重试；失败以后端 `msg` 为准。

---

## 9. 交付与联调清单

- [x] 菜单路由指向 `breedingStandards/equipmentOperation/index`，按钮权限 SQL 与 **§5** 一致  
- [x] 标准类型下拉：`GET /category/informationCategory/children?parentCode=001&categoryType=3`  
- [ ] 后端 `/equipment/workStandard/**` 与总方案 **§3** 对齐，分页字段 `rows` / `total`  
- [ ] 存量环境执行 `sql/biz_equipment_work_standard_alter_standard_type.sql` 后列表类型展示正常  
- [ ] `/common/upload` 可访问且返回 `url`、`fileName`、`originalFilename`  
- [ ] 联调：新增 → 同步知识库 → 发布 → 下架 → 移出 → 删除（及未发布仅本地删除等路径）  
- [ ] 联调：已同步记录编辑被前端拦截；未同步修改成功；已同步修改被后端拒绝（双端一致）

---

## 10. 文档修订记录

| 版本 | 日期 | 说明 |
| --- | --- | --- |
| v1.0 | 2026-05-11 | 初稿，与 `equipmentOperation/index.vue`、`equipmentWorkStandard.js` 及总方案 **§2～§3** 对齐 |
| **v1.1** | **2026-06-01** | **标准类型改资讯类别编码**：动态加载 `parentCode=001&categoryType=3`；筛选/表单传 `code`；存量 `1`～`4` 回退展示；编辑/上传仅 **未发布+未同步**；补充类型加载失败与已同步编辑提示 |
| **v1.2** | **2026-05-20** | 正文服务端白名单：`pdf`、`md`、`doc`、`docx`、`xls`、`xlsx`、`pptx`（移除 `ppt`）；前端 `contentFileExts` 本次不改 |
