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

11 KiB
Raw Blame History

报告模板 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
  • patternNamenameversion 做路径安全清洗
  • 生成相对目录 patternName/name/version/

所有路径相关逻辑统一走该方法:

  • 新增模板
  • 更新模板
  • 重命名目录
  • 删除目录

文件目录迁移

编辑模板时:

  • nameversion 变化,按新目录规则迁移
  • 若未变化,则沿用原目录
  • 文件替换逻辑仍保持现有语义

模式字典读取

可直接复用现有字典服务:

  • 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/updatepattern 为空时,返回参数错误
  • 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 中报告模板下拉相关查询逻辑

结论

本方案将报告模板纳入已有模式体系,但保持“模式为页面隐式上下文”:

  • 用户不需要手工选择模式
  • 页面不展示模式字段
  • 模板列表、模板新增/编辑、计划模板下拉都以当前模式为边界
  • 目录结构与重复规则同时引入模式维度,避免数据和文件冲突

本方案不引入计划与模板的强一致校验,属于低侵入、可平滑上线的模式隔离改造。