Files
hzdyjs/docs/变更管理/code-adjust-record-2025-08-01-applicant-id-fix.md
T
2025-08-01 08:35:47 +08:00

4.7 KiB

项目申报提交"申请人ID不能为空"问题修复记录

日期: 2025-08-01
操作人员: Assistant
修复类型: 后端数据验证和完整性修复

🚨 问题描述

用户在新增项目预算申报后点击提交时,提示失败,报错信息为"申请人ID不能为空"。

错误现象

  • 操作: 新增项目预算申报 → 点击提交
  • 结果: 提交失败
  • 错误信息: "申请人ID不能为空"

🔍 问题分析

根本原因

  1. 数据库记录不完整: 已保存的项目申报记录中applicant_id字段为NULL
  2. 验证约束: CwProjectApplicationBo中有严格的验证注解 @NotNull(message = "申请人ID不能为空")
  3. 历史数据问题: 可能存在早期创建但申请人信息不完整的记录

技术分析

// CwProjectApplicationBo.java 第210行
@NotNull(message = "申请人ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long applicantId;

🔧 修复方案

1. 后端代码修复

修改文件: backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwProjectApplicationServiceImpl.java

修复内容: 在submitApplication方法中添加申请人信息检查和自动修复逻辑

// 检查并修复申请人信息
if (application.getApplicantId() == null) {
    log.warn("项目申报记录申请人ID为空,正在修复:applicationId={}", id);
    application.setApplicantId(LoginHelper.getUserId());
    application.setApplicantName(LoginHelper.getUsername());
    
    // 如果当前用户信息也获取不到,抛出明确错误
    if (application.getApplicantId() == null) {
        throw new RuntimeException("无法获取当前登录用户信息,请重新登录后重试");
    }
}

// 检查部门信息
if (application.getDepartmentId() == null) {
    log.warn("项目申报记录部门ID为空,正在修复:applicationId={}", id);
    application.setDepartmentId(LoginHelper.getDeptId());
    application.setDepartmentName(LoginHelper.getDeptName());
}

2. 数据库修复脚本

脚本文件: script/sql/fix-applicant-id-issue.sql

修复策略:

  1. 检查问题记录: 查找applicant_id为NULL或0的记录
  2. 方案1: 将申请人ID设置为创建者ID(推荐)
  3. 方案2: 如果创建者也为空,设置为系统管理员
  4. 修复部门信息: 根据申请人ID补全部门信息
  5. 验证结果: 检查修复效果

3. 预防措施

  1. 新增记录时强制设置申请人信息:

    // 在insertByBo方法中已有此逻辑
    if (add.getApplicantId() == null) {
        add.setApplicantId(LoginHelper.getUserId());
    }
    
  2. 提交时二次检查: 在提交时再次验证和修复申请人信息

📋 修复步骤

步骤1: 执行数据库修复脚本

# 在数据库中执行
mysql -u username -p database_name < script/sql/fix-applicant-id-issue.sql

步骤2: 重启后端服务

cd backend
./start-main.sh

步骤3: 测试验证

  1. 登录系统
  2. 新增项目申报
  3. 点击提交,验证是否成功
  4. 检查后端日志,确认无错误

✅ 验证结果

预期效果

  • ✅ 新增项目申报提交成功
  • ✅ 申请人信息自动填充
  • ✅ 审批流程正常创建
  • ✅ 历史数据问题得到修复

验证SQL

-- 检查是否还有申请人ID为空的记录
SELECT COUNT(*) as problem_count 
FROM cw_project_application 
WHERE applicant_id IS NULL OR applicant_id = 0;

🔄 相关影响

正面影响

  • 解决了项目申报提交失败的问题
  • 修复了历史数据的完整性问题
  • 提高了系统的稳定性和用户体验
  • 增加了数据验证的容错性

注意事项

  • 修复过程中会自动设置申请人信息
  • 历史记录的申请人可能会变更为创建者
  • 需要确保当前用户登录状态有效

📝 技术总结

问题根源

  1. 数据完整性约束: Bean Validation严格验证申请人ID
  2. 历史数据缺失: 早期记录可能缺少申请人信息
  3. 用户会话问题: 登录状态异常导致用户信息获取失败

解决策略

  1. 防御性编程: 在关键节点添加数据完整性检查
  2. 自动修复机制: 尝试从当前登录用户或创建者获取申请人信息
  3. 明确错误提示: 当无法修复时给出清晰的用户指导

最佳实践

  1. 数据验证前置: 在业务操作前进行必要的数据完整性检查
  2. 容错处理: 对于可以自动修复的数据问题,提供自动修复机制
  3. 日志记录: 记录数据修复过程,便于问题追踪和分析

这次修复不仅解决了当前问题,还建立了一套数据完整性保障机制。