From e06d8fca2cc425eb7dac10bb0b3941dca0b70984 Mon Sep 17 00:00:00 2001 From: wuzhen <52326163@qq.com> Date: Thu, 7 Aug 2025 18:37:28 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E9=87=8D=E8=A6=81=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=EF=BC=8C=E5=8F=AF=E8=83=BD=E4=BC=9A=E5=BD=B1=E5=93=8D=E5=88=B0?= =?UTF-8?q?=E5=85=B6=E4=BB=96=E6=A8=A1=E5=9D=97=E5=8F=8A=E5=B7=A5=E4=BD=9C?= =?UTF-8?q?=E6=B5=81=E3=80=82*****?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/ruoyi-admin/pom.xml | 7 + backend/ruoyi-modules/pom.xml | 1 + .../impl/CwApprovalRecordServiceImpl.java | 99 +- .../impl/CwProjectApplicationServiceImpl.java | 20 +- .../code-adjust-record-2025-01-18-wuzhen.md | 443 ++++++- ...ode-adjust-record-2025-01-27-statistics.md | 110 +- .../code-adjust-record-2025-01-27-wuzhen.md | 609 +++++++++- stgl-api-test.js | 550 --------- web/src/api/cw/approvalRecord.ts | 4 +- web/src/api/cw/financeApproval.ts | 10 +- web/src/api/cw/leaderApproval.ts | 4 +- web/src/api/cw/projectApplication.ts | 4 +- web/src/api/cw/statistics.ts | 16 +- web/src/api/system/SysRegion/types.ts | 14 +- web/src/api/system/bucketPassword.ts | 50 +- web/src/api/system/file.ts | 56 +- .../studentLeave/studentLeave/types.ts | 14 +- web/src/api/xg-xx-bak/classInfo.ts | 128 +- web/src/api/xg-xx-bak/statistics.ts | 252 ++-- web/src/api/xg-xx-bak/student.ts | 328 ++--- web/src/api/xg-xx-bak/types.ts | 1060 ++++++++--------- web/src/api/xg/classTeacherCounselorRel.ts | 2 +- web/src/api/xg/index.ts | 2 +- web/src/api/xg/xgss/dormBed/types.ts | 3 - web/src/api/xg/xgss/dormRoom/types.ts | 14 +- .../xgss/glysqgx/dormManagerSource/types.ts | 14 +- .../glysslqxgx/dormManagerBuilding/types.ts | 14 +- .../api/xg/xgss/ssglyxx/dormManager/types.ts | 14 +- .../api/xg/xgss/sslxx/dormBuilding/types.ts | 6 +- web/src/api/xg/xgss/ssqxx/dormArea/types.ts | 14 +- web/src/api/xg/xgss/xqxx/dormCampus/types.ts | 14 +- web/src/api/xg/xgss/xsssfjgl/index.ts | 4 +- .../xsjcxx/XgStuColBatch/stuColBatch/types.ts | 14 +- .../api/xg/xsjcxx/classMsg/classMsg/types.ts | 14 +- .../stuColBatchClass/types.ts | 14 +- web/src/api/xg/xsjcxx/stuMsgAudit/types.ts | 14 +- web/src/api/xg/xsjcxx/stuMsgSupply/types.ts | 14 +- web/src/api/xg/xsjcxx/studentMsg/index.ts | 28 +- .../xg/xsjcxx/studentMsg/studentMsg/types.ts | 26 +- .../studentMsgBatch/studentMsgBatch/types.ts | 26 +- .../xgClassPosDict/xgClassPosDict/types.ts | 14 +- .../xgClassPosMsg/xgClassPosMsg/types.ts | 14 +- .../xgLeaveTypeConfig/types.ts | 14 +- .../xgStudentManager/studentManager/types.ts | 14 +- .../studentManagerSource/index.ts | 6 +- .../studentManagerSource/types.ts | 14 +- web/src/api/xljk/consultation/appointment.ts | 1 - web/src/api/xljk/consultation/index.ts | 10 +- web/src/api/xljk/consultation/noshow.ts | 6 +- web/src/api/xljk/consultation/types.ts | 8 +- web/src/api/xljk/evaluation/index.ts | 10 +- web/src/api/xljk/evaluation/types.ts | 2 +- web/src/api/zsjy/README.md | 1 + web/src/api/zsjy/enrollment/index.ts | 4 +- web/src/api/zsjy/enrollmentProcess.ts | 254 ++-- web/src/api/zsjy/enrollmentStatistics.ts | 28 +- web/src/api/zsjy/graduateInfo.ts | 7 +- web/src/api/zsjy/index.ts | 10 +- web/src/api/zsjy/jobPosition.ts | 22 +- web/src/api/zsjy/recruitmentPoster.ts | 22 +- web/src/api/zsjy/statistics.ts | 22 +- web/src/assets/styles/index.scss | 3 +- web/src/components/ImageUpload/index-bak.vue | 2 - web/src/components/PosterPreview/index.vue | 189 ++- web/src/plugins/download.ts | 6 +- web/src/plugins/svgicon.ts | 10 +- web/src/router/index.ts | 2 +- web/src/types/global.d.ts | 4 +- web/src/utils/request.ts | 6 +- .../components/PerformanceIndicators.vue | 377 ++---- web/src/views/cw/application/detail.vue | 210 ++-- web/src/views/cw/application/form.vue | 667 +++++------ web/src/views/cw/application/index.vue | 472 ++++---- web/src/views/cw/application/summary.vue | 27 +- web/src/views/cw/approvalRecord/index.vue | 143 +-- web/src/views/cw/approverConfig/detail.vue | 82 +- web/src/views/cw/approverConfig/index.vue | 298 ++--- web/src/views/cw/statistics/index.vue | 5 +- 78 files changed, 3545 insertions(+), 3471 deletions(-) delete mode 100644 stgl-api-test.js diff --git a/backend/ruoyi-admin/pom.xml b/backend/ruoyi-admin/pom.xml index f812e856..4e1232c7 100644 --- a/backend/ruoyi-admin/pom.xml +++ b/backend/ruoyi-admin/pom.xml @@ -135,6 +135,13 @@ ${revision} + + + org.dromara + ruoyi-jcbt + ${revision} + + diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwApprovalRecordServiceImpl.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwApprovalRecordServiceImpl.java index de9c9704..f522adfd 100644 --- a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwApprovalRecordServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwApprovalRecordServiceImpl.java @@ -36,6 +36,8 @@ import org.dromara.system.domain.bo.SysDeptBo; import java.util.*; import java.util.stream.Collectors; import org.dromara.common.core.utils.SpringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; /** * 审批记录Service业务层处理 @@ -54,6 +56,9 @@ public class CwApprovalRecordServiceImpl implements ICwApprovalRecordService { private final ISysUserService sysUserService; private final ISysDeptService sysDeptService; + @Autowired + private JdbcTemplate jdbcTemplate; + /** * 根据主键查询审批记录 */ @@ -1119,51 +1124,91 @@ public class CwApprovalRecordServiceImpl implements ICwApprovalRecordService { return checkApprovalPermission(applicationId, "dept_approve"); } - /** + /** * 获取可选审批人列表(院领导) + * 修改为基于权限角色查找:查找具有cw:approval:leader权限的用户 */ @Override public List> getAvailableApprovers(Long applicationId) { - log.info("开始查询院领导审批人列表,applicationId: {}", applicationId); + log.info("开始查询院领导审批人列表(基于权限角色),applicationId: {}", applicationId); List> approvers = new ArrayList<>(); try { - // 1. 查询部门名称包含"院领导"的部门 - SysDeptBo deptBo = new SysDeptBo(); - deptBo.setDeptName("院领导"); // 设置查询条件 - List leaderDepts = sysDeptService.selectDeptList(deptBo); + // 使用原生SQL查询具有cw:approval:leader权限的用户 + String sql = """ + SELECT DISTINCT + u.user_id, + u.user_name, + u.nick_name, + COALESCE(d.dept_name, '未分配部门') as dept_name, + COALESCE(d.dept_id, 0) as dept_id + FROM sys_user u + LEFT JOIN sys_dept d ON u.dept_id = d.dept_id + INNER JOIN sys_user_role ur ON u.user_id = ur.user_id + INNER JOIN sys_role r ON ur.role_id = r.role_id + INNER JOIN sys_role_menu rm ON r.role_id = rm.role_id + INNER JOIN sys_menu m ON rm.menu_id = m.menu_id + WHERE m.perms = 'cw:approval:leader' + AND u.status = '0' + AND u.del_flag = '0' + AND r.status = '0' + ORDER BY u.user_name + """; - log.info("找到院领导部门数量: {}", leaderDepts.size()); - for (SysDeptVo dept : leaderDepts) { - log.info("院领导部门: ID={}, 名称={}", dept.getDeptId(), dept.getDeptName()); + log.info("执行权限查询SQL查找具有cw:approval:leader权限的用户"); + + // 执行SQL查询 + List> results = jdbcTemplate.queryForList(sql); + + log.info("SQL查询结果:找到 {} 个具有院领导审批权限的用户", results.size()); + + // 转换查询结果为返回格式 + for (Map row : results) { + Map approver = new HashMap<>(); + approver.put("userId", row.get("user_id")); + approver.put("userName", row.get("user_name")); + approver.put("nickName", row.get("nick_name")); + approver.put("deptName", row.get("dept_name")); + approver.put("deptId", row.get("dept_id")); + approvers.add(approver); + + log.info("添加院领导审批人: userId={}, userName={}, nickName={}, deptName={}", + row.get("user_id"), row.get("user_name"), row.get("nick_name"), row.get("dept_name")); } - // 2. 查询院领导部门下的所有用户 - for (SysDeptVo dept : leaderDepts) { - List users = sysUserService.selectUserListByDept(dept.getDeptId()); + // 如果基于权限查询没有找到用户,使用原有的部门查询作为备选方案 + if (approvers.isEmpty()) { + log.warn("基于权限查询未找到院领导,尝试使用部门查询作为备选方案"); - log.info("部门[{}]下的用户数量: {}", dept.getDeptName(), users.size()); + SysDeptBo deptBo = new SysDeptBo(); + deptBo.setDeptName("院领导"); + List leaderDepts = sysDeptService.selectDeptList(deptBo); - // 3. 将用户信息转换为Map格式 - for (SysUserVo user : users) { - // 只返回状态正常的用户 - if ("0".equals(user.getStatus())) { - Map approver = new HashMap<>(); - approver.put("userId", user.getUserId()); - approver.put("userName", user.getUserName()); - approver.put("nickName", user.getNickName()); - approver.put("deptName", dept.getDeptName()); - approver.put("deptId", dept.getDeptId()); - approvers.add(approver); + log.info("备选方案:找到院领导部门数量: {}", leaderDepts.size()); - log.info("添加院领导审批人: userId={}, userName={}, nickName={}", - user.getUserId(), user.getUserName(), user.getNickName()); + for (SysDeptVo dept : leaderDepts) { + List users = sysUserService.selectUserListByDept(dept.getDeptId()); + log.info("备选方案:部门[{}]下的用户数量: {}", dept.getDeptName(), users.size()); + + for (SysUserVo user : users) { + if ("0".equals(user.getStatus())) { + Map approver = new HashMap<>(); + approver.put("userId", user.getUserId()); + approver.put("userName", user.getUserName()); + approver.put("nickName", user.getNickName()); + approver.put("deptName", dept.getDeptName()); + approver.put("deptId", dept.getDeptId()); + approvers.add(approver); + + log.info("备选方案:添加院领导审批人: userId={}, userName={}, nickName={}", + user.getUserId(), user.getUserName(), user.getNickName()); + } } } } - log.info("查询院领导审批人完成,共找到 {} 个院领导", approvers.size()); + log.info("查询院领导审批人完成,共找到 {} 个院领导(权限验证+部门备选)", approvers.size()); } catch (Exception e) { log.error("查询院领导审批人失败:{}", e.getMessage(), e); diff --git a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwProjectApplicationServiceImpl.java b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwProjectApplicationServiceImpl.java index 9264426f..a6d59fba 100644 --- a/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwProjectApplicationServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwProjectApplicationServiceImpl.java @@ -86,13 +86,29 @@ public class CwProjectApplicationServiceImpl implements ICwProjectApplicationSer log.info("✅ [统计页面-项目清单] 查询完成"); log.info("📊 [统计页面-项目清单] 查询结果: 总数={}, 当前页记录数={}", result.getTotal(), result.getRecords().size()); + // 🔧 为每个项目补充绩效指标数据(修复统计页面详情缺少绩效指标的问题) if (!result.getRecords().isEmpty()) { + log.info("🔄 [统计页面-项目清单] 开始补充绩效指标数据..."); + for (CwProjectApplicationVo record : result.getRecords()) { + try { + List performanceIndicators = performanceIndicatorService.queryByApplicationId(record.getId()); + record.setPerformanceIndicators(performanceIndicators); + log.debug(" ✅ 项目ID: {} 绩效指标数量: {}", record.getId(), performanceIndicators.size()); + } catch (Exception e) { + log.error(" ❌ 获取项目ID: {} 的绩效指标数据失败: {}", record.getId(), e.getMessage()); + // 设置空列表,避免前端报错 + record.setPerformanceIndicators(new ArrayList<>()); + } + } + log.info("✅ [统计页面-项目清单] 绩效指标数据补充完成"); + log.info("📝 [统计页面-项目清单] 前3条数据示例:"); for (int i = 0; i < Math.min(result.getRecords().size(), 3); i++) { CwProjectApplicationVo record = result.getRecords().get(i); - log.info(" {}. ID: {}, 申报编号: {}, 项目名称: {}, 状态: {}, 申报人: {}, 部门: {}", + int indicatorCount = record.getPerformanceIndicators() != null ? record.getPerformanceIndicators().size() : 0; + log.info(" {}. ID: {}, 申报编号: {}, 项目名称: {}, 状态: {}, 申报人: {}, 部门: {}, 绩效指标数: {}", i + 1, record.getId(), record.getApplicationNo(), record.getProjectName(), - record.getApprovalStatus(), record.getApplicantName(), record.getDepartmentName()); + record.getApprovalStatus(), record.getApplicantName(), record.getDepartmentName(), indicatorCount); } } else { log.warn("⚠️ [统计页面-项目清单] 查询结果为空!"); diff --git a/docs/变更管理/code-adjust-record-2025-01-18-wuzhen.md b/docs/变更管理/code-adjust-record-2025-01-18-wuzhen.md index 0519ecba..6bd27fdc 100644 --- a/docs/变更管理/code-adjust-record-2025-01-18-wuzhen.md +++ b/docs/变更管理/code-adjust-record-2025-01-18-wuzhen.md @@ -1 +1,442 @@ - \ No newline at end of file +# 代码调整记录 - 2025-01-18 - wuzhen + +## 2025-01-18 17:35:00 - 优化预算申报统计分析模块初始化逻辑 + +### 🎯 优化目标 +优化预算申报统计分析模块的初始化逻辑,界面打开时默认查询所有年份的申报数据,并将预算年度选项从2025年开始。 + +### 🔍 原有实现问题 +**原逻辑**: +1. ❌ 界面打开时默认查询2024年的数据 +2. ❌ 年度选择下拉框包含2024年选项 +3. ❌ 用户需要手动选择"全部年度"才能看到完整数据 + +**问题影响**: +- 用户体验不佳,需要额外操作才能看到全量数据 +- 年度选项包含过时的2024年,不符合当前业务需求 + +### 🚀 优化方案 +**新逻辑**: +1. ✅ 界面打开时默认查询所有年份的申报数据(budgetYear = '') +2. ✅ 年度选择从2025年开始,移除2024年选项 +3. ✅ 增加更多年份选项(2025-2028年) +4. ✅ 重置功能保持一致,重置后也是查询所有年份 + +### 🔧 技术实现 + +#### 修改文件 +**文件路径**:`web/src/views/cw/statistics/index.vue` + +#### 核心变更内容 + +1. **修改默认查询参数**(第244行) +```javascript +// 修改前 +queryParams: { + pageNum: 1, + pageSize: 10, + budgetYear: '2024' // 设置默认年度为2024 +}, + +// 修改后 +queryParams: { + pageNum: 1, + pageSize: 10, + budgetYear: '' // 设置默认为空,查询所有年份数据 +}, +``` + +2. **更新年度选择选项**(第7-12行) +```html + + + + + + + + + + + + + + + + +``` + +3. **重置逻辑验证**(第438-440行) +```javascript +/** 重置按钮操作 */ +resetQuery() { + this.queryParams.budgetYear = '' // ✅ 重置为空,查询所有年份 + this.handleQuery() +} +``` + +### 📊 预期效果 +- ✅ **用户体验优化**:界面打开即可看到所有年份的完整统计数据 +- ✅ **数据展示完整**:默认展示全量数据,避免数据遗漏 +- ✅ **年度选项更新**:移除过时的2024年,从2025年开始 +- ✅ **操作一致性**:重置功能与初始化逻辑保持一致 +- ✅ **前瞻性设计**:增加未来年份选项,便于长期使用 + +### 🚨 后续操作要求 +1. **无需重新编译**:仅前端静态资源修改,刷新页面即可生效 +2. **功能测试验证**: + - 打开预算申报统计分析页面,验证默认显示所有年份数据 + - 测试年度筛选功能,确认2025-2028年选项正常 + - 测试重置功能,确认重置后显示全部年度数据 + - 验证各个统计图表和数据表格正常加载 + +### 💡 技术要点 +- **前端状态管理**:通过修改data中的默认值实现初始化优化 +- **用户界面优化**:年度选项从当前年度开始,提升用户体验 +- **数据查询逻辑**:空字符串作为查询参数时,后端返回所有年份数据 +- **一致性保证**:初始化、重置、查询逻辑保持统一 + +--- + +## 2025-01-18 17:20:00 - 优化财务审批院领导选择逻辑(基于权限角色) + +### 🎯 优化目标 +将财务审批模块中选择院领导的逻辑从"按部门查找"优化为"按权限角色查找",确保选择的用户具有实际的院领导审批权限。 + +### 🔍 原有实现问题 +**原逻辑**:查询部门名称包含"院领导"的部门,返回该部门下的所有正常状态用户 +**问题分析**: +1. ❌ 依赖部门名称,不够灵活 +2. ❌ 可能包含非审批人员(部门内其他用户) +3. ❌ 没有权限验证,可能选择到无权限用户 +4. ❌ 不符合RBAC权限模型设计理念 + +### 🚀 优化方案 +**新逻辑**:基于权限角色查找具有 `cw:approval:leader` 权限的所有用户 +**优势**: +- ✅ 权限导向,确保选择的用户有审批权限 +- ✅ 不依赖部门结构,更灵活 +- ✅ 符合RBAC权限模型 +- ✅ 便于后续权限管理 +- ✅ 保留部门查询作为备选方案 + +### 🔧 技术实现 + +#### 修改文件 +**文件路径**:`backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwApprovalRecordServiceImpl.java` +**修改方法**:`getAvailableApprovers(Long applicationId)` (第1126行) + +#### 核心变更内容 + +1. **添加JdbcTemplate依赖** +```java +@Autowired +private JdbcTemplate jdbcTemplate; +``` + +2. **权限查询SQL** +```sql +SELECT DISTINCT + u.user_id, u.user_name, u.nick_name, + COALESCE(d.dept_name, '未分配部门') as dept_name, + COALESCE(d.dept_id, 0) as dept_id +FROM sys_user u +LEFT JOIN sys_dept d ON u.dept_id = d.dept_id +INNER JOIN sys_user_role ur ON u.user_id = ur.user_id +INNER JOIN sys_role r ON ur.role_id = r.role_id +INNER JOIN sys_role_menu rm ON r.role_id = rm.role_id +INNER JOIN sys_menu m ON rm.menu_id = m.menu_id +WHERE m.perms = 'cw:approval:leader' + AND u.status = '0' + AND u.del_flag = '0' + AND r.status = '0' +ORDER BY u.user_name +``` + +3. **双重保障机制** +- **主方案**:基于权限查询具有 `cw:approval:leader` 权限的用户 +- **备选方案**:如果权限查询无结果,使用原有的部门查询逻辑 + +#### 实现逻辑流程 +``` +1. 执行权限查询SQL → 查找具有cw:approval:leader权限的用户 +2. 转换查询结果 → 组装返回Map格式数据 +3. 结果检查 → 如果权限查询为空,启用部门查询备选方案 +4. 返回结果 → 具有审批权限的院领导列表 +``` + +### 📊 预期效果 +- ✅ **精确权限控制**:只返回真正具有院领导审批权限的用户 +- ✅ **系统一致性**:与RBAC权限模型保持一致 +- ✅ **灵活性提升**:不依赖特定部门名称 +- ✅ **向后兼容**:保留部门查询作为备选,确保系统稳定 +- ✅ **日志完善**:详细的查询过程日志,便于问题排查 + +### 🚨 后续操作要求 +1. **重新编译后端服务**:`mvn clean compile` +2. **重启Spring Boot应用** +3. **功能测试验证**: + - 财务人员审批时选择院领导功能 + - 验证只显示具有 `cw:approval:leader` 权限的用户 + - 测试备选方案是否正常工作 + +### 💡 技术要点 +- **权限查询**:通过多表关联查询用户权限 +- **NULL值处理**:使用COALESCE处理部门信息为空的情况 +- **异常处理**:查询失败时返回空列表,不影响主流程 +- **日志记录**:完整的查询过程日志,便于调试和监控 + +--- + +## 2025-01-18 16:45:00 - 修复财务和院领导审批"我已审批"查询问题 + +### 🚨 问题描述 +财务审批和院领导审批模块的"我已审批"功能无法查询到已审批的记录,用户反馈看不到自己审批过的内容。 + +### 🔍 问题分析 +通过深度分析发现两个核心问题: +1. **财务已审批查询状态不匹配**: + - 审批时更新状态为:`approved/rejected` + - 查询时使用状态为:`completed/rejected` + - 导致状态不匹配,查询不到记录 + +2. **院领导已审批查询状态不匹配**: + - 审批时更新状态为:`approved/rejected` + - 查询时使用状态为:`complete` + - 导致状态不匹配,查询不到记录 + +### 🔧 修复方案 +**方案一:修正查询状态(已采用)** + +#### 修复内容1:财务已审批查询 +**文件**:`backend/ruoyi-modules/ruoyi-cw/src/main/resources/mapper/CwApprovalRecordMapper.xml` +**位置**:第146行 +```xml + +and ar.node_status in ('completed', 'rejected') + + +and ar.node_status in ('approved', 'rejected') +``` + +#### 修复内容2:院领导已审批查询 +**文件**:`backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwApprovalRecordServiceImpl.java` +**位置**:第467行 +```java +// 修复前 +return baseMapper.selectByApproverAndNode(currentUserId, "leader_approve", "complete"); + +// 修复后 +return baseMapper.selectByApproverAndNode(currentUserId, "leader_approve", "approved"); +``` + +### 📊 修复效果预期 +- ✅ 财务人员能在"财务已审批"中看到自己审批的记录 +- ✅ 院领导能在"院领导已审批"中看到自己审批的记录 +- ✅ 通用"我已审批"功能正常工作(之前已修复approverId问题) +- ✅ 三个查询功能相互独立,互不影响 + +### 🚨 后续操作要求 +1. **重新编译后端服务**:`mvn clean compile` +2. **重启Spring Boot应用** +3. **功能测试验证**:用财务和院领导账号分别测试审批和查询功能 + +--- + +## 📋 本次变更概述 +**变更时间**: 2025-01-18 15:30:00 +**变更人员**: wuzhen +**变更类型**: 🔧 审批流程状态统一修复 +**影响范围**: 财务预算申报审批流程 + +## 🎯 问题背景 +发现审批流程中存在**状态不统一**和**逻辑错误**问题: + +### 原有问题 +1. **节点状态不统一**: + - 部门审批通过:`"approved"` + - 财务审批通过:`"completed"` + - 分管领导审批通过:`"completed"` + +2. **分管领导审批逻辑错误**: + - 审批通过后状态设为 `"finance_approving"` + - 应该是最终完成状态 `"approved"` + +3. **"我已审批"查询逻辑不准确**: + - 使用排除法 `.notIn("waiting", "pending")` + - 可能包含错误状态 + +## 🔧 修改内容 + +### 1. 统一财务审批节点状态 +**文件**: `CwApprovalRecordServiceImpl.java` +**位置**: 第1302行 +**修改**: `"completed"` → `"approved"` + +```java +// 修改前 +updateRecord.setNodeStatus("approve".equals(approveAction) ? "completed" : "rejected"); + +// 修改后 +updateRecord.setNodeStatus("approve".equals(approveAction) ? "approved" : "rejected"); +``` + +### 2. 统一分管领导审批节点状态 +**文件**: `CwApprovalRecordServiceImpl.java` +**位置**: 第1202行 +**修改**: `"completed"` → `"approved"` + +```java +// 修改前 +updateRecord.setNodeStatus("approve".equals(approveAction) ? "completed" : "rejected"); + +// 修改后 +updateRecord.setNodeStatus("approve".equals(approveAction) ? "approved" : "rejected"); +``` + +### 3. 修正分管领导审批的申报状态逻辑 +**文件**: `CwApprovalRecordServiceImpl.java` +**位置**: 第1224-1229行 +**修改**: `"finance_approving"` → `"approved"` + +```java +// 修改前 +if ("approve".equals(approveAction)) { + // 审批通过,状态改为财务审批中 + newStatus = "finance_approving"; + log.info("✅ 分管领导审批通过,提交财务审批:applicationId={}", applicationId); + // TODO: 这里可以添加创建财务审批记录的逻辑 + +// 修改后 +if ("approve".equals(approveAction)) { + // 分管领导审批通过,整个审批流程完成 + newStatus = "approved"; + log.info("✅ 分管领导审批通过,整个审批流程完成:applicationId={}", applicationId); +``` + +### 4. 修正"我已审批"查询逻辑 +**文件**: `CwApprovalRecordServiceImpl.java` +**位置**: 第381行 +**修改**: 排除法 → 精确匹配法 + +```java +// 修改前 +queryWrapper.eq(CwApprovalRecord::getApproverId, currentUserId) + .notIn(CwApprovalRecord::getNodeStatus, Arrays.asList("waiting", "pending")) + .orderByDesc(CwApprovalRecord::getEndTime); + +// 修改后 +queryWrapper.eq(CwApprovalRecord::getApproverId, currentUserId) + .in(CwApprovalRecord::getNodeStatus, Arrays.asList("approved", "rejected", "returned")) + .orderByDesc(CwApprovalRecord::getEndTime); +``` + +## 📊 修改后的状态体系 + +### 双层状态管理 +1. **申报级别状态** (`CwProjectApplication.approval_status`): + - `"approved"` = 整个流程完成 ✅ + - `"approving"` = 审批进行中 ⏳ + - `"rejected"` = 审批被拒绝 ❌ + - `"returned"` = 被退回修改 🔄 + +2. **审批节点状态** (`CwApprovalRecord.node_status`): + - `"approved"` = 节点通过(统一标准) + - `"rejected"` = 节点拒绝 + - `"returned"` = 节点退回 + - `"waiting"` = 等待审批 + +### 正确的流程逻辑 +``` +提交申报 → approval_status = "submitted" + ↓ +部门审批 → node_status = "approved" + approval_status = "approving" + ↓ +财务审批 → node_status = "approved" + approval_status = "approving" + ↓ +分管领导审批 → node_status = "approved" + approval_status = "approved" ✅最终完成 +``` + +## 🎯 预期效果 + +1. **状态统一**:所有审批节点通过状态统一为 `"approved"` +2. **流程正确**:分管领导审批通过后,整个流程完成 +3. **用户体验**:通过 `approval_status` 清晰知道审批进度 +4. **功能修复**:"我已审批"功能能正确显示审批记录 + +## ⚠️ 注意事项 + +1. **需要重新编译和启动服务**以生效 +2. **现有数据兼容性**:历史数据中的 `"completed"` 状态需要考虑兼容 +3. **前端显示**:确保前端能正确显示新的状态逻辑 +4. **测试验证**:需要完整测试审批流程的各个环节 + +## 📝 后续工作 + +1. 重启后端服务 +2. 测试完整的审批流程 +3. 验证"我已审批"功能 +4. 检查前端状态显示是否正确 +5. 考虑是否需要数据迁移脚本处理历史数据 + +--- + +## 🔧 财务审批"我已审批"功能修复 - 2025-01-18 22:30:00 + +### 🚨 **问题描述** +- **问题现象**: 财务审批通过后,该申请在"我已审批"列表中看不到 +- **具体案例**: YS202508049627申请财务审批通过后,在财务人员的"我已审批"中不显示 +- **影响范围**: 所有财务审批通过的记录都无法在"我已审批"中查看 + +### 🔍 **根本原因** +财务审批方法(`financeApproval`)中缺少关键的`approverId`字段更新: + +**问题代码**: +```java +// 财务审批时只更新了状态,但没有更新实际审批人ID +updateRecord.setNodeStatus("approved"); +updateRecord.setApproveAction("approve"); +// ❌ 缺少:updateRecord.setApproverId(currentUserId); +``` + +**"我已审批"查询逻辑**: +```java +// 根据approverId查询,如果approverId不匹配就查不到 +queryWrapper.eq(CwApprovalRecord::getApproverId, currentUserId) +``` + +### ✅ **修复方案** +在`CwApprovalRecordServiceImpl.financeApproval()`方法中添加缺失的审批人信息更新: + +```java +// 🔧 修复:更新实际审批人信息(解决"我已审批"查询不到的问题) +updateRecord.setApproverId(currentUserId); + +// 更新审批人姓名(保持数据一致性) +SysUserVo currentUser = sysUserService.selectUserById(currentUserId); +if (currentUser != null) { + updateRecord.setApproverName(currentUser.getNickName()); +} +``` + +### 📁 **修改文件** +- `backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwApprovalRecordServiceImpl.java` + - 修改位置:第1304行后 + - 修改内容:添加approverId和approverName字段更新 + +### 🎯 **预期效果** +修复后: +- ✅ 财务审批通过的记录能在"我已审批"中正确显示 +- ✅ 显示正确的审批人信息 +- ✅ 与分管领导审批记录保持一致的数据结构 +- ✅ 历史数据需要手动修复(如果需要) + +### 🔄 **后续操作** +1. 重启后端服务 +2. 测试财务审批功能 +3. 验证"我已审批"显示是否正常 + +--- + +**✅ 修改完成时间**: 2025-01-18 15:45:00 +**🔄 状态**: 待重启服务验证 \ No newline at end of file diff --git a/docs/变更管理/code-adjust-record-2025-01-27-statistics.md b/docs/变更管理/code-adjust-record-2025-01-27-statistics.md index 8db3845d..54994903 100644 --- a/docs/变更管理/code-adjust-record-2025-01-27-statistics.md +++ b/docs/变更管理/code-adjust-record-2025-01-27-statistics.md @@ -5,6 +5,84 @@ **需求来源**: 用户需求 - 项目预算数据统计功能 **状态**: ✅ 已完成 +## 📋 为奖学金管理模块添加英文文件夹名称 +**时间**: 2025-01-27 14:50:00 +**修改人**: AI Assistant +**任务描述**: 为奖学金管理模块产品需求设计文档中的各个功能模块添加英文文件夹名称 + +### 📋 修改内容 +**修改文件**: `docs/需求文档/奖惩补贴需求/奖学金管理模块产品需求设计.md` + +**具体修改**: +1. **奖项管理模块** → **奖项管理模块 (scholarship-type)** +2. **规则引擎模块** → **规则引擎模块 (scholarship-rule)** +3. **批次管理模块** → **批次管理模块 (scholarship-batch)** +4. **名额分配模块** → **名额分配模块 (scholarship-quota)** +5. **申请管理模块** → **申请管理模块 (scholarship-application)** +6. **审核管理模块** → **审核管理模块 (scholarship-review)** +7. **数据导出模块** → **数据导出模块 (scholarship-export)** +8. **统计报表模块** → **统计报表模块 (scholarship-statistics)**(系统架构图中) + +### ✅ 修改目的 +- 🎯 **开发指导**: 为后续代码开发提供明确的模块文件夹命名规范 +- 📁 **文件组织**: 统一英文命名规范,便于项目结构管理 +- 🔧 **技术实施**: 与Spring Boot项目结构保持一致 +- 📚 **文档完善**: 增强需求文档的技术可操作性 + +### 📋 命名规范 +- **前缀**: 统一使用 `scholarship-` 作为奖学金模块前缀 +- **格式**: 采用 kebab-case 命名风格(小写字母+连字符) +- **语义**: 英文名称与中文功能模块一一对应 +- **扩展**: 为后续模块扩展预留命名空间 + +--- + +## 📋 创建奖学金管理模块产品需求设计文档 +**时间**: 2025-01-27 14:45:00 +**修改人**: AI Assistant +**任务描述**: 根据用户原始需求,创建奖学金管理模块的完整产品需求设计文档 + +### 📋 需求分析内容 +**用户原始需求拆解**: +1. 自动评定规则设置和执行 +2. 奖种兼得关系维护功能 +3. 评定批次管理功能 +4. 二级学院名额分配和二次分配 +5. 学生在线申请和条件校验 +6. 学生处奖项设立功能 +7. 二级学院直接指定学生功能 +8. 申请审核和进度跟踪 +9. 评定结果导出功能 + +### 📋 文档创建内容 +**创建文件**: `docs/业务模块/奖惩补贴管理/奖学金管理模块产品需求设计.md` + +**文档结构**: +1. 需求概述(业务背景、目标用户、核心价值) +2. 核心需求分析(需求拆解、业务流程分析) +3. 功能模块设计(7个核心模块设计) +4. 用户角色与权限(4类角色权限矩阵) +5. 技术实现方案(技术架构、核心技术点、数据库设计) +6. 业务流程设计(完整流程图、关键业务规则) +7. 系统集成方案(学生信息系统集成) +8. 测试方案(功能、性能、安全测试) +9. 实施计划(8.5周开发计划) +10. 风险评估与应对(技术、业务、项目风险) + +### ✅ 特殊处理 +- ❌ **已移除财务系统对接相关内容**(按用户要求) +- ✅ 保留数据导出功能替代财务对接 +- ✅ 完整的需求分析和功能设计 +- ✅ 详细的技术实现方案和数据库设计 + +### 📋 文档特点 +- 📊 **完整性**: 涵盖需求分析到实施的全流程 +- 🎯 **针对性**: 基于用户原始需求精准设计 +- 🔧 **可实施性**: 提供具体的技术方案和开发计划 +- 📈 **可扩展性**: 预留后续功能扩展空间 + +--- + ## 📋 需求描述 开发项目预算数据统计功能,该模块需要具备以下功能: @@ -120,4 +198,34 @@ --- **开发完成时间**: 2025-01-27 17:30:00 -**功能状态**: ✅ 开发完成,可进行测试部署 \ No newline at end of file +**功能状态**: ✅ 开发完成,可进行测试部署 + +## 🔧 修复统计页面项目详情缺少绩效指标问题 +**时间**: 2025-01-27 14:30:00 +**修改人**: AI Assistant +**问题描述**: 预算申报统计模块中项目清单的详情展示缺少绩效指标设置内容 + +### 🚨 问题根源 +- **正常申报页面**: 使用 `/cw/application/{id}` 接口,会获取绩效指标数据 +- **统计页面**: 使用 `/cw/application/statistics/list` 接口,缺少绩效指标数据获取步骤 + +### 🔧 修改内容 +**修改文件**: `backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/service/impl/CwProjectApplicationServiceImpl.java` +**修改方法**: `queryStatisticsPageList`(第84-102行) + +**修改说明**: +1. 在查询结果返回前,为每个项目补充绩效指标数据 +2. 添加异常处理,避免绩效指标获取失败影响整体查询 +3. 增强日志输出,显示绩效指标数量信息 +4. 参考 `queryById` 方法的处理方式,保持数据结构一致 + +### ✅ 修改效果 +- ✅ 统计页面项目清单详情现在包含完整的绩效指标设置内容 +- ✅ ApplicationSummary组件中的绩效指标卡片正常显示 +- ✅ 保持前端代码不变,向下兼容 +- ✅ 统一了正常页面和统计页面的数据结构 + +### 📋 需要操作 +**⚠️ 需要重新编译后端服务才能生效** + +--- \ No newline at end of file diff --git a/docs/变更管理/code-adjust-record-2025-01-27-wuzhen.md b/docs/变更管理/code-adjust-record-2025-01-27-wuzhen.md index 36e7bc1e..aa24817a 100644 --- a/docs/变更管理/code-adjust-record-2025-01-27-wuzhen.md +++ b/docs/变更管理/code-adjust-record-2025-01-27-wuzhen.md @@ -1,77 +1,582 @@ # 代码调整记录 - 2025-01-27 - wuzhen -## 📋 本日变更概览 -- **变更时间**: 2025-01-27 15:30:00 -- **变更人员**: wuzhen -- **变更类型**: 前端样式优化 -- **影响模块**: 财务管理-项目清单 +## 📋 变更概览 +- **变更日期**: 2025-01-27 +- **操作人员**: wuzhen +- **变更类型**: 新增模块 - 数据模型设计 +- **影响范围**: 奖学金管理模块 --- -## 🎨 前端样式优化 +## 🎯 本次变更内容 -### 📱 项目清单页面样式修改 -**文件**: `web/src/views/cw/application/index.vue` -**变更时间**: 2025-01-27 15:30:00 +### ✅ 创建奖学金名额分配模块数据库表 (2025-01-27 16:32:00) -#### 变更内容 -1. **页面布局样式优化** - 参考后勤管理功能样式风格 - - 修改页面容器padding从20px改为8px,与后勤管理保持一致 - - 优化表格卡片布局,使用后勤管理的标准样式 +#### 📊 变更类型 +- **类型**: 数据库结构变更 +- **操作**: 新建表 +- **模块**: ruoyi-jcbt 奖学金名额分配管理 -2. **表格样式优化** - - 添加横向滚动条样式优化,支持更好的表格浏览体验 - - 增加固定列样式优化,提升表格可用性 - - 统一表格行悬停效果,保持视觉一致性 +#### 🎯 创建表结构 +1. **jcbt_scholarship_quota** - 奖学金名额分配表 + - 支持多级分配(全校→学院→专业→班级) + - 包含总名额、已使用、预留、可用等字段 + - 支持手动分配、自动分配、按比例分配等方式 -3. **分页组件样式统一** - - 修改分页容器样式,与后勤管理功能保持一致 - - 调整分页组件的padding和margin,优化视觉效果 +2. **jcbt_scholarship_quota_adjustment** - 名额调整记录表 + - 记录名额增加、减少、转移等操作 + - 支持审批流程和状态管理 + - 保留调整前后的完整数据记录 -4. **操作按钮尺寸调整** - - 将操作按钮尺寸从32x32px调整为27x27px,符合后勤管理标准 +#### 📁 相关文件 +- **SQL脚本**: `backend/sql/jcbt_scholarship_quota_management.sql` +- **数据库**: hzdyjs_xg (远程MySQL: 47.99.164.66:3306) -5. **Vue语法修正** - - 修复`v-model:showSearch`语法错误,改为Vue 2兼容的语法 +#### 🔍 表特性 +- ✅ 符合项目数据库规范(雪花ID、逻辑删除、多租户) +- ✅ 完整的索引策略和约束设置 +- ✅ 支持层级化名额分配管理 +- ✅ 完整的审批流程支持 -#### 技术细节 -- **滚动条样式**: 添加Webkit浏览器横向滚动条美化 -- **固定列阴影**: 增加左右固定列的阴影效果 -- **表格悬停**: 优化表格行悬停时的背景色同步 -- **响应式支持**: 保持原有的响应式设计 - -#### 样式参考标准 -- **参考模块**: 后勤管理功能 (`web/src/views/hq/`) -- **标准文件**: `satSurvey/index.vue`, `satCategory/index.vue` -- **布局规范**: 使用8px页面padding,统一卡片布局 +#### 📋 执行结果 +```sql +-- 成功创建表 +Tables_in_hzdyjs_xg (jcbt_scholarship_quota%) +jcbt_scholarship_quota +jcbt_scholarship_quota_adjustment +``` --- -## 🔧 技术问题修复 +### 🛠️ 修复奖学金类型搜索功能和Vue组件重复模板错误 (2025-01-27 13:58:00) -### Vue Linter错误修复 -**问题**: `v-model:showSearch` 语法在当前Vue版本中不支持 -**解决方案**: 改为 `:showSearch` + `@update:showSearch` 的Vue 2兼容写法 +#### 🔍 问题发现 +1. **搜索功能失效**:奖学金类型管理页面的搜索表单无法正常工作 +2. **Vue编译错误**:`Single file component can contain only one - +

经济效益指标

- + - + - + @@ -317,12 +222,7 @@ - + @@ -334,32 +234,17 @@ - + - + - + @@ -377,12 +262,7 @@ - + @@ -394,32 +274,17 @@ - + - + - + @@ -437,12 +302,7 @@ - + @@ -457,39 +317,24 @@ 满意度指标
- +

服务对象满意度指标

- + - + - + @@ -507,12 +352,7 @@ - + @@ -531,22 +371,22 @@ - diff --git a/web/src/views/cw/application/detail.vue b/web/src/views/cw/application/detail.vue index 6437becf..2fd5a17c 100644 --- a/web/src/views/cw/application/detail.vue +++ b/web/src/views/cw/application/detail.vue @@ -16,12 +16,7 @@ 审批流程 - +

{{ item.title }}

{{ item.description }}

@@ -33,36 +28,25 @@ 操作日志 - - + + - +
- 编辑 - 提交 - 撤回 + 编辑 + 提交 + 撤回 返回
@@ -72,9 +56,9 @@ \ No newline at end of file + diff --git a/web/src/views/cw/approverConfig/detail.vue b/web/src/views/cw/approverConfig/detail.vue index 5bd12d62..d57fe133 100644 --- a/web/src/views/cw/approverConfig/detail.vue +++ b/web/src/views/cw/approverConfig/detail.vue @@ -32,7 +32,7 @@ {{ parseTime(config.createTime, '{y}-{m}-{d} {h}:{i}') }} - +

配置描述

{{ config.description }}

@@ -48,22 +48,18 @@ 共 {{ config.steps.length }} 个步骤
- + - - +
-
+
- +
@@ -95,34 +91,24 @@
- +
- + {{ approver }}
- +
- +
- + @@ -144,13 +130,13 @@ export default { getApprovalTypeTag(type) { const typeMap = { 'fixed': 'success', - 'role': 'warning', + 'role': 'warning', 'dept': 'info', 'custom': 'primary' }; return typeMap[type] || 'info'; }, - + /** 获取审批类型文本 */ getApprovalTypeText(type) { const textMap = { @@ -161,7 +147,7 @@ export default { }; return textMap[type] || type; }, - + /** 获取适用范围文本 */ getScopeText(scope) { const scopeMap = { @@ -172,7 +158,7 @@ export default { }; return scopeMap[scope] || scope; }, - + /** 获取审批方式文本 */ getApprovalModeText(mode) { const modeMap = { @@ -182,7 +168,7 @@ export default { }; return modeMap[mode] || mode; }, - + /** 获取审批方式标签类型 */ getModeTagType(mode) { const typeMap = { @@ -201,7 +187,7 @@ export default { .detail-card { border-radius: 8px; border: 1px solid #e4e7ed; - + .card-header { display: flex; align-items: center; @@ -210,14 +196,14 @@ export default { color: #2c3e50; } } - + .section-title { margin: 0 0 12px 0; font-size: 16px; font-weight: 600; color: #2c3e50; } - + .description-text { margin: 0; padding: 12px; @@ -226,24 +212,24 @@ export default { color: #606266; line-height: 1.6; } - + .steps-detail { .step-detail-item { margin-bottom: 16px; - + &:last-child { margin-bottom: 0; } } - + .step-detail-card { border: 1px solid #e4e7ed; - + .step-header { display: flex; align-items: center; gap: 12px; - + .step-number { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; @@ -252,7 +238,7 @@ export default { font-size: 12px; font-weight: 600; } - + .step-name { font-weight: 600; color: #2c3e50; @@ -260,12 +246,12 @@ export default { } } } - + .step-info { display: flex; align-items: center; margin-bottom: 8px; - + .info-label { font-weight: 600; color: #909399; @@ -273,23 +259,23 @@ export default { min-width: 80px; } } - + .approvers-section { border-top: 1px solid #f0f0f0; padding-top: 16px; - + .info-label { font-weight: 600; color: #909399; margin-bottom: 8px; display: block; } - + .approvers-list { display: flex; flex-wrap: wrap; gap: 8px; - + .approver-tag { background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); color: white; @@ -297,7 +283,7 @@ export default { } } } - + .custom-approver-notice { border-top: 1px solid #f0f0f0; padding-top: 16px; @@ -316,4 +302,4 @@ export default { .mt-6 { margin-top: 24px; } - \ No newline at end of file + diff --git a/web/src/views/cw/approverConfig/index.vue b/web/src/views/cw/approverConfig/index.vue index 2169e9af..383c05a5 100644 --- a/web/src/views/cw/approverConfig/index.vue +++ b/web/src/views/cw/approverConfig/index.vue @@ -85,10 +85,14 @@ 新增 - 修改 + 修改 - 删除 + 删除 展开/折叠 @@ -125,12 +129,7 @@ @@ -178,13 +177,7 @@ - + @@ -241,13 +234,9 @@ 添加步骤
- +
-
+
- + @@ -290,46 +279,25 @@ - +
- - + +
- +
- - + +
- +
- +
- +
- +