✨ 认证记录新增修订版快照列

审核员修订提交内容后需要留痕:snapshot_json 记「司机提交了什么」且永不修改,
修订版另存 audited_snapshot_json,「通过时认定了什么内容」才有据可查。

- 新增列 audited_snapshot_json longtext NULL,位置在 snapshot_json 之后,不进任何索引
- 幂等:查 information_schema 判列,列已存在即跳过;表不存在时故意报 1146 防假绿
- 同步基线建表脚本,避免「迁移加列、基线没同步」
This commit is contained in:
2026-10-28 01:24:04 +08:00
parent 1b19d4e60c
commit a52759678a
2 changed files with 69 additions and 0 deletions
@@ -14,6 +14,7 @@ CREATE TABLE IF NOT EXISTS `blade_transport_cert_record` (
`biz_key` varchar(100) DEFAULT NULL COMMENT '展示键:司机姓名/车牌号',
`status` int(11) NOT NULL COMMENT '审核状态:0审核中 1已通过 2已驳回 3已作废',
`snapshot_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '该次提交的全量认证内容JSON,一经创建不可修改',
`audited_snapshot_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '审核通过时确定的修订版内容;NULL=未修订',
`reject_reason` varchar(200) DEFAULT NULL COMMENT '驳回原因,仅状态为已驳回时有值',
`submit_time` datetime DEFAULT NULL COMMENT '提交时间',
`submit_user` bigint(20) DEFAULT NULL COMMENT '提交人',
@@ -0,0 +1,68 @@
-- ----------------------------
-- 认证记录:新增修订版快照列 audited_snapshot_json(2026-10-28)
-- ----------------------------
-- 背景:审核员可以在审核页面对提交内容做修订(全字段可改,身份字段除外)。
-- 修订结果必须留痕:snapshot_json 是「司机当时提交了什么」,一经创建逐字节不可改;
-- 修订版另存一列,「审核通过时到底认定了什么内容」才查得清。
--
-- 语义:
-- NULL —— 未修订,生效内容即 snapshot_json;
-- 非 NULL —— 审核通过时认定的修订版全量 JSON,生效内容以它为准。
-- 只在「通过」时同事务写入;驳回不写(驳回不产生生效内容,留修订版只会让人误读)。
-- 修订人/修订时间复用 audit_user / audit_time,不新增列。
--
-- 只做结构变更,不回填数据:存量记录一律保持 NULL(历史审核确实没有修订动作)。
--
-- 不加索引:本列只在审核详情与生效内容读取时按主键取用,从不作为查询条件;
-- longtext 建索引会超出索引键长度并拖慢写入。
--
-- 幂等:先查 information_schema 判列,列已存在(或类型/可空性已符合)即跳过;
-- 只用 PREPARE 动态语句、不用存储过程,因此不需要 DELIMITER——按分号逐句切分的
-- 客户端(含数据库驱动)也能直接执行。重复执行零变更。
SET @cert_record_schema = DATABASE();
-- ----------------------------
-- 0. 表存在性守卫
-- ----------------------------
-- 表不存在时故意执行一条只读查询,让客户端报 1146「Table ... doesn't exist」;
-- 否则下面因查不到列而静默跳过,脚本会假绿。
SET @cert_record_guard_sql = (
SELECT IF(COUNT(*) > 0,
'SELECT 1',
'SELECT 1 FROM `blade_transport_cert_record` LIMIT 0')
FROM information_schema.tables
WHERE table_schema = @cert_record_schema
AND table_name = 'blade_transport_cert_record'
);
PREPARE cert_record_guard_stmt FROM @cert_record_guard_sql;
EXECUTE cert_record_guard_stmt;
DEALLOCATE PREPARE cert_record_guard_stmt;
-- ----------------------------
-- 1. 加列 audited_snapshot_json
-- ----------------------------
-- 位置紧接 snapshot_json:两列是同一份内容的前后两态,放一起便于对照。
-- 条件分三种:列不存在则 ADD;列存在但类型不是 longtext 或可空性不是 YES 则 MODIFY
-- (防止历史上的手工变更把列建成 varchar 而截断 JSON);其余情况跳过。
SET @cert_record_audited_snapshot_sql = (
SELECT IF(COUNT(*) = 0,
'ALTER TABLE `blade_transport_cert_record` ADD COLUMN `audited_snapshot_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT ''审核通过时确定的修订版内容;NULL=未修订'' AFTER `snapshot_json`',
IF(SUM(data_type <> 'longtext' OR is_nullable <> 'YES') > 0,
'ALTER TABLE `blade_transport_cert_record` MODIFY COLUMN `audited_snapshot_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT ''审核通过时确定的修订版内容;NULL=未修订''',
'SELECT 1'))
FROM information_schema.columns
WHERE table_schema = @cert_record_schema
AND table_name = 'blade_transport_cert_record'
AND column_name = 'audited_snapshot_json'
);
PREPARE cert_record_audited_snapshot_stmt FROM @cert_record_audited_snapshot_sql;
EXECUTE cert_record_audited_snapshot_stmt;
DEALLOCATE PREPARE cert_record_audited_snapshot_stmt;
-- ----------------------------
-- 2. 回滚
-- ----------------------------
-- 只新增了一列、未进任何索引,回滚即删该列;
-- snapshot_json 的 updateStrategy=NEVER 与生成列 pending_biz_id、唯一键 uk_cert_record_pending 均不受影响:
-- ALTER TABLE `blade_transport_cert_record` DROP COLUMN `audited_snapshot_json`;