452 lines
11 KiB
Markdown
452 lines
11 KiB
Markdown
# 报告模板 `pattern` 字段改造设计
|
||
|
||
## 背景
|
||
|
||
当前报告模板管理使用 `pq_report` 表,前端页面位于:
|
||
|
||
- `frontend/src/views/system/template`
|
||
- `frontend/src/views/plan/planList/components/planPopup.vue`
|
||
|
||
后端代码位于:
|
||
|
||
- `D:\njcn\test\CN_Gather\detection\src\main\java\com\njcn\gather\report`
|
||
- `D:\njcn\test\CN_Gather\detection\src\main\java\com\njcn\gather\plan`
|
||
|
||
数据库结构已新增字段:
|
||
|
||
- `pattern char(32) COLLATE utf8mb4_bin NOT NULL COMMENT '模式id'`
|
||
|
||
当前系统中的设备、计划、脚本、检测源等业务对象都已按模式隔离,但报告模板仍是全局管理:
|
||
|
||
- 模板列表未按模式过滤
|
||
- 模板新增/编辑没有模式归属
|
||
- 计划弹窗的报告模板下拉取的是全部模板
|
||
- 模板文件目录与模式无关
|
||
|
||
本次改造的目标是让报告模板纳入现有的模式上下文管理,但保持“模式为隐式上下文”,不增加用户额外操作负担。
|
||
|
||
## 目标
|
||
|
||
- 报告模板列表按当前模式过滤
|
||
- 报告模板新增/编辑时自动绑定当前模式 `pattern`
|
||
- 报告模板前端页面不展示模式列,不展示模式下拉
|
||
- 计划弹窗中的报告模板选项只返回当前模式模板
|
||
- 删除不再使用的 `getPqReportAllName()` 前后端接口和调用
|
||
- 模板落盘目录改为 `patternName/name/version/`
|
||
- 模板重复校验改为 `pattern + name + version`
|
||
|
||
## 非目标
|
||
|
||
- 不增加模式列展示
|
||
- 不在新增/编辑弹窗中增加模式下拉
|
||
- 不在计划绑定模板时校验 `plan.pattern == report.pattern`
|
||
- 不在生成报告时校验 `plan.pattern == report.pattern`
|
||
- 不处理旧模板数据补 `pattern`,由数据库手工修复
|
||
- 不调整 `ad_plan.reportTemplateId` 的现有绑定模型
|
||
|
||
## 业务约束
|
||
|
||
### 模式来源
|
||
|
||
前端不允许用户手工选择模板模式。页面中的模板模式始终取“当前模式”上下文:
|
||
|
||
- 来源:`modeStore.currentMode`
|
||
- 映射:`dictStore.getDictData('Pattern')` 中与当前模式名称匹配的数据字典项
|
||
- 实际提交值:字典项 `id`
|
||
|
||
### 目录规则
|
||
|
||
模板文件存储目录由当前的:
|
||
|
||
- `name/version/`
|
||
|
||
改为:
|
||
|
||
- `patternName/name/version/`
|
||
|
||
其中:
|
||
|
||
- `patternName` 取模式字典的 `name`
|
||
- 数据库存储的 `pattern` 仍然是模式字典 `id`
|
||
- 目录名在落盘前需要做 Windows 路径安全处理
|
||
|
||
### 模板唯一性
|
||
|
||
模板唯一性由当前的全局:
|
||
|
||
- `name + version`
|
||
|
||
改为:
|
||
|
||
- `pattern + name + version`
|
||
|
||
因此:
|
||
|
||
- 同一模式下不允许同名同版本模板
|
||
- 不同模式下允许同名同版本模板
|
||
|
||
## 数据模型调整
|
||
|
||
### 后端实体与参数
|
||
|
||
以下对象补充 `pattern` 字段:
|
||
|
||
- `PqReport`
|
||
- `ReportParam`
|
||
- `ReportParam.UpdateParam`
|
||
- `ReportParam.QueryParam`
|
||
- `PqReportVO`
|
||
|
||
用途如下:
|
||
|
||
- `PqReport.pattern`:数据库持久化
|
||
- `ReportParam.pattern`:新增/编辑接收当前模式 id
|
||
- `ReportParam.QueryParam.pattern`:列表查询条件
|
||
- `PqReportVO.pattern`:详情回显与后续兼容
|
||
|
||
### 数据库存储
|
||
|
||
- `pq_report.pattern` 保存模式字典 `id`
|
||
- 不额外保存 `patternName`
|
||
- `patternName` 仅在文件目录拼接时通过字典服务即时获取
|
||
|
||
## 后端接口设计
|
||
|
||
### 1. `POST /report/list`
|
||
|
||
职责:
|
||
|
||
- 分页查询当前模式下的报告模板
|
||
|
||
请求参数新增:
|
||
|
||
- `pattern`
|
||
|
||
处理规则:
|
||
|
||
- 必须传 `pattern`
|
||
- 按 `pattern + name + version + state=1` 过滤
|
||
- 不允许在未传 `pattern` 时返回全量模板
|
||
|
||
返回:
|
||
|
||
- 保持现有分页结构
|
||
- `PqReportVO` 中可包含 `pattern`
|
||
- 前端列表不展示该字段
|
||
|
||
### 2. `GET /report/getById`
|
||
|
||
职责:
|
||
|
||
- 查询模板详情
|
||
|
||
处理规则:
|
||
|
||
- 保持现有按 `id` 查询
|
||
- 返回结果包含 `pattern`
|
||
|
||
说明:
|
||
|
||
- 本次不额外增加 `id + pattern` 双重校验
|
||
- 模板访问范围由列表入口和当前页面模式上下文收口
|
||
|
||
### 3. `POST /report/add`
|
||
|
||
职责:
|
||
|
||
- 新增报告模板
|
||
|
||
请求参数新增:
|
||
|
||
- `pattern`
|
||
|
||
处理规则:
|
||
|
||
- `pattern` 必传
|
||
- `pattern` 必须是合法模式字典 id
|
||
- 重复校验使用 `pattern + name + version`
|
||
- 文件目录按 `patternName/name/version/` 创建
|
||
|
||
### 4. `POST /report/update`
|
||
|
||
职责:
|
||
|
||
- 修改报告模板
|
||
|
||
请求参数新增:
|
||
|
||
- `pattern`
|
||
|
||
处理规则:
|
||
|
||
- 前端仍会传当前模式 id
|
||
- 后端接收该字段
|
||
- 不开放通过页面显式修改模式
|
||
- 更新名称或版本时,模板目录迁移到新的 `patternName/name/version/`
|
||
|
||
说明:
|
||
|
||
- 本次不设计跨模式迁移能力
|
||
- 模板模式的变更不作为用户可操作能力暴露
|
||
|
||
### 5. 新增模板选项接口
|
||
|
||
新增接口替代旧的全量模板名接口。
|
||
|
||
建议接口:
|
||
|
||
- `GET /report/listOptions?pattern={patternId}`
|
||
|
||
职责:
|
||
|
||
- 返回当前模式下可选报告模板列表,供计划弹窗下拉使用
|
||
|
||
建议返回结构:
|
||
|
||
- `id`
|
||
- `name`
|
||
- `version`
|
||
- `displayName`
|
||
|
||
其中:
|
||
|
||
- `displayName = name + '_' + version`
|
||
|
||
说明:
|
||
|
||
- 由后端拼接 `displayName`
|
||
- 前端不再自行拼接全量名称列表
|
||
|
||
### 6. 移除旧接口
|
||
|
||
以下接口与服务一并移除:
|
||
|
||
- `GET /report/listAllName`
|
||
- `IPqReportService.listAllName()`
|
||
- `PqReportServiceImpl.listAllName()`
|
||
- 前端 `getPqReportAllName()`
|
||
|
||
## 后端服务设计
|
||
|
||
### 列表查询
|
||
|
||
`PqReportServiceImpl.list()` 增加:
|
||
|
||
- `pattern` 非空校验
|
||
- `wrapper.eq("pattern", queryParam.getPattern())`
|
||
|
||
### 重复校验
|
||
|
||
`checkRepeat()` 调整为:
|
||
|
||
- `pattern`
|
||
- `name`
|
||
- `version`
|
||
- `state = ENABLE`
|
||
|
||
### 模板目录构造
|
||
|
||
新增统一内部方法,例如:
|
||
|
||
- `buildReportTemplateRelativeDir(String patternId, String name, String version)`
|
||
|
||
职责:
|
||
|
||
- 查询字典得到 `patternName`
|
||
- 对 `patternName`、`name`、`version` 做路径安全清洗
|
||
- 生成相对目录 `patternName/name/version/`
|
||
|
||
所有路径相关逻辑统一走该方法:
|
||
|
||
- 新增模板
|
||
- 更新模板
|
||
- 重命名目录
|
||
- 删除目录
|
||
|
||
### 文件目录迁移
|
||
|
||
编辑模板时:
|
||
|
||
- 若 `name` 或 `version` 变化,按新目录规则迁移
|
||
- 若未变化,则沿用原目录
|
||
- 文件替换逻辑仍保持现有语义
|
||
|
||
### 模式字典读取
|
||
|
||
可直接复用现有字典服务:
|
||
|
||
- `IDictDataService`
|
||
|
||
用途:
|
||
|
||
- 校验 `pattern` 是否存在
|
||
- 读取 `pattern.name`
|
||
|
||
## 前端页面设计
|
||
|
||
### 模板管理列表页
|
||
|
||
页面:
|
||
|
||
- `frontend/src/views/system/template/index.vue`
|
||
|
||
调整内容:
|
||
|
||
- 查询列表时自动注入当前模式 `patternId`
|
||
- 列表不新增模式列
|
||
- 列表不新增模式搜索项
|
||
- 打开新增弹窗时,将当前模式 id 写入表单状态
|
||
|
||
### 模板新增/编辑弹窗
|
||
|
||
页面:
|
||
|
||
- `frontend/src/views/system/template/components/reportPopup.vue`
|
||
|
||
调整内容:
|
||
|
||
- 本地表单对象增加 `pattern`
|
||
- 不展示模式下拉
|
||
- 新增时自动写入当前模式 id
|
||
- 编辑时保留接口返回的 `pattern` 值,但不展示、不允许修改
|
||
- 提交 `FormData` 时带上 `pattern`
|
||
|
||
说明:
|
||
|
||
- 模板模式是隐式上下文,不是表单可见字段
|
||
|
||
### 计划弹窗中的报告模板下拉
|
||
|
||
页面:
|
||
|
||
- `frontend/src/views/plan/planList/components/planPopup.vue`
|
||
|
||
调整内容:
|
||
|
||
- 不再调用 `getPqReportAllName()`
|
||
- 改为调用新的按模式模板选项接口
|
||
- 查询参数传当前模式 `patternId`
|
||
- 下拉只展示当前模式模板
|
||
- 展示文案使用后端返回的 `displayName`
|
||
|
||
说明:
|
||
|
||
- 本次不调整计划保存的数据结构
|
||
- 只调整模板下拉的取值范围和数据来源
|
||
|
||
## 前端 API 调整
|
||
|
||
文件:
|
||
|
||
- `frontend/src/api/device/report/index.ts`
|
||
- `frontend/src/api/device/interface/report.ts`
|
||
|
||
调整内容:
|
||
|
||
- `PqReport.ReqReportParams` 增加 `pattern`
|
||
- `PqReport.ResReport` 增加 `pattern`
|
||
- `getPqReportList` 调用参数增加 `pattern`
|
||
- 删除 `getPqReportAllName`
|
||
- 新增按模式查询模板选项接口
|
||
|
||
## 异常处理
|
||
|
||
### 后端
|
||
|
||
- `/report/list` 未传 `pattern` 时,返回参数错误
|
||
- `/report/add`、`/report/update` 中 `pattern` 为空时,返回参数错误
|
||
- `pattern` 对应字典不存在时,返回参数错误
|
||
- 路径安全清洗后若目录段为空,返回参数错误
|
||
- 同模式下模板重名重版本时,返回重复模板错误
|
||
|
||
### 前端
|
||
|
||
- 当前模式找不到对应 `patternId` 时,不发起新增、编辑、列表查询
|
||
- 提示当前模式配置异常
|
||
|
||
## 风险与处理
|
||
|
||
### 风险 1:旧目录与新目录并存
|
||
|
||
由于目录规则由 `name/version/` 改为 `patternName/name/version/`:
|
||
|
||
- 未编辑过的旧模板文件可能仍在旧目录
|
||
- 新增或编辑后的模板会进入新目录
|
||
|
||
处理:
|
||
|
||
- 本次不做历史文件批量迁移
|
||
- 以编辑后的新目录规则为准
|
||
|
||
### 风险 2:不同模式同名同版本模板的路径冲突
|
||
|
||
如果不把模式带入目录,会出现覆盖。
|
||
|
||
处理:
|
||
|
||
- 目录规则强制引入 `patternName`
|
||
- 唯一性规则改为 `pattern + name + version`
|
||
|
||
### 风险 3:计划绑定仍是弱约束
|
||
|
||
本次明确不校验:
|
||
|
||
- `plan.pattern == report.pattern`
|
||
|
||
因此若历史数据存在错绑:
|
||
|
||
- 系统不会主动阻止
|
||
- 但新的模板选择入口只暴露当前模式模板,后续错绑概率会明显下降
|
||
|
||
## 测试范围
|
||
|
||
### 后端验证
|
||
|
||
- 新增模板时成功写入 `pattern`
|
||
- 列表接口只返回当前模式模板
|
||
- 同模式下不允许同名同版本
|
||
- 不同模式下允许同名同版本
|
||
- 模板目录为 `patternName/name/version/`
|
||
- 更新名称或版本时目录迁移正确
|
||
- 新模板选项接口只返回当前模式模板
|
||
- 旧 `listAllName` 接口与实现已彻底移除
|
||
|
||
### 前端联调
|
||
|
||
- 模板管理页在不同模式下看到不同模板列表
|
||
- 新增模板时界面不展示模式字段,但提交体中带 `pattern`
|
||
- 编辑模板时界面不展示模式字段
|
||
- 计划弹窗中报告模板下拉只显示当前模式模板
|
||
- 前端已无 `getPqReportAllName()` 调用残留
|
||
|
||
## 实施范围
|
||
|
||
前端涉及:
|
||
|
||
- `frontend/src/api/device/interface/report.ts`
|
||
- `frontend/src/api/device/report/index.ts`
|
||
- `frontend/src/views/system/template/index.vue`
|
||
- `frontend/src/views/system/template/components/reportPopup.vue`
|
||
- `frontend/src/views/plan/planList/components/planPopup.vue`
|
||
|
||
后端涉及:
|
||
|
||
- `com.njcn.gather.report.pojo.po.PqReport`
|
||
- `com.njcn.gather.report.pojo.param.ReportParam`
|
||
- `com.njcn.gather.report.pojo.vo.PqReportVO`
|
||
- `com.njcn.gather.report.controller.ReportController`
|
||
- `com.njcn.gather.report.service.IPqReportService`
|
||
- `com.njcn.gather.report.service.impl.PqReportServiceImpl`
|
||
- `com.njcn.gather.plan` 中报告模板下拉相关查询逻辑
|
||
|
||
## 结论
|
||
|
||
本方案将报告模板纳入已有模式体系,但保持“模式为页面隐式上下文”:
|
||
|
||
- 用户不需要手工选择模式
|
||
- 页面不展示模式字段
|
||
- 模板列表、模板新增/编辑、计划模板下拉都以当前模式为边界
|
||
- 目录结构与重复规则同时引入模式维度,避免数据和文件冲突
|
||
|
||
本方案不引入计划与模板的强一致校验,属于低侵入、可平滑上线的模式隔离改造。
|