From 8d70a61167f4ca4130654dee9d4091dafb804c83 Mon Sep 17 00:00:00 2001 From: wuzhen <52326163@qq.com> Date: Wed, 13 Aug 2025 17:07:49 +0800 Subject: [PATCH] wuzhen update --- .../controller/InternshipInfoController.java | 49 +++++++++- .../zsjy/mapper/InternshipInfoMapper.java | 8 ++ .../impl/InternshipInfoServiceImpl.java | 73 ++++++++++++++- .../resources/mapper/InternshipInfoMapper.xml | 28 ++++-- web/src/api/zsjy/internship.ts | 44 ++++++++- web/src/api/zsjy/types.ts | 22 ++--- .../views/zsjy/internship/msgmanage/index.vue | 89 +++++++++++++++---- 7 files changed, 267 insertions(+), 46 deletions(-) diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/controller/InternshipInfoController.java b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/controller/InternshipInfoController.java index 94bfc509..57d13f77 100644 --- a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/controller/InternshipInfoController.java +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/controller/InternshipInfoController.java @@ -13,6 +13,7 @@ import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.constraints.NotEmpty; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import jakarta.servlet.http.HttpServletResponse; @@ -23,6 +24,7 @@ import jakarta.servlet.http.HttpServletResponse; * @author system * @date 2025-01-03 */ +@Slf4j @Validated @RequiredArgsConstructor @RestController @@ -39,7 +41,18 @@ public class InternshipInfoController extends BaseController { @SaCheckPermission("zsjy:internship:list") @GetMapping("/list") public TableDataInfo list(@Validated InternshipInfoQueryBO queryBO, PageQuery pageQuery) { - return internshipInfoService.queryPageList(queryBO, pageQuery); + log.info("=== Controller层调试 ==="); + log.info("接口被调用: /zsjy/internship/list"); + log.info("查询参数: {}", queryBO); + log.info("分页参数: pageNum={}, pageSize={}", pageQuery.getPageNum(), pageQuery.getPageSize()); + + TableDataInfo result = internshipInfoService.queryPageList(queryBO, pageQuery); + + log.info("Controller返回结果: total={}, rows.size={}", + result.getTotal(), result.getRows() != null ? result.getRows().size() : "null"); + log.info("=== Controller层调试结束 ==="); + + return result; } /** @@ -83,4 +96,38 @@ public class InternshipInfoController extends BaseController { public R getInternshipStatistics(@Validated InternshipInfoQueryBO queryBO) { return R.ok(internshipInfoService.getInternshipStatistics(queryBO)); } + + /** + * 新增实习信息 + */ + @Operation(summary = "新增实习信息", description = "为学生新增实习信息") + @SaCheckPermission("zsjy:internship:add") + @PostMapping + public R add(@RequestBody @Validated Object addBO) { + // TODO: 实现新增实习信息功能 + return R.ok(); + } + + /** + * 修改实习信息 + */ + @Operation(summary = "修改实习信息", description = "修改学生实习信息") + @SaCheckPermission("zsjy:internship:edit") + @PutMapping + public R edit(@RequestBody @Validated Object editBO) { + // TODO: 实现修改实习信息功能 + return R.ok(); + } + + /** + * 删除实习信息 + */ + @Operation(summary = "删除实习信息", description = "删除学生实习信息") + @SaCheckPermission("zsjy:internship:remove") + @DeleteMapping("/{internshipIds}") + public R remove(@Parameter(description = "实习信息ID串") + @PathVariable Long[] internshipIds) { + // TODO: 实现删除实习信息功能 + return R.ok(); + } } diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/InternshipInfoMapper.java b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/InternshipInfoMapper.java index 935e9fca..fa0c12d0 100644 --- a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/InternshipInfoMapper.java +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/InternshipInfoMapper.java @@ -44,6 +44,14 @@ public interface InternshipInfoMapper { */ List> selectTeacherClasses(@Param("teacherId") Long teacherId); + /** + * 统计班主任管理的班级数量 + * + * @param teacherId 班主任ID + * @return 班级数量 + */ + Long countClassesByTeacherId(@Param("teacherId") Long teacherId); + /** * 查询实习状态统计数据 * diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/service/impl/InternshipInfoServiceImpl.java b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/service/impl/InternshipInfoServiceImpl.java index b06d2e15..8e5e1cb5 100644 --- a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/service/impl/InternshipInfoServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/service/impl/InternshipInfoServiceImpl.java @@ -41,17 +41,58 @@ public class InternshipInfoServiceImpl implements IInternshipInfoService { */ @Override public TableDataInfo queryPageList(InternshipInfoQueryBO queryBO, PageQuery pageQuery) { + log.info("=== 后端调试日志 ==="); + log.info("1. 查询参数: {}", queryBO); + log.info("2. 分页参数: pageNum={}, pageSize={}", pageQuery.getPageNum(), pageQuery.getPageSize()); + // 设置数据权限 setDataPermission(queryBO); + log.info("3. 设置数据权限后的查询参数: {}", queryBO); + log.info("3.1. 权限控制参数: classTeacherId={}, counselorId={}", + queryBO.getClassTeacherId(), queryBO.getCounselorId()); // 创建分页对象 Page page = pageQuery.build(); // 查询数据 List list = internshipInfoMapper.selectInternshipInfoList(page, queryBO); + log.info("4. 查询到的数据条数: {}", list != null ? list.size() : "null"); + + // 调试:输出前几条数据的关键字段和映射结果 + if (list != null && !list.isEmpty()) { + InternshipInfoVO firstRecord = list.get(0); + log.info("4.1. 第一条数据示例: studentId={}, studentName={}, className={}", + firstRecord.getStudentId(), firstRecord.getStudentName(), firstRecord.getClassName()); + + // 详细输出映射结果 + log.info("=== MyBatis映射结果详细信息 ==="); + log.info("学生信息 - ID:{}, 学号:{}, 姓名:{}, 性别:{}, 手机:{}", + firstRecord.getStudentId(), firstRecord.getStudentNo(), + firstRecord.getStudentName(), firstRecord.getGender(), firstRecord.getPhone()); + log.info("班级信息 - 班级ID:{}, 班级名称:{}, 年级:{}, 学院:{}, 专业:{}", + firstRecord.getClassId(), firstRecord.getClassName(), + firstRecord.getGrade(), firstRecord.getCollegeName(), firstRecord.getMajorName()); + log.info("实习信息 - 实习ID:{}, 状态:{}, 单位:{}, 岗位:{}, 薪资:{}", + firstRecord.getInternshipId(), firstRecord.getInternshipStatus(), + firstRecord.getCompanyName(), firstRecord.getInternshipPosition(), + firstRecord.getInternshipAllowance()); + log.info("时间信息 - 开始:{}, 结束:{}, 创建时间:{}", + firstRecord.getInternshipStartDate(), firstRecord.getInternshipEndDate(), + firstRecord.getCreateTime()); + log.info("联系信息 - 联系人:{}, 电话:{}, 协议状态:{}", + firstRecord.getContactPersonName(), firstRecord.getContactPersonPhone(), + firstRecord.getAgreementStatus()); + log.info("=== 映射结果输出完成 ==="); + } + log.info("5. page对象信息: total={}, size={}, current={}", page.getTotal(), page.getSize(), page.getCurrent()); // 处理实习状态显示名称 processInternshipStatusName(list); + log.info("6. 处理状态名称后的数据条数: {}", list != null ? list.size() : "null"); + + // 设置查询结果到page对象中 + page.setRecords(list); + log.info("7. 设置records后的page信息: total={}, records.size={}", page.getTotal(), page.getRecords().size()); return TableDataInfo.build(page); } @@ -142,15 +183,39 @@ public class InternshipInfoServiceImpl implements IInternshipInfoService { try { // 获取当前登录用户ID Long currentUserId = LoginHelper.getUserId(); + log.info("当前登录用户ID: {}", currentUserId); if (ObjectUtil.isNotNull(currentUserId)) { - // 设置班主任ID用于数据权限控制 - queryBO.setClassTeacherId(currentUserId); + // 检查该用户是否是班主任 + Long classTeacherCount = internshipInfoMapper.countClassesByTeacherId(currentUserId); + log.info("用户ID {}作为班主任管理的班级数量: {}", currentUserId, classTeacherCount); - log.debug("设置数据权限:班主任ID={}", currentUserId); + if (classTeacherCount > 0) { + // 是班主任,设置权限限制 + queryBO.setClassTeacherId(currentUserId); + log.info("设置数据权限:班主任ID={}", currentUserId); + } else { + // 不是班主任,检查是否是辅导员或管理员 + // 这里可以根据业务需求,设置更灵活的权限控制 + log.info("当前用户不是班主任,不设置班主任权限限制"); + + // 可以在这里添加其他角色的权限判断,比如: + // 1. 检查是否是辅导员 + // 2. 检查是否是管理员 + // 3. 检查是否有相关权限 + + // 暂时不设置权限限制,允许查看所有数据 + queryBO.setClassTeacherId(null); + queryBO.setCounselorId(null); + log.info("清除权限限制,允许查看所有数据"); + } } } catch (Exception e) { - log.warn("获取数据权限失败:{}", e.getMessage()); + log.error("设置数据权限失败:{}", e.getMessage(), e); + // 异常情况下,清除权限限制以避免查询为空 + queryBO.setClassTeacherId(null); + queryBO.setCounselorId(null); + log.warn("异常情况下清除权限限制,允许查看所有数据"); } } diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/resources/mapper/InternshipInfoMapper.xml b/backend/ruoyi-modules/ruoyi-zsjy/src/main/resources/mapper/InternshipInfoMapper.xml index a99087ae..7a42d5f0 100644 --- a/backend/ruoyi-modules/ruoyi-zsjy/src/main/resources/mapper/InternshipInfoMapper.xml +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/resources/mapper/InternshipInfoMapper.xml @@ -51,8 +51,11 @@ s.class_teacher_name, c.class_teacher_id, c.counselor_id, - i.internship_id as internship_id, - i.internship_status, + i.internship_id, + CASE + WHEN i.internship_status IS NULL OR i.internship_status = '' THEN 'null' + ELSE i.internship_status + END as internship_status, i.company_name, i.company_address, i.position_name as internship_position, @@ -119,22 +122,22 @@ AND i.company_address LIKE CONCAT('%', #{queryBO.companyAddress}, '%') - AND i.internship_position LIKE CONCAT('%', #{queryBO.internshipPosition}, '%') + AND i.position_name LIKE CONCAT('%', #{queryBO.internshipPosition}, '%') - AND i.agreement_status = #{queryBO.agreementStatus} + AND i.status = #{queryBO.agreementStatus} - AND i.internship_start_date >= #{queryBO.internshipStartDateBegin} + AND i.start_date >= #{queryBO.internshipStartDateBegin} - AND i.internship_start_date <= #{queryBO.internshipStartDateEnd} + AND i.start_date <= #{queryBO.internshipStartDateEnd} - AND i.internship_end_date >= #{queryBO.internshipEndDateBegin} + AND i.end_date >= #{queryBO.internshipEndDateBegin} - AND i.internship_end_date <= #{queryBO.internshipEndDateEnd} + AND i.end_date <= #{queryBO.internshipEndDateEnd} @@ -194,4 +197,13 @@ + + + diff --git a/web/src/api/zsjy/internship.ts b/web/src/api/zsjy/internship.ts index 0759d818..a48d91a1 100644 --- a/web/src/api/zsjy/internship.ts +++ b/web/src/api/zsjy/internship.ts @@ -1,12 +1,13 @@ import request from '@/utils/request'; import { AxiosPromise } from 'axios'; import { InternshipInfoVO, InternshipInfoQuery, ClassInfoVO, InternshipStatisticsVO } from '@/api/zsjy/types'; +import { TableDataInfo, R } from '@/api/types'; /** * 查询实习信息列表 * @param query 查询参数 */ -export const listInternshipInfo = (query?: InternshipInfoQuery): AxiosPromise => { +export const listInternshipInfo = (query?: InternshipInfoQuery): AxiosPromise> => { return request({ url: '/zsjy/internship/list', method: 'get', @@ -18,7 +19,7 @@ export const listInternshipInfo = (query?: InternshipInfoQuery): AxiosPromise => { +export const getInternshipInfo = (studentId: string | number): AxiosPromise> => { return request({ url: `/zsjy/internship/${studentId}`, method: 'get' @@ -41,7 +42,7 @@ export const exportInternshipInfo = (query: InternshipInfoQuery) => { /** * 获取班级信息列表(用于下拉选择) */ -export const getClassOptions = (): AxiosPromise => { +export const getClassOptions = (): AxiosPromise> => { return request({ url: '/zsjy/internship/classes', method: 'get' @@ -52,10 +53,45 @@ export const getClassOptions = (): AxiosPromise => { * 获取实习统计数据 * @param query 查询参数 */ -export const getInternshipStatistics = (query?: InternshipInfoQuery): AxiosPromise => { +export const getInternshipStatistics = (query?: InternshipInfoQuery): AxiosPromise> => { return request({ url: '/zsjy/internship/statistics', method: 'get', params: query }); }; + +/** + * 新增实习信息 + * @param data 实习信息数据 + */ +export const addInternshipInfo = (data: any): AxiosPromise> => { + return request({ + url: '/zsjy/internship', + method: 'post', + data: data + }); +}; + +/** + * 修改实习信息 + * @param data 实习信息数据 + */ +export const updateInternshipInfo = (data: any): AxiosPromise> => { + return request({ + url: '/zsjy/internship', + method: 'put', + data: data + }); +}; + +/** + * 删除实习信息 + * @param internshipId 实习信息ID + */ +export const delInternshipInfo = (internshipId: string | number): AxiosPromise> => { + return request({ + url: `/zsjy/internship/${internshipId}`, + method: 'delete' + }); +}; diff --git a/web/src/api/zsjy/types.ts b/web/src/api/zsjy/types.ts index b14fa103..a320bd7e 100644 --- a/web/src/api/zsjy/types.ts +++ b/web/src/api/zsjy/types.ts @@ -769,7 +769,7 @@ export interface InternshipInfoVO { /** * 手机号 */ - mobile?: string; + phone?: string; /** * 学院ID @@ -804,7 +804,7 @@ export interface InternshipInfoVO { /** * 班主任姓名 */ - classMasterName?: string; + classTeacherName?: string; /** * 实习状态 (0=未实习, 1=实习中, 2=实习完成) @@ -819,7 +819,7 @@ export interface InternshipInfoVO { /** * 实习公司 */ - internshipCompany?: string; + companyName?: string; /** * 实习岗位 @@ -829,17 +829,17 @@ export interface InternshipInfoVO { /** * 实习开始时间 */ - internshipStartTime?: string; + internshipStartDate?: string; /** * 实习结束时间 */ - internshipEndTime?: string; + internshipEndDate?: string; /** * 实习地点 */ - internshipLocation?: string; + companyAddress?: string; /** * 创建时间 @@ -909,17 +909,17 @@ export interface InternshipInfoQuery { /** * 实习公司 */ - internshipCompany?: string; + companyName?: string; /** - * 开始时间范围 + * 实习开始日期-开始 */ - startTimeBegin?: string; + internshipStartDateBegin?: string; /** - * 开始时间范围 + * 实习开始日期-结束 */ - startTimeEnd?: string; + internshipStartDateEnd?: string; } /** diff --git a/web/src/views/zsjy/internship/msgmanage/index.vue b/web/src/views/zsjy/internship/msgmanage/index.vue index eb388ce5..5b6e15c0 100644 --- a/web/src/views/zsjy/internship/msgmanage/index.vue +++ b/web/src/views/zsjy/internship/msgmanage/index.vue @@ -32,8 +32,8 @@ - - + + @@ -128,24 +128,28 @@ - + + + - + - + - + - - + + @@ -215,7 +238,7 @@ import { parseTime } from '@/utils/ruoyi'; import { download } from '@/utils/request'; const { proxy } = getCurrentInstance() as ComponentInternalInstance; -const { internship_status } = toRefs(proxy?.useDict('internship_status')); +const { internship_status, sys_user_sex } = toRefs(proxy?.useDict('internship_status', 'sys_user_sex')); const internshipList = ref([]); const classOptions = ref([]); @@ -239,9 +262,9 @@ const data = reactive({ studentNo: '', classId: '', internshipStatus: '', - internshipCompany: '', - startTimeBegin: '', - startTimeEnd: '' + companyName: '', + internshipStartDateBegin: '', + internshipStartDateEnd: '' } as InternshipInfoQuery, dialog: { visible: false, @@ -256,19 +279,33 @@ const getList = async () => { loading.value = true; // 处理日期范围 if (dateRange.value && dateRange.value.length === 2) { - queryParams.value.startTimeBegin = dateRange.value[0]; - queryParams.value.startTimeEnd = dateRange.value[1]; + queryParams.value.internshipStartDateBegin = dateRange.value[0]; + queryParams.value.internshipStartDateEnd = dateRange.value[1]; } else { - queryParams.value.startTimeBegin = ''; - queryParams.value.startTimeEnd = ''; + queryParams.value.internshipStartDateBegin = ''; + queryParams.value.internshipStartDateEnd = ''; } + console.log('=== 前端调试日志 ==='); + console.log('1. 查询参数:', JSON.stringify(queryParams.value, null, 2)); + try { const res = await listInternshipInfo(queryParams.value); + console.log('2. API响应完整数据:', JSON.stringify(res, null, 2)); + console.log('3. res.rows类型:', typeof res.rows, '长度:', res.rows ? res.rows.length : 'undefined'); + console.log('4. res.total:', res.total); + console.log('5. res.code:', res.code); + console.log('6. res.msg:', res.msg); + internshipList.value = res.rows; total.value = res.total; + + console.log('7. 赋值后 internshipList.value:', internshipList.value); + console.log('8. 赋值后 total.value:', total.value); + loading.value = false; } catch (error) { + console.error('API调用失败:', error); loading.value = false; } }; @@ -349,6 +386,18 @@ const handleExport = () => { }); }; +/** 新增实习信息按钮操作 */ +const handleAdd = (row: InternshipInfoVO) => { + // TODO: 实现新增实习信息功能 + proxy?.$modal.msgInfo('新增实习信息功能开发中...'); +}; + +/** 编辑实习信息按钮操作 */ +const handleEdit = (row: InternshipInfoVO) => { + // TODO: 实现编辑实习信息功能 + proxy?.$modal.msgInfo('编辑实习信息功能开发中...'); +}; + /** 取消按钮 */ const cancel = () => { dialog.value.visible = false; @@ -381,9 +430,13 @@ const cancel = () => { color: white; position: relative; overflow: hidden; + height: 100px; /* 设置固定高度,确保所有卡片高度一致 */ .statistics-content { flex: 1; + display: flex; + flex-direction: column; + justify-content: center; /* 内容垂直居中 */ .statistics-number { font-size: 28px;