docs(video): 遗留项防御性加固 — GB2022 扩展字段 exist=false + Mapper 继承警告

基于遗留项调研结论(三项均无当前运行时风险,真正价值是防御未来
误用 BaseMapperX 高层方法),执行最小化防御性修复:

PlatformChannel 的 20 个 GB2022 扩展字段加 @TableField(exist=false):
- customSecurityLevelCode / customPhotoelectricImagingTyp /
  customCapturePositionType / customStreamNumberList /
  customSsvcRatioSupportList / customMobileDeviceType /
  customHorizontalFieldAngle / customVerticalFieldAngle /
  customMaxViewDistance / customGrassrootsCode / customPoType /
  customPoCommonName / customMac / customFunctionType /
  customEncodeType / customInstallTime / customManagementUnit /
  customContactInfo / customRecordSaveDays / customIndustrialClassification
这些是 WVP 预占位字段,SQL 尚未建列,加 exist=false 消除
BaseMapperX 反射写入时 "Unknown column" 的潜在风险,
待业务方决定是否推进 GB2022 自定义属性持久化再补 SQL 列。

StreamProxyMapper / StreamPushMapper 加接口级 Javadoc 警告:
- StreamProxy/StreamPush 继承 CommonGBChannel 带入 40+ 个 gb_* 字段,
  但 video_stream_proxy / video_stream_push 表不含这些列
  (gb 通道信息由 GbChannelService 写入 video_common_gb_channel)
- 警告开发者严禁使用 BaseMapperX 的 insert/updateById/selectByMap
  自动映射方法,写入必须走显式 SQL 方法(add/update/addAll)
- 读取 selectById/selectList 可用(SELECT 时 gb_* 字段返回 null 不报错)

未改动(零当前风险 + 改动成本高):
- SIP 协议时间字段(register_time 等 varchar):Mapper 全显式 SQL
  用 #{} 绑定 String,与 varchar 列自洽;DateUtil.getNow() 返回
  "yyyy-MM-dd HH:mm:ss" 格式字符串,时间比较查询的字符串排序
  与 datetime 排序结果一致;改造涉及 72+ 处调用链
- StreamProxy/StreamPush 继承架构:改组合式重构代价大,
  通过 Javadoc 警告防御未来误用即可

编译通过(mvn compile BUILD SUCCESS)。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
lzh
2026-04-21 13:43:23 +08:00
parent 0ca1adf2a4
commit 8ae7b1a823
3 changed files with 49 additions and 2 deletions

View File

@@ -1,5 +1,6 @@
package com.viewsh.module.video.gb28181.bean;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@@ -70,7 +71,8 @@ public class PlatformChannel extends CommonGBChannel {
@Schema(description = "国标-证书终止有效期(有证书且证书无效的设备必选)")
private Integer customEndTime;
// 2022
// 2022 扩展字段SQL 尚未建列,@TableField(exist=false) 防止 BaseMapperX 反射写入
@TableField(exist = false)
@Schema(description = "国标-摄像机安全能力等级代码")
private String customSecurityLevelCode;
@@ -106,9 +108,13 @@ public class PlatformChannel extends CommonGBChannel {
"8-校园周边、9-治安复杂区域、10-交通干线。当目录项为摄像机时可选。")
private Integer customPositionType;
// 2022
@TableField(exist = false)
@Schema(description = "国标-摄像机光电成像类型。1-可见光成像;2-热成像;3-雷达成像;4-X光成像;5-深度光场成像;9-其他。可多值,")
private String customPhotoelectricImagingTyp;
// 2022
@TableField(exist = false)
@Schema(description = "国标-摄像机采集部位类型")
private String customCapturePositionType;
@@ -130,6 +136,7 @@ public class PlatformChannel extends CommonGBChannel {
private String customResolution;
// 2022
@TableField(exist = false)
@Schema(description = "国标-摄像机支持的码流编号列表,用于实时点播时指定码流编号(可选)")
private String customStreamNumberList;
@@ -143,68 +150,84 @@ public class PlatformChannel extends CommonGBChannel {
private Integer customSvcTimeSupportMode;
// 2022
@TableField(exist = false)
@Schema(description = "国标- SSVC增强层与基本层比例能力 ")
private String customSsvcRatioSupportList;
// 2022
@TableField(exist = false)
@Schema(description = "国标-移动采集设备类型(仅移动采集设备适用,必选);1-移动机器人载摄像机;2-执法记录仪;3-移动单兵设备;" +
"4-车载视频记录设备;5-无人机载摄像机;9-其他")
private Integer customMobileDeviceType;
// 2022
@TableField(exist = false)
@Schema(description = "国标-摄像机水平视场角(可选),取值范围大于0度小于等于360度")
private Double customHorizontalFieldAngle;
// 2022
@TableField(exist = false)
@Schema(description = "国标-摄像机竖直视场角(可选),取值范围大于0度小于等于360度 ")
private Double customVerticalFieldAngle;
// 2022
@TableField(exist = false)
@Schema(description = "国标-摄像机可视距离(可选),单位:米")
private Double customMaxViewDistance;
// 2022
@TableField(exist = false)
@Schema(description = "国标-基层组织编码(必选,非基层建设时为“000000”)")
private String customGrassrootsCode;
// 2022
@TableField(exist = false)
@Schema(description = "国标-监控点位类型(当为摄像机时必选),1-一类视频监控点;2-二类视频监控点;3-三类视频监控点;9-其他点位。")
private Integer customPoType;
// 2022
@TableField(exist = false)
@Schema(description = "国标-点位俗称")
private String customPoCommonName;
// 2022
@TableField(exist = false)
@Schema(description = "国标-设备MAC地址(可选),用“XX-XX-XX-XX-XX-XX”格式表达")
private String customMac;
// 2022
@TableField(exist = false)
@Schema(description = "国标-摄像机卡口功能类型,01-人脸卡口;02-人员卡口;03-机动车卡口;04-非机动车卡口;05-物品卡口;99-其他")
private String customFunctionType;
// 2022
@TableField(exist = false)
@Schema(description = "国标-摄像机视频编码格式")
private String customEncodeType;
// 2022
@TableField(exist = false)
@Schema(description = "国标-摄像机安装使用时间")
private String customInstallTime;
// 2022
@TableField(exist = false)
@Schema(description = "国标-摄像机所属管理单位名称")
private String customManagementUnit;
// 2022
@TableField(exist = false)
@Schema(description = "国标-摄像机所属管理单位联系人的联系方式(电话号码,可多值,用英文半角“/”分割)")
private String customContactInfo;
// 2022
@TableField(exist = false)
@Schema(description = "国标-录像保存天数(可选)")
private Integer customRecordSaveDays;
// 2022
@TableField(exist = false)
@Schema(description = "国标-国民经济行业分类代码(可选)")
private String customIndustrialClassification;
}

View File

@@ -10,6 +10,18 @@ import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 拉流代理 Mapper。
*
* <p><b>注意</b>StreamProxy 继承自 {@link com.viewsh.module.video.gb28181.bean.CommonGBChannel}
* 带入 40+ 个 {@code gb_*} 字段,但 {@code video_stream_proxy} 表<b>不含这些列</b>
* (国标通道信息统一落在 {@code video_common_gb_channel} 表,由 GbChannelService 另写入)。
* 因此<b>严禁使用</b> {@link BaseMapperX} 的 {@code insert(entity)} / {@code updateById(entity)} /
* {@code selectByMap(Map)} 等自动映射方法,否则会因反射包含 {@code gb_*} 字段导致
* {@code Unknown column 'gb_device_id'} 运行时错误。写入必须走下方显式 SQL 方法
* {@link #add}、{@link #update});读取可用 BaseMapperX 的 {@code selectById} / {@code selectList}
* (只涉及 SELECTgb_* 字段对应 null 而非报错)。
*/
@Mapper
@Repository
public interface StreamProxyMapper extends BaseMapperX<StreamProxy> {

View File

@@ -13,6 +13,18 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 推流 Mapper。
*
* <p><b>注意</b>StreamPush 继承自 {@link com.viewsh.module.video.gb28181.bean.CommonGBChannel}
* 带入 40+ 个 {@code gb_*} 字段,但 {@code video_stream_push} 表<b>不含这些列</b>
* (国标通道信息统一落在 {@code video_common_gb_channel} 表,由 GbChannelService 另写入)。
* 因此<b>严禁使用</b> {@link BaseMapperX} 的 {@code insert(entity)} / {@code updateById(entity)} /
* {@code selectByMap(Map)} 等自动映射方法,否则会因反射包含 {@code gb_*} 字段导致
* {@code Unknown column 'gb_device_id'} 运行时错误。写入必须走下方显式 SQL 方法
* {@link #add}、{@link #update}、{@link #addAll});读取可用 BaseMapperX 的
* {@code selectById} / {@code selectList}(只涉及 SELECTgb_* 字段对应 null 而非报错)。
*/
@Mapper
@Repository
public interface StreamPushMapper extends BaseMapperX<StreamPush> {