From 5ffc9d139e30609eea0de40e4929eda791311794 Mon Sep 17 00:00:00 2001 From: chenjy Date: Thu, 21 May 2026 17:22:27 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E6=8C=87=E5=BC=95=20+=20=E5=89=8D=E5=90=8E=E7=AB=AF=E8=81=94?= =?UTF-8?q?=E8=B0=83=E6=8C=87=E5=8D=97=20+=20=E9=94=99=E9=A2=98=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.7 --- CLAUDE.md | 76 ++ ...01-前端联调高频错误模式归纳.md | 106 +++ docs/fix/错题集索引.md | 72 ++ docs/前后端联调指南.md | 758 ++++++++++++++++++ 4 files changed, 1012 insertions(+) create mode 100644 CLAUDE.md create mode 100644 docs/fix/错题库/2026-05/2026-05-21-001-前端联调高频错误模式归纳.md create mode 100644 docs/fix/错题集索引.md create mode 100644 docs/前后端联调指南.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..1b0a9bb --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,76 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Build & Run + +```bash +# 编译(开发阶段跳过 checkstyle) +mvn compile -Dcheckstyle.skip=true + +# 完整编译(含 checkstyle) +mvn compile + +# 打包(默认跳过测试) +mvn clean package + +# 本地运行(因 ZIP layout 无法用 spring-boot:run) +mvn dependency:build-classpath -Dmdep.outputFile=classpath.txt +java -cp "target/classes;$(cat classpath.txt)" -Dfile.encoding=UTF-8 com.chinaweal.youfool.prj.YoufoolApplication +``` + +## Architecture + +OARMS — 广州市户外广告监管系统后端,Spring Boot 3.4.5 + JDK 21 + 达梦 DM8 数据库。 + +### 业务域与模块 + +5 大业务域、10 个模块,按域组织在 `modules/` 下: + +| 域 | 模块 | 包路径 | 表前缀 | +|----|------|--------|--------| +| BS 基础 | 大屏管理 | `modules/screen` | `bs_` | +| LB 法律 | 法律法规 | `modules/law` | `lb_` | +| MR 监测 | 监测规则 | `modules/rule` | `mr_` | +| AM 监控 | 录屏设置/任务/画面监控 | `modules/monitor/{config,task,record}` | `am_` | +| CW 取证 | 固化取证/规则关联/线索生成/线索转办 | `modules/evidence/{record,relation,clue,transfer}` | `cw_` | + +### 分层结构 + +每个模块遵循 Controller → Service → Mapper 三层,实体包内分 `query/`、`req/`、`vo/`: + +``` +modules/{module}/ +├── entity/ # Entity + query/ + req/ + vo/ +├── mapper/ # extends BaseMapper +├── service/ # I{Entity}Service + impl/ +└── controller/ +``` + +### 关键约定 + +- **事务**:必须用 `@DSTransactional`,不能用 `@Transactional`(动态数据源要求) +- **数据源**:`@DS("master")` + `@TableName(schema = "OARMS", value = "表名")` +- **Entity**:继承 `SuperEntity`(含 createBy/createTime/createName/updateBy/updateTime/updateName,不含 id) +- **DI**:`@AllArgsConstructor` + `private final` +- **返回值**:`RestResult.ok(data)` / `RestResult.ok()` +- **日志**:`log.info("[OK] 操作描述: key={}", value)` +- **Mapper 扫描**:`com.chinaweal.youfool.prj.**.mapper`,新模块放此包下自动注册 +- **API 路径**:所有接口以 `/api/` 开头 + +### 数据源 + +两个数据源,通过 dynamic-datasource 切换: +- `master`(primary)→ OARMS schema,业务数据 +- `youfool` → YOUFOOL schema,框架日志(restLog) + +### DM8 数据库要点 + +- DDL/COMMENT/INDEX 中表名列名必须大写,INSERT 中列名可用小写 +- 日期字段:`@JsonFormat(pattern = DateUtil.DATE_DEFAULT_FORMAT, timezone = "GMT+8")` +- 日期时间字段:`@JsonFormat(pattern = DateUtil.DATETIME_DEFAULT_FORMAT, timezone = "GMT+8")` +- DDL 文件放在 `docs/db/sql/`,命名 `V{版本号}__{模块描述}_{ddl|init_data}.sql` + +## Development Guide + +详细开发指南见 `docs/backend-module-dev-guide.md`,包含 Entity/Controller/Service/Mapper/Query 模板代码和 DM8 类型映射表。 diff --git a/docs/fix/错题库/2026-05/2026-05-21-001-前端联调高频错误模式归纳.md b/docs/fix/错题库/2026-05/2026-05-21-001-前端联调高频错误模式归纳.md new file mode 100644 index 0000000..4894d58 --- /dev/null +++ b/docs/fix/错题库/2026-05/2026-05-21-001-前端联调高频错误模式归纳.md @@ -0,0 +1,106 @@ +# LE-2026-05-001 - 前端联调高频错误模式归纳(来自 gz-atms-web 项目) + +**日期**:2026-05-21 +**模块**:通用 +**分类**:前后端数据映射 / 接口参数 / 组件框架 / 数据库SQL +**严重程度**:P1(严重) + +## 问题描述 + +从 gz-atms-web 项目(`D:\chinaweal\gz-atms\gz-atms-web\docs\fix\错题库`)的 12 条错题中,归纳出前后端联调的 8 大高频错误模式。 + +## 错误模式归纳 + +### 模式 1:字段名不匹配 + +| 维度 | 说明 | +|------|------| +| 表现 | 表格数据为空,prop 与后端返回的 JSON key 不一致 | +| 根因 | 前端 prop 用中文/自定义名,后端返回 Java camelCase 字段名 | +| 修复 | prop 必须与 API 返回的 JSON key 精确一致 | +| 检测 | 对比前端 table column prop 与后端 VO 字段名 | + +### 模式 2:rowKey 不匹配 + +| 维度 | 说明 | +|------|------| +| 表现 | 翻页后操作列按钮消失、DOM 状态错乱 | +| 根因 | 默认 rowKey='id',但后端主键字段名不同(如 marketId) | +| 修复 | 显式设置 `row-key="实际主键名"` | +| 检测 | 检查 Entity @TableId 的字段名,与前端 row-key 对比 | + +### 模式 3:分页字段名(list vs records) + +| 维度 | 说明 | +|------|------| +| 表现 | 列表数据加载不出来 | +| 根因 | MyBatis-Plus 分页返回 `records`,前端误用 `list` | +| 修复 | 统一使用 `res.records` | +| 检测 | 后端返回 `Page` 时,前端取列表数据的字段名 | + +### 模式 4:JSON 字符串未解析 + +| 维度 | 说明 | +|------|------| +| 表现 | 调用 `.map()` 报 TypeError: xxx.map is not a function | +| 根因 | 后端 CLOB/JSON 字段返回 String,前端当数组直接使用 | +| 修复 | `JSON.parse(data)` 或 `Array.isArray(data) ? data : JSON.parse(data)` | +| 检测 | 后端 Entity 中 String 类型但实际存储 JSON 的字段(如 relatedRules、scopeDistricts) | + +### 模式 5:数组与单对象混淆 + +| 维度 | 说明 | +|------|------| +| 表现 | 访问属性报 undefined,渲染异常 | +| 根因 | 一对多关系后端返回数组,前端当单个对象使用 | +| 修复 | `Array.isArray(data) ? data[0] : data` | +| 检测 | 详情接口返回类型如果是 `List` 而非 `Entity` | + +### 模式 6:响应拦截器自动解包 + +| 维度 | 说明 | +|------|------| +| 表现 | 取 res.data.data 报 undefined | +| 根因 | request.js 拦截器已自动解包 `response.data`,业务代码再解包一次就多了一层 | +| 修复 | 直接使用 `res.list`、`res.total` 等已解包字段 | +| 检测 | 检查前端 request.js 响应拦截器的 return 逻辑 | + +### 模式 7:导出接口 responseType 未设 blob + +| 维度 | 说明 | +|------|------| +| 表现 | 文件下载报"业务出错"或下载文件损坏 | +| 根因 | 未设置 `responseType: 'blob'`,二进制数据被当文本处理 | +| 修复 | 请求配置中添加 `responseType: 'blob'` | +| 检测 | 所有文件下载接口的前端请求配置 | + +### 模式 8:排序字段驼峰未转下划线 + +| 维度 | 说明 | +|------|------| +| 表现 | 达梦数据库报错"列名无效" | +| 根因 | 前端传驼峰字段名,后端直接拼 SQL,DM8 要求大写下划线列名 | +| 修复 | 后端排序字段先转下划线再拼 SQL,或前端直接传下划线格式 | +| 检测 | 后端 QueryWrapper orderBy 使用了 camelCase 字段名的位置 | + +## AI 检测规则 + +``` +CHECK: 对 OARMS 项目进行以下 8 项自动检测 +RULE: + 1. 前端 table column prop == 后端 VO/Entity 字段名 + 2. 前端 row-key == 后端 @TableId 字段名 + 3. 前端分页取数据字段 == "records"(非 "list") + 4. 后端 CLOB/String 字段(relatedRules, scopeDistricts 等)前端有 JSON.parse + 5. 详情接口返回数组时前端有 Array.isArray 判断 + 6. 前端 request.js 拦截器解包逻辑与业务代码一致 + 7. 文件下载接口前端有 responseType:'blob' + 8. 后端排序字段名已转下划线 +FAIL: 任一规则不满足 → 报告具体位置和修复建议 +``` + +## 参考 + +原始错题来源:`D:\chinaweal\gz-atms\gz-atms-web\docs\fix\错题库\` +- 2026-01: 3 条(方法调用错误、拦截器解包、路径错误) +- 2026-05: 9 条(字段映射、分页、JSON解析、导出、排序等) diff --git a/docs/fix/错题集索引.md b/docs/fix/错题集索引.md new file mode 100644 index 0000000..3019cf8 --- /dev/null +++ b/docs/fix/错题集索引.md @@ -0,0 +1,72 @@ +# OARMS 错题集索引 + +> 前后端联调过程中发现的问题记录,按分类汇总。每条错题对应 `错题库/` 下的一个详细文件。 + +## 索引 + +### 按分类 + +#### 前后端数据映射 + +| 编号 | 日期 | 标题 | 模块 | +|------|------|------|------| +| LE-2026-05-001 | 2026-05-21 | [前端联调高频错误模式归纳(8大模式)](错题库/2026-05/2026-05-21-001-前端联调高频错误模式归纳.md) | 通用 | + +#### 接口参数/返回值 + +| 编号 | 日期 | 标题 | 模块 | +|------|------|------|------| +| (暂无) | | | | + +#### 组件/框架问题 + +| 编号 | 日期 | 标题 | 模块 | +|------|------|------|------| +| (暂无) | | | | + +#### 数据库/SQL + +| 编号 | 日期 | 标题 | 模块 | +|------|------|------|------| +| (暂无) | | | | + +--- + +## 错题编写模板 + +新增错题时复制以下模板,保存为 `错题库/YYYY-MM/YYYY-MM-DD-NNN-简述.md`: + +```markdown +# 编号 - 标题 + +**日期**:YYYY-MM-DD +**模块**:BS-1 / LB-1 / MR-1 / AM-1~3 / CW-1~4 / 通用 +**分类**:前后端数据映射 / 接口参数 / 组件框架 / 数据库SQL +**严重程度**:P0(阻塞) / P1(严重) / P2(一般) / P3(建议) + +## 问题描述 + +(具体的现象和复现步骤) + +## 根因分析 + +(问题的根本原因) + +## 解决方案 + +(修复方法和代码变更) + +## AI 检测规则 + +(AI 可执行的检测逻辑,用于自动发现同类问题) + +``` +CHECK: +RULE: +FAIL: +``` +``` + +## 参考 + +错题模式参考 gz-atms-web 项目的错题库:`D:\chinaweal\gz-atms\gz-atms-web\docs\fix\错题库\` diff --git a/docs/前后端联调指南.md b/docs/前后端联调指南.md new file mode 100644 index 0000000..846d550 --- /dev/null +++ b/docs/前后端联调指南.md @@ -0,0 +1,758 @@ +# OARMS 前后端联调指南 + +> AI 可执行的联调自动化校验手册。按模块逐层核对 PRD→前端接口→后端API→DTO→数据库表的完整链路。 + +## 一、联调流程总览 + +联调链路:**PRD文档 → 前端接口定义 → 后端API路由 → 入参DTO → 数据库表 → 字段映射** + +每个模块的联调校验分为 5 层: + +| 层级 | 校验内容 | 数据来源 | +| ----------- | ---------------------- | -------------------------- | +| L1 接口存在性 | 前端调用的路由是否在后端有对应实现 | Controller @RequestMapping | +| L2 参数一致性 | 前端传参字段名/类型是否与后端 DTO 一致 | Query/Req 类字段 vs 前端请求体 | +| L3 返回值一致性 | 后端返回字段是否满足前端展示需要 | VO/Entity 字段 vs 前端消费字段 | +| L4 DTO-DB映射 | Entity 字段是否与数据库列一一对应 | @TableField vs DDL 列定义 | +| L5 数据完整性 | 表是否存在、是否有初始数据、字段约束是否满足 | DDL 文件 + 数据库查询 | + +## 二、可执行校验规则 + +### 2.1 接口存在性校验 + +``` +CHECK: 对前端每个 API 调用,在后端 Controller 中查找匹配路由 +RULE: HTTP方法 + 路径 必须精确匹配 +FAIL: 前端调用 POST /api/xxx/save 但后端无此路由 → 缺少接口 +``` + +### 2.2 参数一致性校验 + +``` +CHECK: 前端请求体字段 vs 后端 Query/Req 类字段 +RULE: + - 字段名必须完全一致(camelCase) + - 字段类型兼容(前端String ↔ 后端String/Integer/LocalDate等) + - 必填字段标记一致 +FAIL: + - 前端传 screenName 但后端 DTO 无此字段 → 字段缺失 + - 前端传 String 但后端期望 Integer → 类型不匹配 +``` + +### 2.3 返回值一致性校验 + +``` +CHECK: 后端 VO/Entity 返回字段 vs 前端渲染需要的字段 +RULE: + - 前端表格列(col.prop) 必须与返回 JSON key 一致 + - 分页字段:后端 MyBatis-Plus 返回 records,非 list + - 日期格式:后端 @JsonFormat 自动格式化,前端直接展示 + - JSON字符串字段:relatedRules/relatedLawClauses/scopeDistricts 返回 String,前端需 JSON.parse() +FAIL: + - 前端用 res.data.list 但后端返回 records → 分页字段不匹配 + - 前端直接对 JSON 字符串调 .map() → 类型错误 +``` + +### 2.4 DTO-DB映射校验 + +``` +CHECK: Entity 字段 vs 数据库表列 +RULE: + - @TableField("column_name") 的 column_name 必须在 DDL 中存在 + - Java类型映射:String↔VARCHAR/CLOB, Integer↔TINYINT/INT, BigDecimal↔DECIMAL, LocalDate↔DATE, LocalDateTime↔TIMESTAMP + - SuperEntity 审计字段(createBy/createTime/createName/updateBy/updateTime/updateName)不在 Entity 中声明但 DB 有对应列 +FAIL: + - Entity 字段无对应 DB 列 → 字段映射缺失 + - 类型不匹配(如 Java String vs DB INT)→ 类型映射错误 +``` + +### 2.5 数据完整性校验 + +``` +CHECK: 数据库表是否存在、是否有初始数据 +RULE: + - 每个 Entity 对应的表必须在 DDL 文件中定义 + - 有 init_data.sql 的表应包含种子数据 + - 唯一约束字段必须有 check 接口支持 +FAIL: + - DDL 文件不存在 → 需创建表 + - 有表无数据 → 需补充初始数据 +``` + +### 2.6 高频错误模式速查 + +| 错误模式 | 检测方法 | 修复方案 | +| ------------------------ | -------------------- | ----------------------------------- | +| 字段名不匹配(中文prop vs 英文key) | 对比前端prop与后端VO字段 | prop 必须与 JSON key 一致 | +| rowKey不匹配(默认id vs 实际主键名) | 检查Entity @TableId字段名 | 显式设置 row-key="实际主键名" | +| 分页字段名(list vs records) | 检查返回类型 Page\ | 统一用 res.records | +| JSON字符串未解析 | 检查CLOB/JSON字段前端处理 | JSON.parse() 或 Array.isArray() 判断 | +| 数组当单对象 | 检查一对多关系的详情接口 | Array.isArray() ? data\[0] : data | +| 导出接口未设blob | 检查文件下载请求 | 设置 responseType: 'blob' | +| null值导致组件报错 | 检查码表/选项接口返回 | .filter(item => item.value != null) | +| 排序字段驼峰未转下划线 | 检查后端排序逻辑 | 字段名转下划线后再拼SQL | + +*** + +## 三、模块核对表 + +### 3.1 BS-1 大屏管理 + +#### 接口清单 + +| 方法 | 路径 | 入参类型 | 返回类型 | 说明 | +| ---- | --------------------------- | ----------------------------------- | ---------------------------------- | ------ | +| POST | /api/screen/query | ScreenQuery | RestResult\> | 分页查询 | +| GET | /api/screen/detail | String id | RestResult\ | 详情 | +| POST | /api/screen/save | ScreenSaveReq | RestResult\ | 新增 | +| POST | /api/screen/update | ScreenSaveReq | RestResult\ | 更新 | +| POST | /api/screen/remove | String id | RestResult\ | 删除 | +| GET | /api/screen/options | - | RestResult\> | 选项列表 | +| GET | /api/screen/district/list | - | RestResult\> | 行政区划选项 | +| POST | /api/screen/toggle-status | String id, Integer status | RestResult\ | 切换状态 | +| GET | /api/screen/check-code | String screenCode, String excludeId | RestResult\ | 编码唯一校验 | +| GET | /api/screen/check-address | String address, String excludeId | RestResult\ | 地址唯一校验 | +| GET | /api/screen/export | ScreenQuery | RestResult\> | 导出 | +| POST | /api/screen/import | List\ dataList | RestResult\ | 导入 | +| GET | /api/screen/import-template | - | RestResult\> | 导入模板 | +| GET | /api/screen/histories | String id | RestResult\> | 历史版本 | + +#### Query 字段 + +| 字段 | 类型 | 默认值 | 说明 | +| ------------ | ------- | --- | ----- | +| pageNum | Integer | 1 | 页码 | +| pageSize | Integer | 10 | 每页条数 | +| keyword | String | - | 关键词搜索 | +| district | String | - | 区域筛选 | +| screenStatus | Integer | - | 状态筛选 | + +#### SaveReq 字段 + +| 字段 | 类型 | 说明 | +| --------------- | ---------- | -------------- | +| id | String | 主键(更新时必传) | +| screenCode | String | 大屏编码(唯一)**必传** | +| screenName | String | 大屏名称 **必传** | +| address | String | 地址(唯一)**必传** | +| district | String | 所属区域 **必传** | +| ownerUnit | String | 业主单位 **必传** | +| ownerContact | String | 业主联系方式 | +| operatorUnit | String | 运营单位 **必传** | +| operatorContact | String | 运营联系方式 | +| advertiser | String | 广告主 | +| screenSpec | String | 屏幕规格 **必传** | +| adPlayTimeRange | String | 广告播放时间段 **必传** | +| screenStatus | Integer | 状态 | +| longitude | BigDecimal | 经度 | +| latitude | BigDecimal | 纬度 | + +#### 数据库表:bs\_screen + +| DB列 | Java字段 | 类型 | 约束 | +| --------------------- | --------------- | ------------- | ------------------------------ | +| ID | id | VARCHAR(50) | PK, ASSIGN\_UUID | +| SCREEN\_CODE | screenCode | VARCHAR(30) | NOT NULL, UNIQUE | +| SCREEN\_NAME | screenName | VARCHAR(100) | NOT NULL | +| ADDRESS | address | VARCHAR(200) | NOT NULL, UNIQUE | +| DISTRICT | district | VARCHAR(20) | NOT NULL | +| OWNER\_UNIT | ownerUnit | VARCHAR(100) | NOT NULL | +| OWNER\_CONTACT | ownerContact | VARCHAR(20) |
| +| OPERATOR\_UNIT | operatorUnit | VARCHAR(100) | NOT NULL | +| OPERATOR\_CONTACT | operatorContact | VARCHAR(20) |
| +| ADVERTISER | advertiser | VARCHAR(100) |
| +| SCREEN\_SPEC | screenSpec | VARCHAR(50) | NOT NULL | +| AD\_PLAY\_TIME\_RANGE | adPlayTimeRange | VARCHAR(20) | NOT NULL | +| SCREEN\_STATUS | screenStatus | TINYINT | NOT NULL, 默认1, 1=正常,2=停用,3=维修中 | +| LONGITUDE | longitude | DECIMAL(10,6) |
| +| LATITUDE | latitude | DECIMAL(10,6) |
| +| CREATE\_BY | - (SuperEntity) | VARCHAR(50) |
| +| CREATE\_TIME | - (SuperEntity) | TIMESTAMP |
| +| CREATE\_NAME | - (SuperEntity) | VARCHAR(50) |
| +| UPDATE\_BY | - (SuperEntity) | VARCHAR(50) |
| +| UPDATE\_TIME | - (SuperEntity) | TIMESTAMP |
| +| UPDATE\_NAME | - (SuperEntity) | VARCHAR(50) |
| + +关联表:bs\_screen\_history(历史版本) +DDL:V1.0.0\_\_BS\_screen\_ddl.sql + V1.0.0\_\_BS\_screen\_init\_data.sql + +*** + +### 3.2 LB-1 法律法规 + +#### 接口清单 + +| 方法 | 路径 | 入参类型 | 返回类型 | 说明 | +| ---- | ----------------------------------- | ------------------------------------- | ----------------------------------- | ------- | +| POST | /api/law-clause/query | LawClauseQuery | RestResult\> | 分页查询 | +| GET | /api/law-clause/detail | String id | RestResult\ | 详情 | +| POST | /api/law-clause/save | LawClauseSaveReq | RestResult\ | 新增 | +| POST | /api/law-clause/update | LawClauseSaveReq | RestResult\ | 更新 | +| POST | /api/law-clause/remove | String id | RestResult\ | 删除 | +| GET | /api/law-clause/options | - | RestResult\> | 选项列表 | +| POST | /api/law-clause/repeal | String id | RestResult\ | 废止 | +| GET | /api/law-clause/check-clause-number | String clauseNumber, String excludeId | RestResult\ | 条款号唯一校验 | +| GET | /api/law-clause/effective | - | RestResult\> | 已生效条款 | + +#### Query 字段 + +| 字段 | 类型 | 默认值 | 说明 | +| --------------- | ------- | --- | ------ | +| pageNum | Integer | 1 | 页码 | +| pageSize | Integer | 10 | 每页条数 | +| keyword | String | - | 关键词搜索 | +| effectiveStatus | Integer | - | 生效状态筛选 | + +#### SaveReq 字段 + +| 字段 | 类型 | 说明 | +| -------------------- | --------- | -------------- | +| id | String | 主键(更新时必传) | +| clauseCode | String | 条款编号(唯一)**必传** | +| lawName | String | 法规名称 **必传** | +| clauseNumber | String | 条款号 **必传** | +| clauseContent | String | 条款内容 **必传** | +| clauseContentSummary | String | 条款摘要 | +| effectiveStatus | Integer | 生效状态 1=有效,2=废止 | +| publishDate | LocalDate | 发布日期 | + +#### 数据库表:lb\_law\_clause + +| DB列 | Java字段 | 类型 | 约束 | +| -------------------------- | -------------------- | ------------- | ------------------------ | +| ID | id | VARCHAR(50) | PK, ASSIGN\_UUID | +| CLAUSE\_CODE | clauseCode | VARCHAR(30) | UNIQUE | +| LAW\_NAME | lawName | VARCHAR(200) | NOT NULL | +| CLAUSE\_NUMBER | clauseNumber | VARCHAR(50) | NOT NULL | +| CLAUSE\_CONTENT | clauseContent | VARCHAR(2000) | NOT NULL | +| CLAUSE\_CONTENT\_SUMMARY | clauseContentSummary | VARCHAR(200) |
| +| EFFECTIVE\_STATUS | effectiveStatus | TINYINT | NOT NULL, 默认1, 1=有效,2=废止 | +| PUBLISH\_DATE | publishDate | DATE |
| +| CREATE\_BY \~ UPDATE\_NAME | - (SuperEntity) | - | 审计字段 | + +DDL:V2.0.0\_\_LB\_law\_ddl.sql + V2.0.0\_\_LB\_law\_init\_data.sql + +*** + +### 3.3 MR-1 监测规则 + +#### 接口清单 + +| 方法 | 路径 | 入参类型 | 返回类型 | 说明 | +| ---- | ------------------------------------ | --------------------------------- | ------------------------------------------ | ------ | +| POST | /api/monitoring-rules/query | MonitoringRuleQuery | RestResult\> | 分页查询 | +| GET | /api/monitoring-rules/detail | String id | RestResult\ | 详情 | +| POST | /api/monitoring-rules/save | MonitoringRuleSaveReq | RestResult\ | 新增 | +| POST | /api/monitoring-rules/update | MonitoringRuleSaveReq | RestResult\ | 更新 | +| POST | /api/monitoring-rules/remove | String id | RestResult\ | 删除 | +| POST | /api/monitoring-rules/toggle-status | String id, Integer status | RestResult\ | 切换启用状态 | +| GET | /api/monitoring-rules/check-name | String ruleName, String excludeId | RestResult\ | 名称唯一校验 | +| GET | /api/monitoring-rules/enabled | - | RestResult\> | 已启用规则 | +| GET | /api/monitoring-rules/scope-types | - | RestResult\> | 范围类型选项 | +| GET | /api/monitoring-rules/status-options | - | RestResult\> | 状态选项 | +| POST | /api/monitoring-rules/export | MonitoringRuleQuery | RestResult\> | 导出 | + +#### Query 字段 + +| 字段 | 类型 | 默认值 | 说明 | +| ------------ | ------- | --- | ------ | +| pageNum | Integer | 1 | 页码 | +| pageSize | Integer | 10 | 每页条数 | +| keyword | String | - | 关键词搜索 | +| enableStatus | Integer | - | 启用状态筛选 | +| scopeType | Integer | - | 范围类型筛选 | + +#### SaveReq 字段 + +| 字段 | 类型 | 说明 | +| -------------- | ------------- | ------------------------------------ | +| id | String | 主键(更新时必传) | +| ruleCode | String | 规则编码(唯一) | +| ruleName | String | 规则名称(唯一) | +| ruleContent | String | 规则内容 | +| scopeType | Integer | 适用范围 1=全部大屏,2=指定区域 | +| scopeDistricts | String | 适用区域列表(JSON数组字符串)⚠️前端需JSON.stringify | +| enableStatus | Integer | 启用状态 1=已启用,2=已停用 | +| clauseIds | List\ | 关联法条ID列表 | + +#### DetailVO 额外字段 + +| 字段 | 类型 | 说明 | +| ---------- | ---------- | -------- | +| lawClauses | List\ | 关联法条详情列表 | +| histories | List\ | 操作历史列表 | + +#### 数据库表 + +主表:mr\_monitoring\_rule +关联表:mr\_rule\_law\_clause\_rel(规则-法条关联) +日志表:mr\_rule\_operation\_history(操作历史) + +| DB列 | Java字段 | 类型 | 约束 | +| -------------------------- | --------------- | ------------- | ---------------------- | +| ID | id | VARCHAR(50) | PK | +| RULE\_CODE | ruleCode | VARCHAR(30) | UNIQUE | +| RULE\_NAME | ruleName | VARCHAR(100) | UNIQUE | +| RULE\_CONTENT | ruleContent | VARCHAR(2000) |
| +| SCOPE\_TYPE | scopeType | TINYINT | 1=全部,2=指定区域 | +| SCOPE\_DISTRICTS | scopeDistricts | CLOB | JSON数组 ⚠️前端需JSON.parse | +| ENABLE\_STATUS | enableStatus | TINYINT | 1=启用,2=停用 | +| CREATE\_BY \~ UPDATE\_NAME | - (SuperEntity) | - | 审计字段 | + +DDL:V6.0.0\_\_MR\_monitoring\_rule\_ddl.sql + V6.0.0\_\_MR\_monitoring\_rule\_init\_data.sql + +⚠️ **JSON字段注意**:scopeDistricts 在 DB 中为 CLOB 存储 JSON 数组,后端 Entity 返回 String 类型。前端使用时需要 JSON.parse() 解析,不能直接当数组用。 + +*** + +### 3.4 AM-1 录屏设置 + +#### 接口清单 + +| 方法 | 路径 | 入参类型 | 返回类型 | 说明 | +| ---- | ------------------------------------------ | ------------------------- | ----------------------------------------- | ------- | +| POST | /api/recording-config/query | RecordingConfigQuery | RestResult\> | 分页查询 | +| GET | /api/recording-config/detail | String id | RestResult\ | 详情 | +| POST | /api/recording-config/save | RecordingConfigSaveReq | RestResult\ | 新增 | +| POST | /api/recording-config/update | RecordingConfigSaveReq | RestResult\ | 更新 | +| POST | /api/recording-config/remove | String id | RestResult\ | 删除 | +| GET | /api/recording-config/configurable-screens | - | RestResult\> | 可配置大屏列表 | +| POST | /api/recording-config/toggle-status | String id, Integer status | RestResult\ | 切换启用状态 | + +#### Query 字段 + +| 字段 | 类型 | 默认值 | 说明 | +| ------------ | ------- | --- | ------ | +| pageNum | Integer | 1 | 页码 | +| pageSize | Integer | 10 | 每页条数 | +| keyword | String | - | 关键词搜索 | +| district | String | - | 区域筛选 | +| configStatus | Integer | - | 配置状态筛选 | + +#### SaveReq 字段 + +| 字段 | 类型 | 说明 | +| --------------- | ------- | ---------------- | +| id | String | 主键(更新时必传) | +| screenId | String | 大屏ID(唯一约束) | +| screenName | String | 大屏名称(冗余) | +| screenAddress | String | 大屏地址(冗余) | +| district | String | 所属区域(冗余) | +| recordStartTime | String | 录屏开始时间 HH:MM:SS | +| recordEndTime | String | 录屏结束时间 HH:MM:SS | +| recordDuration | Integer | 单次录屏时长(秒,10-300) | +| recordFrequency | Integer | 录屏频率(分钟,1-60) | +| configStatus | Integer | 配置状态 1=已启用,2=已停用 | + +#### 数据库表:am\_recording\_config + +| DB列 | Java字段 | 类型 | 约束 | +| -------------------------- | --------------- | ------------ | --------- | +| ID | id | VARCHAR(50) | PK | +| SCREEN\_ID | screenId | VARCHAR(50) | UNIQUE | +| SCREEN\_NAME | screenName | VARCHAR(200) |
| +| SCREEN\_ADDRESS | screenAddress | VARCHAR(500) |
| +| DISTRICT | district | VARCHAR(50) |
| +| RECORD\_START\_TIME | recordStartTime | VARCHAR(8) | HH:MM:SS | +| RECORD\_END\_TIME | recordEndTime | VARCHAR(8) | HH:MM:SS | +| RECORD\_DURATION | recordDuration | INT | 10-300 | +| RECORD\_FREQUENCY | recordFrequency | INT | 1-60 | +| CONFIG\_STATUS | configStatus | TINYINT | 1=启用,2=停用 | +| CREATE\_BY \~ UPDATE\_NAME | - (SuperEntity) | - | 审计字段 | + +DDL:V3.0.0\_\_AM\_recording\_config\_ddl.sql(无 init\_data) + +*** + +### 3.5 AM-2 随机录屏 + +#### 接口清单 + +| 方法 | 路径 | 入参类型 | 返回类型 | 说明 | +| ---- | -------------------------- | ------------------ | --------------------------------------- | ---- | +| POST | /api/recording-task/query | RecordingTaskQuery | RestResult\> | 分页查询 | +| GET | /api/recording-task/detail | String id | RestResult\ | 详情 | + +#### Query 字段 + +| 字段 | 类型 | 默认值 | 说明 | +| -------------- | ------- | --- | ------- | +| pageNum | Integer | 1 | 页码 | +| pageSize | Integer | 10 | 每页条数 | +| screenId | String | - | 大屏筛选 | +| taskStatus | Integer | - | 任务状态筛选 | +| startTimeBegin | String | - | 开始时间范围起 | +| startTimeEnd | String | - | 开始时间范围止 | +| district | String | - | 区域筛选 | +| screenName | String | - | 大屏名称筛选 | + +#### 数据库表:am\_recording\_task + +| DB列 | Java字段 | 类型 | 约束 | +| -------------------------- | --------------- | ------------ | ---------------- | +| ID | id | VARCHAR(50) | PK | +| SCREEN\_ID | screenId | VARCHAR(50) |
| +| CONFIG\_ID | configId | VARCHAR(50) |
| +| ACTUAL\_START\_TIME | actualStartTime | TIMESTAMP |
| +| ACTUAL\_END\_TIME | actualEndTime | TIMESTAMP |
| +| TASK\_STATUS | taskStatus | TINYINT | 1=录屏中,2=已完成,3=失败 | +| VIDEO\_FILE\_PATH | videoFilePath | VARCHAR(500) |
| +| RETRY\_COUNT | retryCount | INT |
| +| ERROR\_MESSAGE | errorMessage | VARCHAR(500) |
| +| CREATE\_BY \~ UPDATE\_NAME | - (SuperEntity) | - | 审计字段 | + +关联表:am\_alert\_notification(告警通知) + +| DB列 | Java字段 | 类型 | 约束 | +| -------------------------- | --------------- | ------------ | -------------------- | +| ID | id | VARCHAR(50) | PK | +| TASK\_ID | taskId | VARCHAR(50) |
| +| SCREEN\_ID | screenId | VARCHAR(50) |
| +| ALERT\_TYPE | alertType | TINYINT | 1=录屏失败,2=录屏超时,3=设备离线 | +| ALERT\_MESSAGE | alertMessage | VARCHAR(500) |
| +| IS\_RESOLVED | isResolved | TINYINT | 0=未处理,1=已处理 | +| RESOLVED\_BY | resolvedBy | VARCHAR(100) |
| +| RESOLVED\_AT | resolvedAt | TIMESTAMP |
| +| CREATE\_BY \~ UPDATE\_NAME | - (SuperEntity) | - | 审计字段 | + +DDL:V4.0.0\_\_AM\_recording\_task\_ddl.sql(无 init\_data) + +*** + +### 3.6 AM-3 广告画面监控 + +#### 接口清单 + +| 方法 | 路径 | 入参类型 | 返回类型 | 说明 | +| ---- | -------------------------- | ------------------ | --------------------------------------- | ---- | +| POST | /api/monitor-record/query | MonitorRecordQuery | RestResult\> | 分页查询 | +| GET | /api/monitor-record/detail | String id | RestResult\ | 详情 | +| POST | /api/monitor-record/start | String id | RestResult\ | 开始监控 | +| POST | /api/monitor-record/judge | MonitorJudgeReq | RestResult\ | 监控判定 | + +#### Query 字段 + +| 字段 | 类型 | 默认值 | 说明 | +| ------------- | ------- | --- | ------ | +| pageNum | Integer | 1 | 页码 | +| pageSize | Integer | 10 | 每页条数 | +| screenId | String | - | 大屏筛选 | +| monitorStatus | Integer | - | 监控状态筛选 | +| district | String | - | 区域筛选 | +| startTime | String | - | 开始时间 | +| endTime | String | - | 结束时间 | +| monitorPerson | String | - | 监控人 | +| screenName | String | - | 大屏名称 | + +#### JudgeReq 字段 + +| 字段 | 类型 | 说明 | +| ------------- | ------- | -------------- | +| id | String | 记录ID | +| monitorStatus | Integer | 判定状态 3=正常,4=违规 | +| monitorResult | String | 判定结果描述 | + +#### 数据库表:am\_monitor\_record + +| DB列 | Java字段 | 类型 | 约束 | +| -------------------------- | --------------- | ------------ | --------------------- | +| ID | id | VARCHAR(50) | PK | +| TASK\_ID | taskId | VARCHAR(50) |
| +| SCREEN\_ID | screenId | VARCHAR(50) |
| +| SCREEN\_NAME | screenName | VARCHAR(200) | 冗余 | +| SCREEN\_ADDRESS | screenAddress | VARCHAR(500) | 冗余 | +| DISTRICT | district | VARCHAR(50) | 冗余 | +| MONITOR\_STATUS | monitorStatus | TINYINT | 1=待监控,2=监控中,3=正常,4=违规 | +| MONITOR\_RESULT | monitorResult | VARCHAR(500) |
| +| MONITOR\_PERSON | monitorPerson | VARCHAR(100) |
| +| MONITORED\_AT | monitoredAt | TIMESTAMP |
| +| CREATE\_BY \~ UPDATE\_NAME | - (SuperEntity) | - | 审计字段 | + +DDL:V5.0.0\_\_AM\_monitor\_record\_ddl.sql(无 init\_data) + +*** + +### 3.7 CW-1 固化取证 + +#### 接口清单 + +| 方法 | 路径 | 入参类型 | 返回类型 | 说明 | +| ---- | ----------------------------- | --------------------- | ------------------------------------------ | ---- | +| POST | /api/evidence-record/query | EvidenceRecordQuery | RestResult\> | 分页查询 | +| GET | /api/evidence-record/detail | String id | RestResult\ | 详情 | +| POST | /api/evidence-record/save | EvidenceRecordSaveReq | RestResult\ | 保存取证 | +| GET | /api/evidence-record/download | String id | RestResult\ | 下载地址 | +| GET | /api/evidence-record/play | String id | RestResult\ | 播放地址 | + +#### Query 字段 + +| 字段 | 类型 | 默认值 | 说明 | +| -------------- | ------- | --- | ------ | +| pageNum | Integer | 1 | 页码 | +| pageSize | Integer | 10 | 每页条数 | +| district | String | - | 区域筛选 | +| evidenceStatus | Integer | - | 取证状态筛选 | +| startTime | String | - | 开始时间 | +| endTime | String | - | 结束时间 | +| evidencePerson | String | - | 取证人 | + +#### SaveReq 字段 + +| 字段 | 类型 | 说明 | +| ----------------- | ------- | ---------------------- | +| monitorRecordId | String | 关联监测记录ID **必传** | +| screenId | String | 大屏ID **必传** | +| evidenceVideoFile | String | 取证视频文件路径 **必传** | +| clipStartTime | String | 片段起始时间 HH:MM:SS **必传** | +| clipEndTime | String | 片段结束时间 HH:MM:SS **必传** | +| clipDuration | Integer | 片段时长(秒,>=3)**必传** | +| evidencePerson | String | 取证人 **必传** | + +#### DetailVO 额外字段 + +| 字段 | 类型 | 说明 | +| ------------- | ---------- | ------ | +| statusHistory | List\ | 状态变更历史 | + +#### 数据库表 + +主表:cw\_evidence\_record +日志表:cw\_evidence\_status\_history + +主表字段: + +| DB列 | Java字段 | 类型 | 约束 | +| -------------------------- | ------------------- | ------------ | -------------------------------------- | +| ID | id | VARCHAR(50) | PK | +| MONITOR\_RECORD\_ID | monitorRecordId | VARCHAR(50) | NOT NULL | +| SCREEN\_ID | screenId | VARCHAR(50) | NOT NULL | +| SCREEN\_NAME | screenName | VARCHAR(200) | NOT NULL, 冗余 | +| SCREEN\_ADDRESS | screenAddress | VARCHAR(500) | NOT NULL, 冗余 | +| DISTRICT | district | VARCHAR(50) | NOT NULL, 冗余 | +| EVIDENCE\_VIDEO\_FILE | evidenceVideoFile | VARCHAR(500) | NOT NULL, UNIQUE | +| CLIP\_START\_TIME | clipStartTime | VARCHAR(8) | NOT NULL, HH:MM:SS | +| CLIP\_END\_TIME | clipEndTime | VARCHAR(8) | NOT NULL, HH:MM:SS | +| CLIP\_DURATION | clipDuration | INT | NOT NULL, >=3 | +| EVIDENCE\_STATUS | evidenceStatus | TINYINT | NOT NULL, 默认1, 1=待关联规则,2=已关联规则,3=已生成线索 | +| EVIDENCE\_PERSON | evidencePerson | VARCHAR(100) | NOT NULL | +| EVIDENCED\_AT | evidencedAt | TIMESTAMP | NOT NULL | +| SOURCE\_MONITOR\_PERSON | sourceMonitorPerson | VARCHAR(100) | NOT NULL, 冗余 | +| SOURCE\_MONITOR\_TIME | sourceMonitorTime | TIMESTAMP | 冗余 | +| SOURCE\_MONITOR\_REMARK | sourceMonitorRemark | VARCHAR(500) | 冗余 | +| CREATE\_BY \~ UPDATE\_NAME | - (SuperEntity) | - | 审计字段 | + +DDL:V7.0.0\_\_CW\_evidence\_ddl.sql(无 init\_data) + +⚠️ **文件下载/播放**:download 和 play 接口当前为占位实现,需对接文件存储系统。 + +*** + +### 3.8 CW-2 规则关联 + +#### 接口清单 + +| 方法 | 路径 | 入参类型 | 返回类型 | 说明 | +| ---- | --------------------------------------------- | ----------------- | ----------------------- | -------- | +| GET | /api/evidence-rule-relation/query-by-evidence | String evidenceId | RestResult\> | 按证据查关联规则 | +| POST | /api/evidence-rule-relation/relate | RuleRelateReq | RestResult\ | 关联规则 | + +#### RuleRelateReq 字段 + +| 字段 | 类型 | 说明 | +| ---------- | ------------- | ------ | +| evidenceId | String | 证据ID | +| ruleIds | List\ | 规则ID列表 | + +#### 数据库表:cw\_evidence\_rule\_relation + +| DB列 | Java字段 | 类型 | 约束 | +| -------------- | ------------ | ----------- | ------ | +| ID | id | VARCHAR(50) | PK | +| EVIDENCE\_ID | evidenceId | VARCHAR(50) |
| +| RULE\_ID | ruleId | VARCHAR(50) |
| +| ASSOCIATED\_BY | associatedBy | VARCHAR(50) |
| +| ASSOCIATED\_AT | associatedAt | TIMESTAMP |
| + +DDL:V8.0.0\_\_CW\_evidence\_rule\_relation\_ddl.sql(无 init\_data) + +*** + +### 3.9 CW-3 线索生成 + +#### 接口清单 + +| 方法 | 路径 | 入参类型 | 返回类型 | 说明 | +| ---- | ----------------------------------- | ------------------- | ------------------------------------------ | ------- | +| POST | /api/monitoring-clue/query | MonitoringClueQuery | RestResult\> | 分页查询 | +| GET | /api/monitoring-clue/detail | String id | RestResult\ | 详情 | +| POST | /api/monitoring-clue/generate | String evidenceId | RestResult\ | 生成线索 | +| GET | /api/monitoring-clue/clue-preview | String evidenceId | RestResult\ | 生成前预览 | +| GET | /api/monitoring-clue/status-summary | - | RestResult\> | 各状态数量统计 | + +#### Query 字段 + +| 字段 | 类型 | 默认值 | 说明 | +| ---------- | ------- | --- | ------ | +| pageNum | Integer | 1 | 页码 | +| pageSize | Integer | 10 | 每页条数 | +| clueCode | String | - | 线索编码 | +| district | String | - | 区域筛选 | +| clueStatus | Integer | - | 线索状态筛选 | +| keyword | String | - | 关键词 | + +#### DetailVO 额外字段 + +| 字段 | 类型 | 说明 | +| -------------- | ---------- | ------ | +| generationLogs | List\ | 生成日志列表 | + +#### 数据库表 + +主表:cw\_monitoring\_clue +日志表:cw\_clue\_generation\_log + +主表字段: + +| DB列 | Java字段 | 类型 | 约束 | +| -------------------------- | ----------------- | ------------ | ------------------------------- | +| ID | id | VARCHAR(50) | PK | +| CLUE\_CODE | clueCode | VARCHAR(20) | UNIQUE, 格式 XS-{YYYYMMDD}-{seq3} | +| EVIDENCE\_ID | evidenceId | VARCHAR(50) | UNIQUE | +| SCREEN\_ID | screenId | VARCHAR(50) |
| +| SCREEN\_NAME | screenName | VARCHAR(100) | 冗余 | +| SCREEN\_ADDRESS | screenAddress | VARCHAR(200) | 冗余 | +| DISTRICT | district | VARCHAR(20) | 冗余 | +| OWNER\_UNIT | ownerUnit | VARCHAR(100) | 冗余 | +| OWNER\_CONTACT | ownerContact | VARCHAR(20) | 冗余 | +| OPERATOR\_UNIT | operatorUnit | VARCHAR(100) | 冗余 | +| OPERATOR\_CONTACT | operatorContact | VARCHAR(20) | 冗余 | +| ADVERTISER | advertiser | VARCHAR(100) | 冗余 | +| RELATED\_RULES | relatedRules | CLOB | JSON数组 ⚠️需JSON.parse | +| RELATED\_LAW\_CLAUSES | relatedLawClauses | CLOB | JSON数组 ⚠️需JSON.parse | +| VIDEO\_EVIDENCE\_PATH | videoEvidencePath | VARCHAR(500) |
| +| CLIP\_START\_TIME | clipStartTime | VARCHAR(8) | 冗余 | +| CLIP\_END\_TIME | clipEndTime | VARCHAR(8) | 冗余 | +| CLIP\_DURATION | clipDuration | INT | 冗余 | +| CLUE\_STATUS | clueStatus | TINYINT | 1=待转办,2=已转办,3=处理中,4=已办结 | +| GENERATED\_BY | generatedBy | VARCHAR(100) |
| +| GENERATED\_AT | generatedAt | TIMESTAMP |
| +| TRANSFERRED\_AT | transferredAt | TIMESTAMP |
| +| CREATE\_BY \~ UPDATE\_NAME | - (SuperEntity) | - | 审计字段 | + +DDL:V9.0.0\_\_CW\_monitoring\_clue\_ddl.sql(无 init\_data) + +⚠️ **JSON字段注意**:relatedRules 和 relatedLawClauses 为 CLOB 存储 JSON 数组,前端需 JSON.parse()。 +⚠️ **线索编码规则**:自动生成,格式 `XS-{YYYYMMDD}-{seq3}`。 + +*** + +### 3.10 CW-4 线索转办 + +#### 接口清单 + +| 方法 | 路径 | 入参类型 | 返回类型 | 说明 | +| ---- | --------------------------------------------------- | ----------------------- | ---------------------------------------- | ---------- | +| POST | /api/clue-transfer/query | ClueTransferQuery | RestResult\> | 分页查询 | +| GET | /api/clue-transfer/detail | String id | RestResult\ | 详情 | +| POST | /api/clue-transfer/submit | ClueTransferReq | RestResult\ | 提交转办 | +| GET | /api/clue-transfer/targets/districts | - | RestResult\> | 目标区域 | +| GET | /api/clue-transfer/targets/departments | String districtCode | RestResult\> | 目标部门 | +| GET | /api/clue-transfer/targets/persons | String departmentId | RestResult\> | 目标人员 | +| GET | /api/clue-transfer/clues/{clueId}/disposal-feedback | String clueId | RestResult\ | 处置反馈 | +| POST | /api/clue-transfer/pending-clues/query | PendingClueQuery | RestResult\> | 待转办线索查询 | +| GET | /api/clue-transfer/pending-clues/detail | String clueId | RestResult\ | 待转办线索详情 | +| GET | /api/clue-transfer/operation-logs | String transferRecordId | RestResult\> | 操作日志 | +| POST | /api/clue-transfer/status-update | TransferStatusUpdateReq | RestResult\ | 状态更新(外部回调) | +| POST | /api/clue-transfer/urge | TransferUrgeReq | RestResult\ | 催办 | +| POST | /api/clue-transfer/withdraw | TransferWithdrawReq | RestResult\ | 撤回 | + +#### ClueTransferQuery 字段 + +| 字段 | 类型 | 默认值 | 说明 | +| ---------------------- | ------- | --- | ---- | +| pageNum | Integer | 1 | 页码 | +| pageSize | Integer | 10 | 每页条数 | +| clueId | String | - | 线索ID | +| transferTargetDistrict | String | - | 目标区域 | +| transferStatus | String | - | 转办状态 | + +#### ClueTransferReq 字段 + +| 字段 | 类型 | 说明 | +| ------------------------ | ------ | ----- | +| clueId | String | 线索ID | +| transferTargetDistrict | String | 目标区域 | +| transferTargetDepartment | String | 目标部门 | +| transferTargetPerson | String | 目标联系人 | +| transferDescription | String | 转办说明 | + +#### PendingClueQuery 字段 + +| 字段 | 类型 | 默认值 | 说明 | +| -------- | ------- | --- | ---- | +| pageNum | Integer | 1 | 页码 | +| pageSize | Integer | 10 | 每页条数 | +| clueCode | String | - | 线索编码 | +| district | String | - | 区域 | +| keyword | String | - | 关键词 | + +#### 其他 Req 字段 + +**TransferStatusUpdateReq** + +| 字段 | 类型 | 说明 | +| ---------------- | ------ | ------ | +| transferRecordId | String | 转办记录ID | +| newStatus | String | 新状态 | +| externalClueId | String | 外部线索ID | +| disposalResult | String | 处置结果 | +| remark | String | 备注 | + +**TransferUrgeReq** + +| 字段 | 类型 | 说明 | +| ---------------- | ------ | ------ | +| transferRecordId | String | 转办记录ID | +| urgeMessage | String | 催办信息 | + +**TransferWithdrawReq** + +| 字段 | 类型 | 说明 | +| ---------------- | ------ | ------ | +| transferRecordId | String | 转办记录ID | +| withdrawReason | String | 撤回原因 | + +#### ClueTransferDetailVO 额外字段 + +| 字段 | 类型 | 说明 | +| ------------- | ---------- | ---- | +| clueCode | String | 线索编码 | +| operationLogs | List\ | 操作日志 | + +#### 数据库表 + +主表:cw\_clue\_transfer\_record +日志表:cw\_transfer\_operation\_log + +主表字段: + +| DB列 | Java字段 | 类型 | 约束 | +| ---------------------------- | ------------------------ | ------------- | --------------------------------------- | +| ID | id | VARCHAR(50) | PK | +| CLUE\_ID | clueId | VARCHAR(50) |
| +| TRANSFER\_TARGET\_DISTRICT | transferTargetDistrict | VARCHAR(20) |
| +| TRANSFER\_TARGET\_DEPARTMENT | transferTargetDepartment | VARCHAR(100) |
| +| TRANSFER\_TARGET\_PERSON | transferTargetPerson | VARCHAR(50) |
| +| TRANSFER\_DESCRIPTION | transferDescription | VARCHAR(500) |
| +| TRANSFER\_PERSON | transferPerson | VARCHAR(100) |
| +| TRANSFERRED\_AT | transferredAt | TIMESTAMP |
| +| TRANSFER\_STATUS | transferStatus | VARCHAR(20) | transferred/processing/completed/failed | +| EXTERNAL\_CLUE\_ID | externalClueId | VARCHAR(100) |
| +| DISPOSAL\_RESULT | disposalResult | VARCHAR(2000) |
| +| DISPOSAL\_COMPLETED\_AT | disposalCompletedAt | TIMESTAMP |
| +| CREATE\_BY \~ UPDATE\_NAME | - (SuperEntity) | - | 审计字段 | + +DDL:V10.0.0\_\_CW\_clue\_transfer\_ddl.sql(无 init\_data) + +⚠️ **模拟数据**:targets/districts、targets/departments、targets/persons 接口当前返回模拟数据,需对接组织架构系统。 +⚠️ **状态流转**:transferred → processing → completed/failed,通过 status-update 接口由外部系统回调。