# 实战业务培训 — 前端技术方案

> 依据：`实战业务培训功能需求.md`、`实战业务培训技术方案.md`；布局对齐 `dataHub/dataSendRecord/index.vue`、`innovationPlatform/techProjectGuide/index.vue`（双 `el-card`）；字段 **小驼峰**。

---

## 1. 页面与路由

| 项 | 说明 |
| --- | --- |
| **Vue 路径** | `ruoyi-ui/src/views/techService/practicalTraining/index.vue` |
| **组件名** | `PracticalTraining` |
| **菜单配置** | 组件路径：`techService/practicalTraining/index`（「科技平台与服务」目录下，手工配置） |
| **权限前缀** | `techService:practicalTraining:list\|query\|add\|edit\|remove\|publish\|offline` |

---

## 2. API 模块

| 项 | 说明 |
| --- | --- |
| **文件** | `ruoyi-ui/src/api/techService/practicalTraining.js` |
| **Base** | `/techService/practicalTraining` |

| 方法 | HTTP | 说明 |
| --- | --- | --- |
| `listPracticalTraining` | GET | `/list` |
| `getPracticalTraining` | GET | `/{id}` |
| `addPracticalTraining` | POST | `/`（Body 可含 `saveAndPublish`） |
| `updatePracticalTraining` | PUT | `/` |
| `delPracticalTraining` | DELETE | `/{ids}` |
| `publishPracticalTraining` | POST | `/publish/{id}` |
| `offlinePracticalTraining` | POST | `/offline/{id}` |

---

## 3. 页面结构

1. **筛选区**：培训主题（精确）；培训日期 `daterange` → `startDate`/`endDate`；搜索、重置、新增。  
2. **列表区**：主题、培训时间、计划人数、地点、报名起止、发布日期、报名状态（`el-tag`）、实际报名人数、操作（查看/发布/编辑/下架/删除，按发布状态与 `canOffline` 显隐）。  
3. **新增/编辑弹窗**：§5.1.1 全部业务字段；封面上传（`/common/upload`，jpg/jpeg/png ≤10MB）；底部 **发布**（仅新增）+ **确定** + **取消**。  
4. **查看弹窗**：只读展示业务字段、封面预览、发布/报名状态、审计信息；底部按矩阵提供发布/下架/编辑/删除。

---

## 4. 业务规则（前端）

| 规则 | 实现 |
| --- | --- |
| 时间链 | `registrationStartTime < registrationEndTime < trainingTime`；`validateTimeChain` + 提交前 `isTimeChainValid` |
| 培训日期筛选 | `trainingDateRange` → `startDate`、`endDate`；起 > 止时 `msgError` 不请求 |
| 培训主题 | 精确提交；1～20 字 trim 校验 |
| 计划人数 | `el-input-number`，整数 ≥1 |
| 新增默认培训时间 | 打开新增时 `trainingTime = 当前时刻` |
| 新增保存并发布 | `saveAndPublish: true` |
| 未发布 | 可编辑、删除、发布；操作列与详情一致 |
| 已发布 | 不可编辑/删除；`canOffline`：优先用接口 `canOffline`，否则 `now < registrationStartTime` |
| 报名状态展示 | 优先 `enrollStatusName`；否则按 `enrollStatus` 1～4 映射 i18n |
| 发布日期 | 未发布或 `publishTime` 空显示「—」；否则格式化为 `YYYY-MM-DD` |
| 封面 | 可选；`coverFileUrl` + `coverFilePath` 成对提交 |

---

## 5. 国际化

| 项 | 说明 |
| --- | --- |
| **语言包** | `techService.practicalTraining`（`lang/zh/techService.js`、`lang/bo/techService.js`） |
| **Mixin** | `techServiceLocaleMixin`，`tsNs = 'practicalTraining'`，方法 `tsT` / `tsCommon` |
| **注册** | `lang/zh-CN.js`、`lang/bo.js` 引入 `techService` |
| **报名状态** | `techService.enrollStatus.*` |

---

## 6. 联调说明

1. 部署 `BizPracticalTrainingController` 及 `biz_practical_training` 表（见后端技术方案）。  
2. 菜单组件 `techService/practicalTraining/index`，权限与后端 §4 一致。  
3. 验证：主题精确筛选、培训日期闭区间、时间链校验、仅保存/保存并发布、列表发布与下架前置、已发布不可改删、详情 `canOffline`、双语切换。

---

## 7. 文件清单

| 类型 | 路径 |
| --- | --- |
| 页面 | `ruoyi-ui/src/views/techService/practicalTraining/index.vue` |
| API | `ruoyi-ui/src/api/techService/practicalTraining.js` |
| Mixin | `ruoyi-ui/src/mixins/techServiceLocaleMixin.js` |
| i18n | `ruoyi-ui/src/lang/zh/techService.js`、`lang/bo/techService.js` |

---

## 8. 修订记录

| 版本 | 说明 |
| --- | --- |
| 1.0 | 初版：双卡片列表；CRUD+发布下架；报名状态标签；封面上传；汉藏 i18n |
