Files
pqs-9100_client/docs/superpowers/specs/2026-06-12-report-template-pattern-design.md
2026-06-12 09:49:30 +08:00

452 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 报告模板 `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` 中报告模板下拉相关查询逻辑
## 结论
本方案将报告模板纳入已有模式体系,但保持“模式为页面隐式上下文”:
- 用户不需要手工选择模式
- 页面不展示模式字段
- 模板列表、模板新增/编辑、计划模板下拉都以当前模式为边界
- 目录结构与重复规则同时引入模式维度,避免数据和文件冲突
本方案不引入计划与模板的强一致校验,属于低侵入、可平滑上线的模式隔离改造。