diff --git a/backend/ruoyi-modules/ruoyi-jcbt/src/main/java/org/dromara/jcbt/controller/JcbtWorkStudyApplicationCollegeReviewController.java b/backend/ruoyi-modules/ruoyi-jcbt/src/main/java/org/dromara/jcbt/controller/JcbtWorkStudyApplicationCollegeReviewController.java index 0d42f306..fd65f658 100644 --- a/backend/ruoyi-modules/ruoyi-jcbt/src/main/java/org/dromara/jcbt/controller/JcbtWorkStudyApplicationCollegeReviewController.java +++ b/backend/ruoyi-modules/ruoyi-jcbt/src/main/java/org/dromara/jcbt/controller/JcbtWorkStudyApplicationCollegeReviewController.java @@ -56,19 +56,14 @@ public class JcbtWorkStudyApplicationCollegeReviewController extends BaseControl @GetMapping("/pendingList") public TableDataInfo pendingList(JcbtWorkStudyApplicationBo bo, PageQuery pageQuery) { // 获取当前用户的学院ID - String currentUserCollegeId = getCurrentUserCollegeId(); + Long currentUserCollegeId = getCurrentUserCollegeIdAsLong(); if (currentUserCollegeId == null) { log.warn("当前用户没有关联的学院信息,无法查看审核列表"); return TableDataInfo.build(); } // 设置学院过滤条件 - 只查看本学院学生的申请 - try { - bo.setCollegeId(Long.parseLong(currentUserCollegeId)); - } catch (NumberFormatException e) { - log.error("学院ID格式错误: {}", currentUserCollegeId); - return TableDataInfo.build(); - } + bo.setCollegeId(currentUserCollegeId); // 只查询已提交状态的申请(待学院审核) bo.setStatus("SUBMITTED"); @@ -84,19 +79,14 @@ public class JcbtWorkStudyApplicationCollegeReviewController extends BaseControl @GetMapping("/list") public TableDataInfo list(JcbtWorkStudyApplicationBo bo, PageQuery pageQuery) { // 获取当前用户的学院ID - String currentUserCollegeId = getCurrentUserCollegeId(); + Long currentUserCollegeId = getCurrentUserCollegeIdAsLong(); if (currentUserCollegeId == null) { log.warn("当前用户没有关联的学院信息,无法查看申请列表"); return TableDataInfo.build(); } // 设置学院过滤条件 - 只查看本学院学生的申请 - try { - bo.setCollegeId(Long.parseLong(currentUserCollegeId)); - } catch (NumberFormatException e) { - log.error("学院ID格式错误: {}", currentUserCollegeId); - return TableDataInfo.build(); - } + bo.setCollegeId(currentUserCollegeId); // 审核模块不显示草稿状态的申请 if (bo.getStatus() == null || bo.getStatus().isEmpty()) { @@ -121,17 +111,32 @@ public class JcbtWorkStudyApplicationCollegeReviewController extends BaseControl @SaCheckPermission("jcbt:workStudyApplication:collegeReview") @GetMapping("/{id}") public R getInfo(@PathVariable Long id) { + // 获取申请信息 JcbtWorkStudyApplicationVo vo = workStudyApplicationService.queryById(id); if (vo == null) { return R.fail("申请不存在"); } // 权限检查:只能查看本学院学生的申请 - String currentUserCollegeId = getCurrentUserCollegeId(); - if (currentUserCollegeId == null || !currentUserCollegeId.equals(vo.getCollegeId())) { - return R.fail("无权查看此申请"); + Long currentUserCollegeId = getCurrentUserCollegeIdAsLong(); + + // 添加详细日志用于调试 + log.info("权限检查 - 申请ID: {}, 申请学院ID: {}({}), 当前用户学院ID: {}({})", + id, vo.getCollegeId(), vo.getCollegeId() != null ? vo.getCollegeId().getClass().getSimpleName() : "null", + currentUserCollegeId, currentUserCollegeId != null ? currentUserCollegeId.getClass().getSimpleName() : "null"); + + if (currentUserCollegeId == null) { + log.warn("权限检查失败 - 当前用户没有关联的学院信息,用户ID: {}, 部门ID: {}, 部门名称: {}", + LoginHelper.getUserId(), LoginHelper.getDeptId(), LoginHelper.getDeptName()); + return R.fail("无权查看此申请:用户未关联学院信息"); } + if (!currentUserCollegeId.equals(vo.getCollegeId())) { + log.warn("权限检查失败 - 学院不匹配,申请学院ID: {}, 用户学院ID: {}", vo.getCollegeId(), currentUserCollegeId); + return R.fail("无权查看此申请:只能查看本学院学生的申请"); + } + + log.info("权限检查通过 - 申请ID: {}", id); return R.ok(vo); } @@ -151,7 +156,7 @@ public class JcbtWorkStudyApplicationCollegeReviewController extends BaseControl return R.fail("申请不存在"); } - String currentUserCollegeId = getCurrentUserCollegeId(); + Long currentUserCollegeId = getCurrentUserCollegeIdAsLong(); if (currentUserCollegeId == null || !currentUserCollegeId.equals(application.getCollegeId())) { return R.fail("无权审核此申请"); } @@ -172,7 +177,7 @@ public class JcbtWorkStudyApplicationCollegeReviewController extends BaseControl @Parameter(description = "审核意见") @RequestParam String reviewComment) { // 权限检查:批量审核前检查所有申请是否属于当前用户学院 - String currentUserCollegeId = getCurrentUserCollegeId(); + Long currentUserCollegeId = getCurrentUserCollegeIdAsLong(); if (currentUserCollegeId == null) { return R.fail("当前用户没有关联的学院信息"); } @@ -196,19 +201,14 @@ public class JcbtWorkStudyApplicationCollegeReviewController extends BaseControl @SaCheckPermission("jcbt:workStudyApplication:collegeReview") @GetMapping("/statistics") public R> getStatistics() { - String currentUserCollegeId = getCurrentUserCollegeId(); + Long currentUserCollegeId = getCurrentUserCollegeIdAsLong(); if (currentUserCollegeId == null) { return R.fail("当前用户没有关联的学院信息"); } // 构建查询条件 JcbtWorkStudyApplicationBo bo = new JcbtWorkStudyApplicationBo(); - try { - bo.setCollegeId(Long.parseLong(currentUserCollegeId)); - } catch (NumberFormatException e) { - log.error("学院ID格式错误: {}", currentUserCollegeId); - return R.fail("学院ID格式错误"); - } + bo.setCollegeId(currentUserCollegeId); // 获取各状态申请数量 Map statistics = new HashMap<>(); @@ -267,10 +267,58 @@ public class JcbtWorkStudyApplicationCollegeReviewController extends BaseControl return R.ok(options); } - // ========== 辅助方法 ========== + // ========== 工具方法 ========== /** - * 获取当前用户所属学院ID + * 调试权限信息 - 查看当前用户的学院关联情况 + */ + @Operation(summary = "调试权限信息") + @SaCheckPermission("jcbt:workStudyApplication:collegeReview") + @GetMapping("/debug/permission") + public R> debugPermission() { + Map result = new HashMap<>(); + + try { + Long userId = LoginHelper.getUserId(); + result.put("userId", userId); + result.put("username", LoginHelper.getUsername()); + result.put("deptId", LoginHelper.getDeptId()); + result.put("deptName", LoginHelper.getDeptName()); + + try { + result.put("deptCategory", LoginHelper.getDeptCategory()); + } catch (Exception e) { + result.put("deptCategory", "获取失败: " + e.getMessage()); + } + + // 检查学生信息 + try { + XgStudentMsgVo studentInfo = xgStudentMsgService.queryByUserId(userId); + if (studentInfo != null) { + result.put("isStudent", true); + result.put("studentCollegeId", studentInfo.getCollegeId()); + result.put("studentCollegeName", studentInfo.getCollegeName()); + } else { + result.put("isStudent", false); + } + } catch (Exception e) { + result.put("studentInfoError", e.getMessage()); + } + + // 获取最终的学院ID + String collegeId = getCurrentUserCollegeId(); + result.put("finalCollegeId", collegeId); + result.put("hasCollegeAccess", collegeId != null); + + } catch (Exception e) { + result.put("error", e.getMessage()); + } + + return R.ok(result); + } + + /** + * 获取当前用户的学院ID * 通过查询学生信息或用户部门信息获取 */ private String getCurrentUserCollegeId() { @@ -331,4 +379,20 @@ public class JcbtWorkStudyApplicationCollegeReviewController extends BaseControl return null; } } + + /** + * 获取当前用户的学院ID,返回Long类型 + */ + private Long getCurrentUserCollegeIdAsLong() { + String collegeIdStr = getCurrentUserCollegeId(); + if (collegeIdStr == null) { + return null; + } + try { + return Long.parseLong(collegeIdStr); + } catch (NumberFormatException e) { + log.error("学院ID格式错误: {}", collegeIdStr, e); + return null; + } + } } diff --git a/backend/ruoyi-modules/ruoyi-jcbt/src/main/resources/mapper/jcbt/JcbtWorkStudyApplicationMapper.xml b/backend/ruoyi-modules/ruoyi-jcbt/src/main/resources/mapper/jcbt/JcbtWorkStudyApplicationMapper.xml index 71232921..0672aa62 100644 --- a/backend/ruoyi-modules/ruoyi-jcbt/src/main/resources/mapper/jcbt/JcbtWorkStudyApplicationMapper.xml +++ b/backend/ruoyi-modules/ruoyi-jcbt/src/main/resources/mapper/jcbt/JcbtWorkStudyApplicationMapper.xml @@ -15,6 +15,12 @@ + + + + + + @@ -52,6 +58,12 @@ grade, class_name, phone, + contact_phone, + id_card, + family_financial_status, + planned_work_hours, + position_type, + work_location, email, application_reason, status, diff --git a/web/src/api/jcbt/workStudyApplication.ts b/web/src/api/jcbt/workStudyApplication.ts index f9b7cf76..8f7527aa 100644 --- a/web/src/api/jcbt/workStudyApplication.ts +++ b/web/src/api/jcbt/workStudyApplication.ts @@ -30,7 +30,7 @@ export interface WorkStudyApplicationQuery extends PageQuery { /** 工作地点 */ workLocation?: string; /** 申请状态 */ - applicationStatus?: string; + status?: string; /** 学院审核状态 */ collegeReviewStatus?: string; /** 学生处审核状态 */ @@ -135,7 +135,7 @@ export interface WorkStudyApplicationVO { /** 备注 */ remark?: string; /** 申请状态 */ - applicationStatus: string; + status: string; /** 学院审核状态 */ collegeReviewStatus?: string; /** 学院审核时间 */ diff --git a/web/src/api/jcbt/workStudyApplicationCollegeReview.ts b/web/src/api/jcbt/workStudyApplicationCollegeReview.ts index 3f9cf51d..90b020e2 100644 --- a/web/src/api/jcbt/workStudyApplicationCollegeReview.ts +++ b/web/src/api/jcbt/workStudyApplicationCollegeReview.ts @@ -21,18 +21,28 @@ export interface WorkStudyApplicationVO { status?: string; statusName?: string; applicationDate?: string; - collegeReviewBy?: string | number; - collegeReviewByName?: string; + // 学院审核相关字段 + collegeReviewStatus?: string; collegeReviewTime?: string; + collegeReviewerId?: string | number; + collegeReviewerName?: string; collegeReviewComment?: string; - finalReviewBy?: string | number; - finalReviewByName?: string; + // 最终审核相关字段 + finalReviewStatus?: string; finalReviewTime?: string; + finalReviewerId?: string | number; + finalReviewerName?: string; finalReviewComment?: string; + // 基础字段 createBy?: string | number; createTime?: string; updateBy?: string | number; updateTime?: string; + // 兼容旧字段名(保持向后兼容) + collegeReviewBy?: string | number; + collegeReviewByName?: string; + finalReviewBy?: string | number; + finalReviewByName?: string; } // 查询参数 diff --git a/web/src/views/jcbt/workstudy/Application/components/ApplicationDetail.vue b/web/src/views/jcbt/workstudy/Application/components/ApplicationDetail.vue index 3d0bae10..940ea6c5 100644 --- a/web/src/views/jcbt/workstudy/Application/components/ApplicationDetail.vue +++ b/web/src/views/jcbt/workstudy/Application/components/ApplicationDetail.vue @@ -9,8 +9,8 @@ 申请信息 - - {{ getStatusText(applicationData.applicationStatus) }} + + {{ getStatusText(applicationData.status) }} @@ -242,7 +242,7 @@ const getEconomicStatusType = (status: string) => { const getStepActive = () => { if (!applicationData.value) return 0; - const status = applicationData.value.applicationStatus; + const status = applicationData.value.status; switch (status) { case 'DRAFT': case 'SUBMITTED': @@ -262,7 +262,7 @@ const getStepActive = () => { const getStepStatus = (step: 'college' | 'final') => { if (!applicationData.value) return 'wait'; - const status = applicationData.value.applicationStatus; + const status = applicationData.value.status; if (step === 'college') { if (status === 'COLLEGE_APPROVED') return 'finish'; @@ -289,7 +289,7 @@ const getStepDescription = (step: 'college' | 'final') => { if (applicationData.value.collegeReviewTime) { return applicationData.value.collegeReviewTime; } - if (['SUBMITTED'].includes(applicationData.value.applicationStatus)) { + if (['SUBMITTED'].includes(applicationData.value.status)) { return '待审核'; } } @@ -298,7 +298,7 @@ const getStepDescription = (step: 'college' | 'final') => { if (applicationData.value.finalReviewTime) { return applicationData.value.finalReviewTime; } - if (applicationData.value.applicationStatus === 'COLLEGE_APPROVED') { + if (applicationData.value.status === 'COLLEGE_APPROVED') { return '待审核'; } } @@ -323,7 +323,7 @@ const getStepIconClass = (step: 'college' | 'final') => { const getFinalStatus = () => { if (!applicationData.value) return 'wait'; - const status = applicationData.value.applicationStatus; + const status = applicationData.value.status; if (status === 'FINAL_APPROVED') return 'finish'; if (['FINAL_REJECTED', 'COLLEGE_REJECTED'].includes(status)) return 'error'; return 'wait'; @@ -333,7 +333,7 @@ const getFinalStatus = () => { const getFinalDescription = () => { if (!applicationData.value) return ''; - const status = applicationData.value.applicationStatus; + const status = applicationData.value.status; if (status === 'FINAL_APPROVED') return '申请通过'; if (status === 'FINAL_REJECTED') return '申请被拒绝'; if (status === 'COLLEGE_REJECTED') return '申请被拒绝'; @@ -372,7 +372,7 @@ const handleDetail = async (id: string | number, mode: 'application' | 'position // 将岗位信息转换为申请信息格式用于显示 applicationData.value = { ...res.data, - applicationStatus: 'NOT_APPLIED' + status: 'NOT_APPLIED' // 其他字段根据需要添加 } as WorkStudyApplicationVO; } diff --git a/web/src/views/jcbt/workstudy/depreview/components/ApplicationDetail.vue b/web/src/views/jcbt/workstudy/depreview/components/ApplicationDetail.vue index 12a29dc8..7e445678 100644 --- a/web/src/views/jcbt/workstudy/depreview/components/ApplicationDetail.vue +++ b/web/src/views/jcbt/workstudy/depreview/components/ApplicationDetail.vue @@ -57,27 +57,41 @@ - - {{ applicationData.statusName }} + + {{ applicationData.statusName || applicationData.status }} {{ applicationData.applicationDate }} - - {{ applicationData.collegeReviewByName }} + + + + + {{ getReviewStatusText(applicationData.collegeReviewStatus) }} + + + + {{ applicationData.collegeReviewerName }} {{ applicationData.collegeReviewTime }} - +
{{ applicationData.collegeReviewComment }}
- - {{ applicationData.finalReviewByName }} + + + + + {{ getReviewStatusText(applicationData.finalReviewStatus) }} + + + + {{ applicationData.finalReviewerName }} {{ applicationData.finalReviewTime }} - +
{{ applicationData.finalReviewComment }}
@@ -137,19 +151,16 @@ const getDetail = async () => { const response = await getCollegeApplication(props.applicationId); console.log('详情API响应:', response); - // 处理不同的响应格式 - if (response.data) { - if (response.data.data) { - applicationData.value = response.data.data; - } else { - applicationData.value = response.data; - } + // 处理响应格式 + if (response && response.data) { + applicationData.value = response.data; } - } catch (error) { + } catch (error: any) { console.error('获取申请详情失败:', error); - if (error.message.includes('404')) { + const errorMessage = error?.message || ''; + if (errorMessage.includes('404')) { ElMessage.error('申请不存在或您无权查看此申请'); - } else if (error.message.includes('403')) { + } else if (errorMessage.includes('403')) { ElMessage.error('权限不足,无法查看申请详情'); } else { ElMessage.error('获取申请详情失败,请稍后重试'); @@ -167,7 +178,7 @@ const handleClose = () => { // 获取状态类型 const getStatusType = (status: string) => { - const statusMap = { + const statusMap: Record = { 'DRAFT': 'info', 'SUBMITTED': 'warning', 'COLLEGE_APPROVED': 'success', @@ -178,6 +189,26 @@ const getStatusType = (status: string) => { }; return statusMap[status] || 'info'; }; + +// 获取审核状态类型 +const getReviewStatusType = (status: string) => { + const statusMap: Record = { + 'PENDING': 'warning', + 'APPROVED': 'success', + 'REJECTED': 'danger' + }; + return statusMap[status] || 'info'; +}; + +// 获取审核状态文本 +const getReviewStatusText = (status: string) => { + const statusMap: Record = { + 'PENDING': '待审核', + 'APPROVED': '已通过', + 'REJECTED': '已拒绝' + }; + return statusMap[status] || status; +};