# 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 接口由外部系统回调。