Files
hzdyjs/党籍保留保存并提交功能修复报告.md
T
2025-10-14 16:41:19 +08:00

13 KiB
Raw Blame History

党籍保留保存并提交功能修复报告

📋 问题描述

现象:在出国党籍保留菜单下的"党籍保留"选项卡中,点击"新增登记"按钮,填写内容后点击"保存并提交"按钮提示"保存并提交失败"。

报告时间:2025-10-05
修复状态:🔴 待修复


🔍 问题分析

根本原因

后端代码完全缺失!

根据 backend/ruoyi-modules/ruoyi-rs/出国模块开发进程分析报告.md 的记录:

### 2.3 出国党籍保留表 (rs_party_membership_retention)

#### ❌ 完成情况 (10%)

**后端代码** (❌ 全部未创建):
| 文件类型 | 文件路径 | 状态 |
|---------|----------|------|
| Entity实体 | domain/RsPartyMembershipRetention.java | ❌ 待创建 |
| VO类 | domain/vo/RsPartyMembershipRetentionVo.java | ❌ 待创建 |
| BO类 | domain/bo/RsPartyMembershipRetentionBo.java | ❌ 待创建 |
| Query类 | domain/query/RsPartyMembershipRetentionQuery.java | ❌ 待创建 |
| Mapper接口 | mapper/RsPartyMembershipRetentionMapper.java | ❌ 待创建 |
| Mapper XML | resources/mapper/rs/RsPartyMembershipRetentionMapper.xml | ❌ 待创建 |
| Service接口 | service/IRsPartyMembershipRetentionService.java | ❌ 待创建 |
| Service实现 | service/impl/RsPartyMembershipRetentionServiceImpl.java | ❌ 待创建 |
| Controller | controller/RsPartyMembershipRetentionController.java | ❌ 待创建 |

前端调用情况

前端代码已经完整开发:

API接口定义:web/src/api/rs/party-membership-retention.ts

// 新增并提交党籍保留申请
export function addAndSubmitPartyRetention(data: PartyRetentionForm) {
  return request({
    url: '/rs/party/retention/addAndSubmit',
    method: 'post',
    data: data
  })
}

前端调用:web/src/views/rs/party-membership-retention/index.vue:882

const submitAndConfirmRetention = () => {
  retentionFormRef.value?.validate(async (valid) => {
    if (valid) {
      retentionDialog.loading = true;
      try {
        await addAndSubmitPartyRetention(retentionForm.value);
        ElMessage.success('保存并提交成功');
        
        retentionDialog.visible = false;
        resetRetentionForm();
        getRetentionList();
      } catch (error) {
        ElMessage.error('保存并提交失败');
      } finally {
        retentionDialog.loading = false;
      }
    }
  });
};

但后端完全没有对应的Controller、Service、Mapper等任何代码,导致前端调用404错误。

影响范围

  • ❌ 整个党籍保留模块完全无法使用
  • ❌ 所有API接口都不存在(列表查询、新增、修改、删除、提交等)
  • ❌ 前端页面已开发完成但无法正常工作

🛠️ 修复方案

修复步骤概览

参考"出国登记"模块的成功案例,需要创建完整的后端代码:

  1. ✅ 数据库表:rs_party_membership_retention (SQL脚本已存在)
  2. ❌ Entity实体类:RsPartyMembershipRetention.java
  3. ❌ VO类:RsPartyMembershipRetentionVo.java
  4. ❌ BO类:RsPartyMembershipRetentionBo.java
  5. ❌ Query类:RsPartyMembershipRetentionQuery.java
  6. ❌ Mapper接口:RsPartyMembershipRetentionMapper.java
  7. ❌ Mapper XML:RsPartyMembershipRetentionMapper.xml
  8. ❌ Service接口:IRsPartyMembershipRetentionService.java
  9. ❌ Service实现:RsPartyMembershipRetentionServiceImpl.java
  10. ❌ Controller:RsPartyMembershipRetentionController.java

需要实现的API接口

根据前端API文件 web/src/api/rs/party-membership-retention.ts,需要实现以下接口:

基础接口

  1. GET /rs/party/retention/list - 查询党籍保留列表(分页)
  2. GET /rs/party/retention/{retentionId} - 查询党籍保留详情
  3. POST /rs/party/retention - 新增党籍保留
  4. PUT /rs/party/retention - 修改党籍保留
  5. DELETE /rs/party/retention/{retentionIds} - 删除党籍保留

业务接口

  1. POST /rs/party/retention/addAndSubmit - 新增并提交党籍保留(核心功能)
  2. POST /rs/party/retention/submit - 提交党籍保留申请
  3. POST /rs/party/retention/cancel/{retentionId} - 撤回党籍保留申请
  4. GET /rs/party/retention/history/list - 查询历史记录列表
  5. POST /rs/party/retention/export - 导出党籍保留列表
  6. POST /rs/party/retention/history/export - 导出历史记录

📊 数据库表结构

表名:rs_party_membership_retention

根据 backend/ruoyi-modules/ruoyi-rs/出国党籍保留表创建脚本.sql:

CREATE TABLE `rs_party_membership_retention` (
    -- ========== 主键和关联字段 ==========
    `retention_id`       bigint(20)   NOT NULL AUTO_INCREMENT COMMENT '党籍保留ID(主键)',
    `application_id`     bigint(20)   NULL     DEFAULT NULL   COMMENT '关联出国申请ID',
    `registration_id`    bigint(20)   NULL     DEFAULT NULL   COMMENT '关联出国登记ID',
    
    -- ========== 基本信息字段 ==========
    `name`               varchar(50)  NOT NULL                COMMENT '我支部同志(姓名)',
    `spouse`             varchar(50)  NULL     DEFAULT NULL   COMMENT '偕配偶姓名',
    
    -- ========== 出国时间字段 ==========
    `travel_start_date`  date         NOT NULL                COMMENT '拟出国开始日期',
    `travel_end_date`    date         NOT NULL                COMMENT '拟出国结束日期',
    `stay_days`          int(11)      NULL     DEFAULT NULL   COMMENT '在外停留天数',
    
    -- ========== 出国目的和地点字段 ==========
    `destination`        varchar(100) NOT NULL                COMMENT '因私赴XX(国家或地区)',
    `purpose`            text         NULL                    COMMENT '出国目的详细说明',
    `travel_reason`      varchar(50)  NULL     DEFAULT NULL   COMMENT '出国原因(简要)',
    
    -- ========== 费用信息字段 ==========
    `self_funded`        char(1)      NOT NULL DEFAULT '1'    COMMENT '费用自理:1-是,0-否',
    
    -- ========== 党组织信息字段 ==========
    `party_branch`       varchar(100) NOT NULL                COMMENT '党支部名称',
    `relative_name`      varchar(50)  NULL     DEFAULT NULL   COMMENT '国内亲属姓名',
    `relative_phone`     varchar(20)  NULL     DEFAULT NULL   COMMENT '国内亲属联系电话',
    
    -- ========== 签字信息字段 ==========
    `applicant_signature` text        NULL                    COMMENT '申请人签字(Base64图片)',
    `application_date`   date         NULL     DEFAULT NULL   COMMENT '申请日期',
    
    -- ========== 审批流程字段 ==========
    `status`             char(1)      NOT NULL DEFAULT '0'    COMMENT '状态:0-草稿,1-待审核,2-已通过,3-已拒绝,4-已撤回',
    `submit_time`        datetime     NULL     DEFAULT NULL   COMMENT '提交时间',
    `approval_time`      datetime     NULL     DEFAULT NULL   COMMENT '审批时间',
    `approval_result`    char(1)      NULL     DEFAULT NULL   COMMENT '审批结果:1-通过,2-拒绝',
    `approval_opinion`   text         NULL                    COMMENT '审批意见',
    `approver_id`        bigint(20)   NULL     DEFAULT NULL   COMMENT '审批人ID',
    `approver_name`      varchar(50)  NULL     DEFAULT NULL   COMMENT '审批人姓名',
    
    -- ========== 系统字段 ==========
    `create_dept`        bigint(20)   NULL     DEFAULT NULL   COMMENT '创建部门',
    `create_by`          bigint(20)   NULL     DEFAULT NULL   COMMENT '创建者',
    `create_time`        datetime     NULL     DEFAULT NULL   COMMENT '创建时间',
    `update_by`          bigint(20)   NULL     DEFAULT NULL   COMMENT '更新者',
    `update_time`        datetime     NULL     DEFAULT NULL   COMMENT '更新时间',
    `remark`             varchar(500) NULL     DEFAULT NULL   COMMENT '备注',
    `deleted`            char(1)      NOT NULL DEFAULT '0'    COMMENT '删除标志:0-未删除,1-已删除',
    `tenant_id`          varchar(20)  NULL     DEFAULT '000000' COMMENT '租户编号',
    
    PRIMARY KEY (`retention_id`),
    KEY `idx_registration_id` (`registration_id`),
    KEY `idx_application_id` (`application_id`),
    KEY `idx_status` (`status`),
    KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='出国党籍保留表';

🔧 详细修复步骤

第一步:验证数据库表

-- 检查表是否存在
SHOW TABLES LIKE 'rs_party_membership_retention';

-- 如果不存在,执行创建脚本
SOURCE backend/ruoyi-modules/ruoyi-rs/出国党籍保留表创建脚本.sql;

第二步:创建后端代码

参考"出国登记"模块的代码结构,创建完整的后端代码。

核心接口实现重点

1. addAndSubmit 方法(保存并提交)

参考 RsOverseasRegistrationServiceImpl.java:218-252 的实现:

@Override
@Transactional(rollbackFor = Exception.class)
public Boolean addAndSubmit(RsPartyMembershipRetentionBo bo) {
    // ⚠️ 强制清空Bo中的基础字段,让MyBatis-Plus自动填充
    bo.setCreateBy(null);
    bo.setCreateTime(null);
    bo.setUpdateBy(null);
    bo.setUpdateTime(null);
    
    // 1. 先新增党籍保留记录
    RsPartyMembershipRetention add = MapstructUtils.convert(bo, RsPartyMembershipRetention.class);
    
    // 直接设置为待审核状态
    add.setStatus("1"); // 待审核
    add.setSubmitTime(new Date());
    
    // 计算停留天数
    if (add.getTravelStartDate() != null && add.getTravelEndDate() != null) {
        long days = (add.getTravelEndDate().getTime() - add.getTravelStartDate().getTime()) / (1000 * 60 * 60 * 24);
        add.setStayDays((int) days);
    }
    
    boolean flag = baseMapper.insert(add) > 0;
    if (!flag) {
        throw new RuntimeException("保存党籍保留失败!");
    }
    
    bo.setRetentionId(add.getRetentionId());
    log.info("新增并提交成功,retentionId: {}, createBy: {}, createTime: {}, submitTime: {}", 
        add.getRetentionId(), add.getCreateBy(), add.getCreateTime(), add.getSubmitTime());
    return true;
}

2. Controller接口

/**
 * 新增并提交党籍保留申请
 */
@SaCheckPermission("rs:party:retention:add")
@Log(title = "党籍保留", businessType = BusinessType.INSERT)
@PostMapping("/addAndSubmit")
public R<Void> addAndSubmit(@Validated(AddGroup.class) @RequestBody RsPartyMembershipRetentionBo bo) {
    return toAjax(retentionService.addAndSubmit(bo));
}

📝 参考资料

成功案例

  • 出国登记模块修复报告:出国登记保存并提交功能修复报告.md
  • 出国登记Service实现:backend/ruoyi-modules/ruoyi-rs/src/main/java/org/dromara/rs/service/impl/RsOverseasRegistrationServiceImpl.java
  • 出国登记Controller:backend/ruoyi-modules/ruoyi-rs/src/main/java/org/dromara/rs/controller/RsOverseasRegistrationController.java

设计文档

  • 数据库脚本:backend/ruoyi-modules/ruoyi-rs/出国党籍保留表创建脚本.sql
  • 流程设计:backend/ruoyi-modules/ruoyi-rs/出国流程重新设计方案.md
  • 开发进度:backend/ruoyi-modules/ruoyi-rs/出国模块开发进程分析报告.md

前端代码

  • API接口:web/src/api/rs/party-membership-retention.ts
  • 页面组件:web/src/views/rs/party-membership-retention/index.vue

⚠️ 重要提示

  1. MyBatis-Plus自动填充问题:

    • 必须在 addAndSubmit 方法中清空 createBy、createTime、updateBy、updateTime 字段
    • 否则会导致这些字段为null,无法正确记录操作人和时间
  2. 状态管理:

    • 草稿状态:0
    • 待审核状态:1(提交后的状态)
    • 已通过:2
    • 已拒绝:3
    • 已撤回:4
  3. 权限配置:

    • 需要在系统菜单中配置对应的权限标识
    • 权限前缀:rs:party:retention:

📅 修复计划

步骤 任务 预计时间 状态
1 验证数据库表是否存在 5分钟 ⏳ 待开始
2 创建Entity实体类 15分钟 ⏳ 待开始
3 创建VO、BO、Query类 20分钟 ⏳ 待开始
4 创建Mapper接口和XML 15分钟 ⏳ 待开始
5 创建Service接口和实现 30分钟 ⏳ 待开始
6 创建Controller控制器 20分钟 ⏳ 待开始
7 测试所有接口 30分钟 ⏳ 待开始
8 前后端联调测试 20分钟 ⏳ 待开始

总计:约2.5小时


📌 总结

这是一个前端已完成但后端完全缺失的典型案例。需要参考"出国登记"模块的成功经验,完整创建后端代码才能解决问题。

关键点:

  • ✅ 前端代码完整且正确
  • ❌ 后端代码完全缺失
  • ✅ 数据库设计已完成
  • ✅ 有成功案例可参考(出国登记模块)

下一步行动:按照修复计划逐步创建后端代码。