Files
hzdyjs/出国登记保存失败问题修复报告-2025-10-05.md
T
2025-10-14 16:41:19 +08:00

9.4 KiB
Raw Blame History

出国登记保存失败问题修复报告

修复日期: 2025-10-05
问题类型: 数据库字段长度设计不合理
影响功能: 人事管理 > 出国登记 > 新增登记


🔴 问题现象

错误信息

Error updating database.
Cause: com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: 
Data truncation: Data too long for column 'political_status' at row 1

SQL: INSERT INTO rs_overseas_registration 
     (name, gender, birth_date, political_status, id_number, 
      registered_address, department, position, administrative_level, 
      personnel_category, status, registration_time, remarks, 
      create_dept, tenant_id) 
     VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, '000000')

复现路径

  1. 登录系统
  2. 进入"人事管理" → "出国登记"菜单
  3. 点击"出国登记"选项卡
  4. 点击"新增登记"按钮
  5. 填写表单信息,选择政治面貌(如"中共党员")
  6. 点击"保存并提交"
  7. 报错:Data too long for column 'political_status'

🔍 问题分析

1. 数据库字段定义问题

当前字段定义(有问题):

-- 从创建脚本看到的定义
`political_status` char(2) NOT NULL COMMENT '政治面貌:参考rs_political_status字典'

问题所在:

  • 字段类型:char(2) 只能存储2个字节
  • 实际需求:前端传递完整中文文本(如"中共党员")
  • UTF-8编码:4个中文字符 = 12个字节
  • 结论:char(2) 完全无法存储任何一个政治面貌选项!

2. 前端传值方式分析

前端代码(web/src/views/rs/overseas-registration/index.vue:323-338):

<el-form-item label="政治面貌" prop="politicalStatus">
  <el-select v-model="registrationForm.politicalStatus" placeholder="请选择政治面貌">
    <el-option label="中共党员" value="中共党员" />
    <el-option label="中共预备党员" value="中共预备党员" />
    <el-option label="共青团员" value="共青团员" />
    <el-option label="民革党员" value="民革党员" />
    <!-- ... 其他选项 ... -->
  </el-select>
</el-form-item>

分析:

  • 前端直接使用完整的中文标签文本作为value
  • 不是使用字典编码(1, 2, 3...)
  • 这是正确的做法,因为便于阅读和维护
  • 但数据库字段必须能够存储完整文本

3. 政治面貌选项长度统计

选项文本 字符数 字节数(UTF-8) char(2)能否存储 varchar(20)能否存储
中共党员 4 12 ❌ ✅
中共预备党员 6 18 ❌ ✅
共青团员 4 12 ❌ ✅
民革党员 4 12 ❌ ✅
民盟盟员 4 12 ❌ ✅
民建会员 4 12 ❌ ✅
民进会员 4 12 ❌ ✅
农工党党员 5 15 ❌ ✅
致公党党员 5 15 ❌ ✅
九三学社社员 6 18 ❌ ✅
台盟盟员 4 12 ❌ ✅
无党派人士 5 15 ❌ ✅
群众 2 6 ❌ ✅

结论:

  • char(2): 所有选项都无法存储 ❌
  • varchar(20): 所有当前选项都可以存储 ✅
  • varchar(50): 最安全的选择,预留扩展空间 ✅✅✅

4. 根本原因总结

  1. 字段长度设计错误:使用了char(2),远远不足以存储中文文本
  2. 缺少数据验证:建表时没有与实际前端传值进行验证
  3. 文档不一致:不同文档中字段定义不一致(char(2)、varchar(20)、varchar(50))

🔧 修复方案

修复步骤

1. 执行SQL修复脚本

脚本位置: docs/设计文档/database/【立即执行】修复political_status字段长度.sql

核心SQL:

-- 修改出国登记表
ALTER TABLE `rs_overseas_registration` 
MODIFY COLUMN `political_status` varchar(50) NOT NULL COMMENT '政治面貌';

-- 修改出国申请表(保持一致)
ALTER TABLE `rs_overseas_application` 
MODIFY COLUMN `political_status` varchar(50) NOT NULL COMMENT '政治面貌';

2. 执行方式

方式一:通过Navicat/DBeaver等工具

  1. 连接到数据库 hzdyjs_xg
  2. 打开SQL脚本文件
  3. 执行整个脚本
  4. 查看验证结果

方式二:通过命令行

mysql -uroot -p hzdyjs_xg < "docs/设计文档/database/【立即执行】修复political_status字段长度.sql"

3. 验证修复结果

验证SQL:

SELECT 
    TABLE_NAME,
    COLUMN_NAME,
    DATA_TYPE,
    CHARACTER_MAXIMUM_LENGTH,
    COLUMN_COMMENT
FROM 
    information_schema.COLUMNS
WHERE 
    TABLE_SCHEMA = 'hzdyjs_xg'
    AND TABLE_NAME IN ('rs_overseas_registration', 'rs_overseas_application')
    AND COLUMN_NAME = 'political_status';

预期结果:

TABLE_NAME                   | COLUMN_NAME      | DATA_TYPE | CHARACTER_MAXIMUM_LENGTH | COLUMN_COMMENT
----------------------------|------------------|-----------|--------------------------|----------------
rs_overseas_registration    | political_status | varchar   | 50                       | 政治面貌
rs_overseas_application     | political_status | varchar   | 50                       | 政治面貌

4. 功能测试

修复完成后,请测试以下场景:

测试场景 操作步骤 预期结果
新增登记-短文本 选择"群众" → 保存 ✅ 保存成功
新增登记-中等文本 选择"中共党员" → 保存 ✅ 保存成功
新增登记-较长文本 选择"九三学社社员" → 保存 ✅ 保存成功
编辑登记 修改政治面貌 → 保存 ✅ 更新成功
保存并提交 填写完整信息 → 保存并提交 ✅ 提交成功

📊 影响范围

受影响的表

  1. ✅ rs_overseas_registration (出国登记表) - 已修复
  2. ✅ rs_overseas_application (出国申请表) - 已修复

受影响的功能

  1. 人事管理 > 出国登记 > 新增登记
  2. 人事管理 > 出国登记 > 编辑登记
  3. 人事管理 > 出国申请 > 新增申请
  4. 人事管理 > 出国申请 > 编辑申请

代码检查(无需修改)

后端实体类(正确):

// RsOverseasRegistration.java
@ExcelProperty(value = "政治面貌")
private String politicalStatus;

前端表单(正确):

<el-select v-model="registrationForm.politicalStatus">
  <el-option label="中共党员" value="中共党员" />
</el-select>

📝 经验总结

设计教训

  1. 中文字段长度计算规则

    varchar长度 = 最大字符数 × 3(UTF-8) + 预留空间(20-30%)
    
  2. 常见错误

    • ❌ 使用char(2)存储中文文本
    • ❌ 只考虑字符数,不考虑字节数
    • ❌ 没有与实际数据进行验证
    • ✅ 使用varchar(50)存储4-6个中文字符的内容
  3. 推荐长度标准

    内容类型 字符数 推荐varchar长度
    政治面貌 2-6 50
    姓名 2-10 50
    部门名称 10-30 100
    地址 20-100 300

预防措施

1. 设计阶段

  • 建表前必须确认字段长度满足所有可能值
  • 中文字段统一按字符数×3计算
  • 预留20-30%扩展空间

2. 开发阶段

  • 前端传值与数据库字段长度必须匹配
  • 单元测试包含边界值测试
  • 集成测试覆盖所有下拉选项

3. 文档规范

  • 数据库设计文档标注字段长度计算依据
  • 字典数据变更时同步检查字段长度

✅ 修复清单

立即执行

  • 创建修复SQL脚本
  • 编写修复报告
  • 执行SQL修复脚本(请数据库管理员执行)
  • 验证字段长度已更新为varchar(50)
  • 测试"新增出国登记"功能
  • 测试所有政治面貌选项

后续优化

  • 全局检查其他表的political_status字段
  • 检查其他中文字段的长度是否合理
  • 更新数据库设计规范文档
  • 在代码生成模板中增加字段长度验证

🎯 关键提示

⚠️ 执行前注意事项

  1. 备份: 脚本已自动创建备份表,但建议额外备份
  2. 时机: 建议在业务低峰期执行
  3. 权限: 需要ALTER TABLE权限
  4. 时长: 预计1-2秒(取决于表数据量)
  5. 安全: ALTER TABLE不会丢失数据

✅ 执行后验证

  1. 查看字段长度是否已更新为50
  2. 测试新增登记功能(选择所有政治面貌选项)
  3. 测试编辑登记功能
  4. 检查现有数据是否正常

🔗 相关文档

修复文档

  • 本次修复SQL: docs/设计文档/database/【立即执行】修复political_status字段长度.sql
  • 历史修复记录: docs/变更管理/出国登记political_status字段长度不足修复-2025-10-04.md

设计文档

  • 数据库设计: docs/设计文档/database/出国管理三表架构设计方案.md
  • 开发规范: .cursor/cursorrules-backend.md

变更记录

  • 字段重构记录: docs/变更管理/出国登记字段重构记录-2025-09-29.md
  • 数据库准备记录: docs/变更管理/出国登记表数据库准备记录-2025-09-30.md

📞 问题追踪

问题ID: RS-POLITICAL-STATUS-LENGTH-001
创建时间: 2025-10-05
修复状态: 待执行SQL脚本
责任人: 数据库管理员
预计修复时间: 2分钟


修复完成后,请立即测试"新增出国登记"功能,特别是选择"中共党员"、"九三学社社员"等选项!