13 KiB
13 KiB
党籍保留保存并提交功能修复报告
📋 问题描述
现象:在出国党籍保留菜单下的"党籍保留"选项卡中,点击"新增登记"按钮,填写内容后点击"保存并提交"按钮提示"保存并提交失败"。
报告时间: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接口都不存在(列表查询、新增、修改、删除、提交等)
- ❌ 前端页面已开发完成但无法正常工作
🛠️ 修复方案
修复步骤概览
参考"出国登记"模块的成功案例,需要创建完整的后端代码:
- ✅ 数据库表:
rs_party_membership_retention(SQL脚本已存在) - ❌ Entity实体类:
RsPartyMembershipRetention.java - ❌ VO类:
RsPartyMembershipRetentionVo.java - ❌ BO类:
RsPartyMembershipRetentionBo.java - ❌ Query类:
RsPartyMembershipRetentionQuery.java - ❌ Mapper接口:
RsPartyMembershipRetentionMapper.java - ❌ Mapper XML:
RsPartyMembershipRetentionMapper.xml - ❌ Service接口:
IRsPartyMembershipRetentionService.java - ❌ Service实现:
RsPartyMembershipRetentionServiceImpl.java - ❌ Controller:
RsPartyMembershipRetentionController.java
需要实现的API接口
根据前端API文件 web/src/api/rs/party-membership-retention.ts,需要实现以下接口:
基础接口
GET /rs/party/retention/list- 查询党籍保留列表(分页)GET /rs/party/retention/{retentionId}- 查询党籍保留详情POST /rs/party/retention- 新增党籍保留PUT /rs/party/retention- 修改党籍保留DELETE /rs/party/retention/{retentionIds}- 删除党籍保留
业务接口
POST /rs/party/retention/addAndSubmit- 新增并提交党籍保留(核心功能)POST /rs/party/retention/submit- 提交党籍保留申请POST /rs/party/retention/cancel/{retentionId}- 撤回党籍保留申请GET /rs/party/retention/history/list- 查询历史记录列表POST /rs/party/retention/export- 导出党籍保留列表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
⚠️ 重要提示
-
MyBatis-Plus自动填充问题:
- 必须在
addAndSubmit方法中清空createBy、createTime、updateBy、updateTime字段 - 否则会导致这些字段为null,无法正确记录操作人和时间
- 必须在
-
状态管理:
- 草稿状态:
0 - 待审核状态:
1(提交后的状态) - 已通过:
2 - 已拒绝:
3 - 已撤回:
4
- 草稿状态:
-
权限配置:
- 需要在系统菜单中配置对应的权限标识
- 权限前缀:
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小时
📌 总结
这是一个前端已完成但后端完全缺失的典型案例。需要参考"出国登记"模块的成功经验,完整创建后端代码才能解决问题。
关键点:
- ✅ 前端代码完整且正确
- ❌ 后端代码完全缺失
- ✅ 数据库设计已完成
- ✅ 有成功案例可参考(出国登记模块)
下一步行动:按照修复计划逐步创建后端代码。