gz-oarms/docs/前后端联调指南.md

759 lines
45 KiB
Markdown
Raw Permalink Normal View History

# 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\<Entity> | 统一用 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\<Page\<ScreenDetailVO>> | 分页查询 |
| GET | /api/screen/detail | String id | RestResult\<ScreenDetailVO> | 详情 |
| POST | /api/screen/save | ScreenSaveReq | RestResult\<?> | 新增 |
| POST | /api/screen/update | ScreenSaveReq | RestResult\<?> | 更新 |
| POST | /api/screen/remove | String id | RestResult\<?> | 删除 |
| GET | /api/screen/options | - | RestResult\<List\<Map>> | 选项列表 |
| GET | /api/screen/district/list | - | RestResult\<List\<Map>> | 行政区划选项 |
| POST | /api/screen/toggle-status | String id, Integer status | RestResult\<?> | 切换状态 |
| GET | /api/screen/check-code | String screenCode, String excludeId | RestResult\<Map> | 编码唯一校验 |
| GET | /api/screen/check-address | String address, String excludeId | RestResult\<Map> | 地址唯一校验 |
| GET | /api/screen/export | ScreenQuery | RestResult\<List\<Map>> | 导出 |
| POST | /api/screen/import | List\<Map> dataList | RestResult\<Map> | 导入 |
| GET | /api/screen/import-template | - | RestResult\<List\<Map>> | 导入模板 |
| GET | /api/screen/histories | String id | RestResult\<List\<Map>> | 历史版本 |
#### 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) | <br /> |
| OPERATOR\_UNIT | operatorUnit | VARCHAR(100) | NOT NULL |
| OPERATOR\_CONTACT | operatorContact | VARCHAR(20) | <br /> |
| ADVERTISER | advertiser | VARCHAR(100) | <br /> |
| 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) | <br /> |
| LATITUDE | latitude | DECIMAL(10,6) | <br /> |
| CREATE\_BY | - (SuperEntity) | VARCHAR(50) | <br /> |
| CREATE\_TIME | - (SuperEntity) | TIMESTAMP | <br /> |
| CREATE\_NAME | - (SuperEntity) | VARCHAR(50) | <br /> |
| UPDATE\_BY | - (SuperEntity) | VARCHAR(50) | <br /> |
| UPDATE\_TIME | - (SuperEntity) | TIMESTAMP | <br /> |
| UPDATE\_NAME | - (SuperEntity) | VARCHAR(50) | <br /> |
关联表bs\_screen\_history历史版本
DDLV1.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\<Page\<LawClauseEntity>> | 分页查询 |
| GET | /api/law-clause/detail | String id | RestResult\<LawClauseEntity> | 详情 |
| 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\<List\<Map>> | 选项列表 |
| POST | /api/law-clause/repeal | String id | RestResult\<?> | 废止 |
| GET | /api/law-clause/check-clause-number | String clauseNumber, String excludeId | RestResult\<Map> | 条款号唯一校验 |
| GET | /api/law-clause/effective | - | RestResult\<List\<LawClauseEntity>> | 已生效条款 |
#### 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) | <br /> |
| EFFECTIVE\_STATUS | effectiveStatus | TINYINT | NOT NULL, 默认1, 1=有效,2=废止 |
| PUBLISH\_DATE | publishDate | DATE | <br /> |
| CREATE\_BY \~ UPDATE\_NAME | - (SuperEntity) | - | 审计字段 |
DDLV2.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\<Page\<MonitoringRuleDetailVO>> | 分页查询 |
| GET | /api/monitoring-rules/detail | String id | RestResult\<MonitoringRuleDetailVO> | 详情 |
| 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\<Map> | 名称唯一校验 |
| GET | /api/monitoring-rules/enabled | - | RestResult\<List\<Map>> | 已启用规则 |
| GET | /api/monitoring-rules/scope-types | - | RestResult\<List\<Map>> | 范围类型选项 |
| GET | /api/monitoring-rules/status-options | - | RestResult\<List\<Map>> | 状态选项 |
| POST | /api/monitoring-rules/export | MonitoringRuleQuery | RestResult\<List\<Map>> | 导出 |
#### 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\<String> | 关联法条ID列表 |
#### DetailVO 额外字段
| 字段 | 类型 | 说明 |
| ---------- | ---------- | -------- |
| lawClauses | List\<Map> | 关联法条详情列表 |
| histories | List\<Map> | 操作历史列表 |
#### 数据库表
主表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) | <br /> |
| SCOPE\_TYPE | scopeType | TINYINT | 1=全部,2=指定区域 |
| SCOPE\_DISTRICTS | scopeDistricts | CLOB | JSON数组 ⚠前端需JSON.parse |
| ENABLE\_STATUS | enableStatus | TINYINT | 1=启用,2=停用 |
| CREATE\_BY \~ UPDATE\_NAME | - (SuperEntity) | - | 审计字段 |
DDLV6.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\<Page\<RecordingConfigEntity>> | 分页查询 |
| GET | /api/recording-config/detail | String id | RestResult\<RecordingConfigEntity> | 详情 |
| 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\<List\<Map>> | 可配置大屏列表 |
| 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) | <br /> |
| SCREEN\_ADDRESS | screenAddress | VARCHAR(500) | <br /> |
| DISTRICT | district | VARCHAR(50) | <br /> |
| 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) | - | 审计字段 |
DDLV3.0.0\_\_AM\_recording\_config\_ddl.sql无 init\_data
***
### 3.5 AM-2 随机录屏
#### 接口清单
| 方法 | 路径 | 入参类型 | 返回类型 | 说明 |
| ---- | -------------------------- | ------------------ | --------------------------------------- | ---- |
| POST | /api/recording-task/query | RecordingTaskQuery | RestResult\<Page\<RecordingTaskEntity>> | 分页查询 |
| GET | /api/recording-task/detail | String id | RestResult\<Map> | 详情 |
#### 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) | <br /> |
| CONFIG\_ID | configId | VARCHAR(50) | <br /> |
| ACTUAL\_START\_TIME | actualStartTime | TIMESTAMP | <br /> |
| ACTUAL\_END\_TIME | actualEndTime | TIMESTAMP | <br /> |
| TASK\_STATUS | taskStatus | TINYINT | 1=录屏中,2=已完成,3=失败 |
| VIDEO\_FILE\_PATH | videoFilePath | VARCHAR(500) | <br /> |
| RETRY\_COUNT | retryCount | INT | <br /> |
| ERROR\_MESSAGE | errorMessage | VARCHAR(500) | <br /> |
| CREATE\_BY \~ UPDATE\_NAME | - (SuperEntity) | - | 审计字段 |
关联表am\_alert\_notification告警通知
| DB列 | Java字段 | 类型 | 约束 |
| -------------------------- | --------------- | ------------ | -------------------- |
| ID | id | VARCHAR(50) | PK |
| TASK\_ID | taskId | VARCHAR(50) | <br /> |
| SCREEN\_ID | screenId | VARCHAR(50) | <br /> |
| ALERT\_TYPE | alertType | TINYINT | 1=录屏失败,2=录屏超时,3=设备离线 |
| ALERT\_MESSAGE | alertMessage | VARCHAR(500) | <br /> |
| IS\_RESOLVED | isResolved | TINYINT | 0=未处理,1=已处理 |
| RESOLVED\_BY | resolvedBy | VARCHAR(100) | <br /> |
| RESOLVED\_AT | resolvedAt | TIMESTAMP | <br /> |
| CREATE\_BY \~ UPDATE\_NAME | - (SuperEntity) | - | 审计字段 |
DDLV4.0.0\_\_AM\_recording\_task\_ddl.sql无 init\_data
***
### 3.6 AM-3 广告画面监控
#### 接口清单
| 方法 | 路径 | 入参类型 | 返回类型 | 说明 |
| ---- | -------------------------- | ------------------ | --------------------------------------- | ---- |
| POST | /api/monitor-record/query | MonitorRecordQuery | RestResult\<Page\<MonitorRecordEntity>> | 分页查询 |
| GET | /api/monitor-record/detail | String id | RestResult\<MonitorRecordEntity> | 详情 |
| 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) | <br /> |
| SCREEN\_ID | screenId | VARCHAR(50) | <br /> |
| 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) | <br /> |
| MONITOR\_PERSON | monitorPerson | VARCHAR(100) | <br /> |
| MONITORED\_AT | monitoredAt | TIMESTAMP | <br /> |
| CREATE\_BY \~ UPDATE\_NAME | - (SuperEntity) | - | 审计字段 |
DDLV5.0.0\_\_AM\_monitor\_record\_ddl.sql无 init\_data
***
### 3.7 CW-1 固化取证
#### 接口清单
| 方法 | 路径 | 入参类型 | 返回类型 | 说明 |
| ---- | ----------------------------- | --------------------- | ------------------------------------------ | ---- |
| POST | /api/evidence-record/query | EvidenceRecordQuery | RestResult\<Page\<EvidenceRecordDetailVO>> | 分页查询 |
| GET | /api/evidence-record/detail | String id | RestResult\<EvidenceRecordDetailVO> | 详情 |
| POST | /api/evidence-record/save | EvidenceRecordSaveReq | RestResult\<?> | 保存取证 |
| GET | /api/evidence-record/download | String id | RestResult\<Map> | 下载地址 |
| GET | /api/evidence-record/play | String id | RestResult\<Map> | 播放地址 |
#### 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\<Map> | 状态变更历史 |
#### 数据库表
主表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) | - | 审计字段 |
DDLV7.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\<List\<Map>> | 按证据查关联规则 |
| POST | /api/evidence-rule-relation/relate | RuleRelateReq | RestResult\<?> | 关联规则 |
#### RuleRelateReq 字段
| 字段 | 类型 | 说明 |
| ---------- | ------------- | ------ |
| evidenceId | String | 证据ID |
| ruleIds | List\<String> | 规则ID列表 |
#### 数据库表cw\_evidence\_rule\_relation
| DB列 | Java字段 | 类型 | 约束 |
| -------------- | ------------ | ----------- | ------ |
| ID | id | VARCHAR(50) | PK |
| EVIDENCE\_ID | evidenceId | VARCHAR(50) | <br /> |
| RULE\_ID | ruleId | VARCHAR(50) | <br /> |
| ASSOCIATED\_BY | associatedBy | VARCHAR(50) | <br /> |
| ASSOCIATED\_AT | associatedAt | TIMESTAMP | <br /> |
DDLV8.0.0\_\_CW\_evidence\_rule\_relation\_ddl.sql无 init\_data
***
### 3.9 CW-3 线索生成
#### 接口清单
| 方法 | 路径 | 入参类型 | 返回类型 | 说明 |
| ---- | ----------------------------------- | ------------------- | ------------------------------------------ | ------- |
| POST | /api/monitoring-clue/query | MonitoringClueQuery | RestResult\<Page\<MonitoringClueDetailVO>> | 分页查询 |
| GET | /api/monitoring-clue/detail | String id | RestResult\<MonitoringClueDetailVO> | 详情 |
| POST | /api/monitoring-clue/generate | String evidenceId | RestResult\<?> | 生成线索 |
| GET | /api/monitoring-clue/clue-preview | String evidenceId | RestResult\<Map> | 生成前预览 |
| GET | /api/monitoring-clue/status-summary | - | RestResult\<List\<Map>> | 各状态数量统计 |
#### Query 字段
| 字段 | 类型 | 默认值 | 说明 |
| ---------- | ------- | --- | ------ |
| pageNum | Integer | 1 | 页码 |
| pageSize | Integer | 10 | 每页条数 |
| clueCode | String | - | 线索编码 |
| district | String | - | 区域筛选 |
| clueStatus | Integer | - | 线索状态筛选 |
| keyword | String | - | 关键词 |
#### DetailVO 额外字段
| 字段 | 类型 | 说明 |
| -------------- | ---------- | ------ |
| generationLogs | List\<Map> | 生成日志列表 |
#### 数据库表
主表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) | <br /> |
| 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) | <br /> |
| 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) | <br /> |
| GENERATED\_AT | generatedAt | TIMESTAMP | <br /> |
| TRANSFERRED\_AT | transferredAt | TIMESTAMP | <br /> |
| CREATE\_BY \~ UPDATE\_NAME | - (SuperEntity) | - | 审计字段 |
DDLV9.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\<Page\<ClueTransferDetailVO>> | 分页查询 |
| GET | /api/clue-transfer/detail | String id | RestResult\<ClueTransferDetailVO> | 详情 |
| POST | /api/clue-transfer/submit | ClueTransferReq | RestResult\<?> | 提交转办 |
| GET | /api/clue-transfer/targets/districts | - | RestResult\<List\<Map>> | 目标区域 |
| GET | /api/clue-transfer/targets/departments | String districtCode | RestResult\<List\<Map>> | 目标部门 |
| GET | /api/clue-transfer/targets/persons | String departmentId | RestResult\<List\<Map>> | 目标人员 |
| GET | /api/clue-transfer/clues/{clueId}/disposal-feedback | String clueId | RestResult\<Map> | 处置反馈 |
| POST | /api/clue-transfer/pending-clues/query | PendingClueQuery | RestResult\<Page\<PendingClueVO>> | 待转办线索查询 |
| GET | /api/clue-transfer/pending-clues/detail | String clueId | RestResult\<PendingClueDetailVO> | 待转办线索详情 |
| GET | /api/clue-transfer/operation-logs | String transferRecordId | RestResult\<List\<OperationLogVO>> | 操作日志 |
| 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\<Map> | 操作日志 |
#### 数据库表
主表cw\_clue\_transfer\_record
日志表cw\_transfer\_operation\_log
主表字段:
| DB列 | Java字段 | 类型 | 约束 |
| ---------------------------- | ------------------------ | ------------- | --------------------------------------- |
| ID | id | VARCHAR(50) | PK |
| CLUE\_ID | clueId | VARCHAR(50) | <br /> |
| TRANSFER\_TARGET\_DISTRICT | transferTargetDistrict | VARCHAR(20) | <br /> |
| TRANSFER\_TARGET\_DEPARTMENT | transferTargetDepartment | VARCHAR(100) | <br /> |
| TRANSFER\_TARGET\_PERSON | transferTargetPerson | VARCHAR(50) | <br /> |
| TRANSFER\_DESCRIPTION | transferDescription | VARCHAR(500) | <br /> |
| TRANSFER\_PERSON | transferPerson | VARCHAR(100) | <br /> |
| TRANSFERRED\_AT | transferredAt | TIMESTAMP | <br /> |
| TRANSFER\_STATUS | transferStatus | VARCHAR(20) | transferred/processing/completed/failed |
| EXTERNAL\_CLUE\_ID | externalClueId | VARCHAR(100) | <br /> |
| DISPOSAL\_RESULT | disposalResult | VARCHAR(2000) | <br /> |
| DISPOSAL\_COMPLETED\_AT | disposalCompletedAt | TIMESTAMP | <br /> |
| CREATE\_BY \~ UPDATE\_NAME | - (SuperEntity) | - | 审计字段 |
DDLV10.0.0\_\_CW\_clue\_transfer\_ddl.sql无 init\_data
⚠️ **模拟数据**targets/districts、targets/departments、targets/persons 接口当前返回模拟数据,需对接组织架构系统。
⚠️ **状态流转**transferred → processing → completed/failed通过 status-update 接口由外部系统回调。