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

148 lines
4.7 KiB
Markdown

# 项目申报提交"申请人ID不能为空"问题修复记录
**日期**: 2025-08-01
**操作人员**: Assistant
**修复类型**: 后端数据验证和完整性修复
## 🚨 问题描述
用户在新增项目预算申报后点击提交时,提示失败,报错信息为"申请人ID不能为空"。
### 错误现象
- **操作**: 新增项目预算申报 → 点击提交
- **结果**: 提交失败
- **错误信息**: "申请人ID不能为空"
## 🔍 问题分析
### 根本原因
1. **数据库记录不完整**: 已保存的项目申报记录中`applicant_id`字段为NULL
2. **验证约束**: `CwProjectApplicationBo`中有严格的验证注解 `@NotNull(message = "申请人ID不能为空")`
3. **历史数据问题**: 可能存在早期创建但申请人信息不完整的记录
### 技术分析
```java
// 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`方法中添加申请人信息检查和自动修复逻辑
```java
// 检查并修复申请人信息
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. **新增记录时强制设置申请人信息**:
```java
// 在insertByBo方法中已有此逻辑
if (add.getApplicantId() == null) {
add.setApplicantId(LoginHelper.getUserId());
}
```
2. **提交时二次检查**: 在提交时再次验证和修复申请人信息
## 📋 修复步骤
### 步骤1: 执行数据库修复脚本
```bash
# 在数据库中执行
mysql -u username -p database_name < script/sql/fix-applicant-id-issue.sql
```
### 步骤2: 重启后端服务
```bash
cd backend
./start-main.sh
```
### 步骤3: 测试验证
1. 登录系统
2. 新增项目申报
3. 点击提交,验证是否成功
4. 检查后端日志,确认无错误
## ✅ 验证结果
### 预期效果
- ✅ 新增项目申报提交成功
- ✅ 申请人信息自动填充
- ✅ 审批流程正常创建
- ✅ 历史数据问题得到修复
### 验证SQL
```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. **日志记录**: 记录数据修复过程,便于问题追踪和分析
这次修复不仅解决了当前问题,还建立了一套数据完整性保障机制。