Files
hzdyjs/docs/变更管理/code-adjust-record-2025-01-26-cw-db-fix.md
T
2025-07-30 23:24:43 +08:00

6.0 KiB
Raw Blame History

财务项目申报数据库字段修复记录

时间: 2025-01-26 21:45:00
操作人: AI Assistant
变更类型: Bug修复 - 数据库字段映射错误

问题描述

🔴 主要错误

用户报告两个问题:

  1. 项目预算提交审批提示申报编号不能为空
  2. 数据库错误: Field 'applicant_name' doesn't have a default value

🔍 根本原因分析

1. 数据库字段缺失

ERROR: Field 'applicant_name' doesn't have a default value
  • 数据库表 cw_project_application 中的必填字段未在INSERT时提供值
  • 缺失字段:applicant_name、department_id、department_name (均为 NOT NULL)

2. 后端字段映射问题

// 只设置了 applicantId,缺少其他必填字段
if (add.getApplicantId() == null) {
    add.setApplicantId(LoginHelper.getUserId());
}

3. 前端验证规则错误

@NotBlank(message = "申报编号不能为空", groups = { AddGroup.class, EditGroup.class })
  • 申报编号应该系统自动生成,不应在新增时验证

修复内容

📝 1. 修复后端字段映射

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

// 修复前(不完整)
if (add.getApplicantId() == null) {
    add.setApplicantId(LoginHelper.getUserId());
}

// 修复后(完整)
if (add.getApplicantId() == null) {
    add.setApplicantId(LoginHelper.getUserId());
}
if (StringUtils.isBlank(add.getApplicantName())) {
    add.setApplicantName(LoginHelper.getUsername());
}
if (add.getDepartmentId() == null) {
    add.setDepartmentId(LoginHelper.getDeptId());
}
if (StringUtils.isBlank(add.getDepartmentName())) {
    add.setDepartmentName(LoginHelper.getDeptName());
}

📝 2. 修复验证注解

文件: backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/bo/CwProjectApplicationBo.java

// 修复前(错误验证)
@NotBlank(message = "申报编号不能为空", groups = { AddGroup.class, EditGroup.class })

// 修复后(只在编辑时验证)
@NotBlank(message = "申报编号不能为空", groups = { EditGroup.class })

📝 3. 修复前端提交逻辑

文件: web/src/views/cw/application/index.vue

// 修复前(使用错误的API)
addProjectApplication(form.value).then(response => {
    submitApplication(response.data).then(() => {
        // ...
    });
});

// 修复后(使用正确的流程)
saveDraft(form.value).then(response => {
    // 保存草稿后,form.value.id 会被设置
    if (form.value.id) {
        submitApplication(form.value.id).then(() => {
            // ...
        });
    }
});

数据库表结构确认

📊 必填字段列表

-- cw_project_application 表中的 NOT NULL 字段
`application_no` varchar(50) NOT NULL,        -- 申报编号(系统生成)
`project_name` varchar(200) NOT NULL,         -- 项目名称(用户输入)
`principal` varchar(50) NOT NULL,             -- 项目负责人(用户输入)
`applicant_id` bigint(20) NOT NULL,           -- 申请人ID(系统设置)
`applicant_name` varchar(50) NOT NULL,        -- 申请人姓名(系统设置)
`department_id` bigint(20) NOT NULL,          -- 所属部门ID(系统设置)
`department_name` varchar(100) NOT NULL,      -- 所属部门名称(系统设置)
`year` int(11) NOT NULL                       -- 预算年度(用户输入)

📊 系统自动生成字段

  • applicant_id ← LoginHelper.getUserId()
  • applicant_name ← LoginHelper.getUsername()
  • department_id ← LoginHelper.getDeptId()
  • department_name ← LoginHelper.getDeptName()
  • application_no ← generateApplicationNo() (格式:YS+日期+随机数)

技术要点

🎯 RuoYi框架规范

  1. LoginHelper工具类: 获取当前登录用户的相关信息
  2. 验证分组: AddGroup.class 新增验证,EditGroup.class 编辑验证
  3. 自动填充: 系统字段应在Service层自动设置,不依赖前端传值

🎯 数据一致性保证

  1. 必填字段: 确保所有 NOT NULL 字段都有值
  2. 业务逻辑: 申请人信息自动从当前登录用户获取
  3. 唯一性: 申报编号系统生成,确保唯一性

验证步骤

✅ 后端验证

  1. 新增申报: POST /cw/application 应该成功,不报字段缺失错误
  2. 保存草稿: POST /cw/application/saveDraft 应该成功
  3. 数据库检查: 确认 applicant_name、department_id、department_name 有值

✅ 前端验证

  1. 新增表单: 点击"新增"按钮,弹窗正常打开
  2. 保存草稿: 填写必填项,点击"保存草稿"成功
  3. 提交审批: 点击"提交审批"成功,不报申报编号为空

✅ 完整流程验证

  1. 填写表单 → 保存草稿 → 提交审批 → 状态更新
  2. 编辑功能 → 修改内容 → 保存 → 数据更新

影响范围

📁 涉及文件

  • CwProjectApplicationServiceImpl.java - Service实现类(字段自动设置)
  • CwProjectApplicationBo.java - BO验证注解(申报编号验证)
  • web/src/views/cw/application/index.vue - 前端提交逻辑

🔄 功能影响

  • ✅ 修复: 新增申报功能正常工作
  • ✅ 修复: 提交审批功能正常工作
  • ✅ 改进: 用户体验优化,无需手动输入系统字段

注意事项

⚠️ 数据安全

  • 申请人信息完全基于当前登录用户,确保数据安全
  • 部门信息自动获取,避免越权申报

⚠️ 后续维护

  • 如需修改申报编号生成规则,修改 generateApplicationNo() 方法
  • 如需增加必填字段验证,注意区分新增和编辑场景

结果确认

🎯 预期效果

  • 新增申报时不再报"申报编号不能为空"错误
  • 保存时不再报数据库字段缺失错误
  • 申请人和部门信息自动填充,用户体验改善

备注: 本次修复解决了财务申报模块的核心数据库映射问题,确保所有必填字段都能正确设置,提升了系统稳定性和用户体验。