From 3fd877d57e883f745acb839f1ea70c83ef61d024 Mon Sep 17 00:00:00 2001 From: wuzhen <52326163@qq.com> Date: Wed, 13 Aug 2025 20:15:27 +0800 Subject: [PATCH 1/3] wuzhen update --- .../src/main/resources/application.yml | 6 +- backend/ruoyi-modules/ruoyi-zsjy/pom.xml | 6 + .../impl/InternshipInfoServiceImpl.java | 129 +++++++++++++++-- web/src/api/zsjy/types.ts | 135 ++++++++++++------ 4 files changed, 215 insertions(+), 61 deletions(-) diff --git a/backend/ruoyi-admin/src/main/resources/application.yml b/backend/ruoyi-admin/src/main/resources/application.yml index 24fb3c8a..f66f8f50 100644 --- a/backend/ruoyi-admin/src/main/resources/application.yml +++ b/backend/ruoyi-admin/src/main/resources/application.yml @@ -163,9 +163,9 @@ mybatis-plus: mapperLocations: classpath*:mapper/**/*Mapper.xml # 实体扫描,多个package用逗号或者分号分隔 typeAliasesPackage: org.dromara.**.domain - # 临时禁用SQL日志(减少系统负担) - # configuration: - # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + # 启用SQL日志输出,用于调试数据库插入问题 + configuration: + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: dbConfig: # 主键类型 diff --git a/backend/ruoyi-modules/ruoyi-zsjy/pom.xml b/backend/ruoyi-modules/ruoyi-zsjy/pom.xml index 3a3abd1b..aed2e7cc 100644 --- a/backend/ruoyi-modules/ruoyi-zsjy/pom.xml +++ b/backend/ruoyi-modules/ruoyi-zsjy/pom.xml @@ -104,6 +104,12 @@ ruoyi-workflow + + + org.dromara + ruoyi-xg + + 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 a24fba68..8f33c0c8 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 @@ -14,6 +14,9 @@ import org.dromara.common.excel.utils.ExcelUtil; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.xg.domain.vo.XgStudentMsgVo; +import org.dromara.xg.service.IXgStudentMsgService; +import org.dromara.common.core.exception.ServiceException; import org.dromara.zsjy.domain.bo.InternshipInfoQueryBO; import org.dromara.zsjy.domain.bo.InternshipInfoAddBO; import org.dromara.zsjy.domain.bo.InternshipInfoEditBO; @@ -41,6 +44,7 @@ public class InternshipInfoServiceImpl implements IInternshipInfoService { private final InternshipInfoMapper internshipInfoMapper; private final ZsjyInternshipInfoMapper zsjyInternshipInfoMapper; + private final IXgStudentMsgService xgStudentMsgService; /** * 查询学生实习信息分页列表(班主任专用) @@ -266,35 +270,104 @@ public class InternshipInfoServiceImpl implements IInternshipInfoService { @Override @Transactional(rollbackFor = Exception.class) public Boolean insertInternshipInfo(InternshipInfoAddBO addBO) { - log.info("新增实习信息,参数:{}", addBO); + log.info("=== 新增实习信息开始 ==="); + log.info("1. 接收到的参数:{}", addBO); // 检查该学生是否已经有实习信息 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(ZsjyInternshipInfo::getStudentId, addBO.getStudentId()); ZsjyInternshipInfo existingInfo = zsjyInternshipInfoMapper.selectOne(queryWrapper); + log.info("2. 检查学生是否已有实习信息,结果:{}", existingInfo != null ? "已存在" : "不存在"); if (ObjectUtil.isNotNull(existingInfo)) { log.warn("学生ID:{} 已存在实习信息,不能重复添加", addBO.getStudentId()); throw new RuntimeException("该学生已存在实习信息,不能重复添加"); } + // 根据学生ID查询学生基础信息 + log.info("3. 查询学生基础信息..."); + XgStudentMsgVo studentInfo = getStudentInfo(addBO.getStudentId()); + log.info("4. 学生信息查询结果:学号={}, 姓名={}, 学院ID={}, 专业ID={}, 班级ID={}, 手机号={}", + studentInfo.getStudentNo(), studentInfo.getName(), + studentInfo.getCollegeId(), studentInfo.getMajorId(), + studentInfo.getClassId(), studentInfo.getPhone()); + // 构建实习信息实体 ZsjyInternshipInfo internshipInfo = new ZsjyInternshipInfo(); - BeanUtil.copyProperties(addBO, internshipInfo); + log.info("5. 开始字段映射..."); - // 映射字段名称差异 - internshipInfo.setPositionName(addBO.getInternshipPosition()); - internshipInfo.setStartDate(addBO.getInternshipStartDate()); - internshipInfo.setEndDate(addBO.getInternshipEndDate()); - internshipInfo.setCompanyContact(addBO.getContactPersonName()); - internshipInfo.setCompanyPhone(addBO.getContactPersonPhone()); - internshipInfo.setStatus(addBO.getAgreementStatus()); + // 学生基础信息映射(数据库必填字段) + internshipInfo.setStudentId(addBO.getStudentId()); + internshipInfo.setStudentNo(studentInfo.getStudentNo()); // 从学生信息获取 + internshipInfo.setStudentName(studentInfo.getName()); // 从学生信息获取 + internshipInfo.setGender(studentInfo.getGender()); // 从学生信息获取 + + // 类型转换:String -> Long(处理可能的空值) + internshipInfo.setCollegeId(StringUtils.isNotBlank(studentInfo.getCollegeId()) ? + Long.parseLong(studentInfo.getCollegeId()) : null); // 从学生信息获取 + internshipInfo.setMajorId(StringUtils.isNotBlank(studentInfo.getMajorId()) ? + Long.parseLong(studentInfo.getMajorId()) : null); // 从学生信息获取 + internshipInfo.setClassId(StringUtils.isNotBlank(studentInfo.getClassId()) ? + Long.parseLong(studentInfo.getClassId()) : null); // 从学生信息获取 + + internshipInfo.setPhone(studentInfo.getPhone()); // 从学生信息获取 + + // 实习相关信息映射(来自BO) + internshipInfo.setInternshipStatus(addBO.getInternshipStatus()); + internshipInfo.setCompanyName(addBO.getCompanyName()); + internshipInfo.setCompanyAddress(addBO.getCompanyAddress()); + internshipInfo.setInternshipAllowance(addBO.getInternshipAllowance()); + internshipInfo.setPositionName(addBO.getInternshipPosition()); // internshipPosition -> positionName + internshipInfo.setStartDate(addBO.getInternshipStartDate()); // internshipStartDate -> startDate + internshipInfo.setEndDate(addBO.getInternshipEndDate()); // internshipEndDate -> endDate + + // 公司联系信息映射(优先使用BO中的新字段,兼容旧字段) + internshipInfo.setCompanyContact(StringUtils.isNotBlank(addBO.getCompanyContact()) ? + addBO.getCompanyContact() : addBO.getContactPersonName()); // 优先使用companyContact + internshipInfo.setCompanyPhone(StringUtils.isNotBlank(addBO.getCompanyPhone()) ? + addBO.getCompanyPhone() : addBO.getContactPersonPhone()); // 优先使用companyPhone + + // 新增字段映射(从BO中获取真实值) + internshipInfo.setCompanyIndustry(addBO.getCompanyIndustry()); // 行业类型 + internshipInfo.setCompanyScale(addBO.getCompanyScale()); // 单位规模 + internshipInfo.setPositionDuties(addBO.getPositionDuties()); // 岗位职责 + internshipInfo.setWorkHours(addBO.getWorkHours()); // 工作时长 + internshipInfo.setAccommodationAddress(addBO.getAccommodationAddress()); // 住宿地址 + internshipInfo.setAccommodationType(addBO.getAccommodationType()); // 住宿类型 + internshipInfo.setAccommodationCost(addBO.getAccommodationCost()); // 住宿费用 + + internshipInfo.setStatus(addBO.getAgreementStatus()); // agreementStatus -> status + // actualEndDate保持null,因为实习还未结束 + + log.info("6. 映射后的实体对象:"); + log.info(" - studentId: {}", internshipInfo.getStudentId()); + log.info(" - studentNo: {}", internshipInfo.getStudentNo()); + log.info(" - studentName: {}", internshipInfo.getStudentName()); + log.info(" - collegeId: {}", internshipInfo.getCollegeId()); + log.info(" - majorId: {}", internshipInfo.getMajorId()); + log.info(" - classId: {}", internshipInfo.getClassId()); + log.info(" - phone: {}", internshipInfo.getPhone()); + log.info(" - internshipStatus: {}", internshipInfo.getInternshipStatus()); + log.info(" - companyName: {}", internshipInfo.getCompanyName()); + log.info(" - companyAddress: {}", internshipInfo.getCompanyAddress()); + log.info(" - positionName: {}", internshipInfo.getPositionName()); + log.info(" - internshipAllowance: {}", internshipInfo.getInternshipAllowance()); + log.info(" - startDate: {}", internshipInfo.getStartDate()); + log.info(" - endDate: {}", internshipInfo.getEndDate()); + log.info(" - companyContact: {}", internshipInfo.getCompanyContact()); + log.info(" - companyPhone: {}", internshipInfo.getCompanyPhone()); + log.info(" - status: {}", internshipInfo.getStatus()); // 插入数据 + log.info("7. 开始执行数据库插入操作..."); int result = zsjyInternshipInfoMapper.insert(internshipInfo); - log.info("新增实习信息结果:{}", result > 0 ? "成功" : "失败"); + log.info("8. 数据库插入结果:{} (1表示成功,0表示失败)", result); + log.info("9. 插入后的主键ID:{}", internshipInfo.getInternshipId()); - return result > 0; + boolean success = result > 0; + log.info("=== 新增实习信息结束,结果:{} ===", success ? "成功" : "失败"); + + return success; } /** @@ -323,8 +396,22 @@ public class InternshipInfoServiceImpl implements IInternshipInfoService { internshipInfo.setPositionName(editBO.getInternshipPosition()); internshipInfo.setStartDate(editBO.getInternshipStartDate()); internshipInfo.setEndDate(editBO.getInternshipEndDate()); - internshipInfo.setCompanyContact(editBO.getContactPersonName()); - internshipInfo.setCompanyPhone(editBO.getContactPersonPhone()); + + // 公司联系信息映射(优先使用BO中的新字段,兼容旧字段) + internshipInfo.setCompanyContact(StringUtils.isNotBlank(editBO.getCompanyContact()) ? + editBO.getCompanyContact() : editBO.getContactPersonName()); // 优先使用companyContact + internshipInfo.setCompanyPhone(StringUtils.isNotBlank(editBO.getCompanyPhone()) ? + editBO.getCompanyPhone() : editBO.getContactPersonPhone()); // 优先使用companyPhone + + // 新增字段映射(从BO中获取真实值) + internshipInfo.setCompanyIndustry(editBO.getCompanyIndustry()); // 行业类型 + internshipInfo.setCompanyScale(editBO.getCompanyScale()); // 单位规模 + internshipInfo.setPositionDuties(editBO.getPositionDuties()); // 岗位职责 + internshipInfo.setWorkHours(editBO.getWorkHours()); // 工作时长 + internshipInfo.setAccommodationAddress(editBO.getAccommodationAddress()); // 住宿地址 + internshipInfo.setAccommodationType(editBO.getAccommodationType()); // 住宿类型 + internshipInfo.setAccommodationCost(editBO.getAccommodationCost()); // 住宿费用 + internshipInfo.setStatus(editBO.getAgreementStatus()); // 更新数据 @@ -356,4 +443,20 @@ public class InternshipInfoServiceImpl implements IInternshipInfoService { return result > 0; } + + /** + * 根据学生ID查询学生基础信息 + * + * @param studentId 学生ID + * @return 学生信息 + */ + private XgStudentMsgVo getStudentInfo(Long studentId) { + log.info("根据学生ID查询学生信息:{}", studentId); + XgStudentMsgVo studentInfo = xgStudentMsgService.queryByUserId(studentId); + if (studentInfo == null) { + log.error("未找到学生信息,学生ID:{}", studentId); + throw new ServiceException("未找到学生信息,学生ID:" + studentId); + } + return studentInfo; + } } diff --git a/web/src/api/zsjy/types.ts b/web/src/api/zsjy/types.ts index 8668c151..02673477 100644 --- a/web/src/api/zsjy/types.ts +++ b/web/src/api/zsjy/types.ts @@ -871,6 +871,16 @@ export interface InternshipInfoAddBO { */ studentId: string | number; + /** + * 学生姓名(前端显示用) + */ + studentName?: string; + + /** + * 学生学号(前端显示用) + */ + studentNo?: string; + /** * 实习状态(1进行中 2已完成 3中断) */ @@ -886,6 +896,16 @@ export interface InternshipInfoAddBO { */ companyAddress: string; + /** + * 单位联系人 + */ + companyContact?: string; + + /** + * 联系人电话 + */ + companyPhone?: string; + /** * 行业类型 */ @@ -897,30 +917,40 @@ export interface InternshipInfoAddBO { companyScale?: string; /** - * 单位联系人 + * 实习岗位 */ - companyContact: string; + internshipPosition: string; + + /** + * 实习薪资 + */ + internshipAllowance?: number; + + /** + * 实习开始时间 + */ + internshipStartDate: string; + + /** + * 实习结束时间 + */ + internshipEndDate: string; + + /** + * 联系人姓名 + */ + contactPersonName: string; /** * 联系人电话 */ - companyPhone: string; - - /** - * 岗位名称 - */ - positionName: string; + contactPersonPhone: string; /** * 岗位职责 */ positionDuties?: string; - /** - * 实习津贴 - */ - internshipAllowance?: number; - /** * 工作时长 */ @@ -942,19 +972,9 @@ export interface InternshipInfoAddBO { accommodationCost?: number; /** - * 实习开始日期 + * 实习协议状态(1已签署 2未签署) */ - startDate: string; - - /** - * 实习结束日期 - */ - endDate: string; - - /** - * 实际结束日期 - */ - actualEndDate?: string; + agreementStatus: string; /** * 备注 @@ -976,6 +996,16 @@ export interface InternshipInfoEditBO { */ studentId: string | number; + /** + * 学生姓名(前端显示用) + */ + studentName?: string; + + /** + * 学生学号(前端显示用) + */ + studentNo?: string; + /** * 实习状态(1进行中 2已完成 3中断) */ @@ -991,6 +1021,16 @@ export interface InternshipInfoEditBO { */ companyAddress: string; + /** + * 单位联系人 + */ + companyContact?: string; + + /** + * 联系人电话 + */ + companyPhone?: string; + /** * 行业类型 */ @@ -1002,30 +1042,40 @@ export interface InternshipInfoEditBO { companyScale?: string; /** - * 单位联系人 + * 实习岗位 */ - companyContact: string; + internshipPosition: string; + + /** + * 实习薪资 + */ + internshipAllowance?: number; + + /** + * 实习开始时间 + */ + internshipStartDate: string; + + /** + * 实习结束时间 + */ + internshipEndDate: string; + + /** + * 联系人姓名 + */ + contactPersonName: string; /** * 联系人电话 */ - companyPhone: string; - - /** - * 岗位名称 - */ - positionName: string; + contactPersonPhone: string; /** * 岗位职责 */ positionDuties?: string; - /** - * 实习津贴 - */ - internshipAllowance?: number; - /** * 工作时长 */ @@ -1047,14 +1097,9 @@ export interface InternshipInfoEditBO { accommodationCost?: number; /** - * 实习开始日期 + * 实习协议状态(1已签署 2未签署) */ - startDate: string; - - /** - * 实习结束日期 - */ - endDate: string; + agreementStatus: string; /** * 实际结束日期 From d4d3dd26fc8dc35a84881322f9537c60222bc548 Mon Sep 17 00:00:00 2001 From: wuzhen <52326163@qq.com> Date: Wed, 13 Aug 2025 20:27:26 +0800 Subject: [PATCH 2/3] wuzhen update --- web/src/api/zsjy/types.ts | 25 ++++++++++++ .../views/zsjy/internship/msgmanage/index.vue | 40 ++++++++++++++----- 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/web/src/api/zsjy/types.ts b/web/src/api/zsjy/types.ts index 02673477..23dd8ba4 100644 --- a/web/src/api/zsjy/types.ts +++ b/web/src/api/zsjy/types.ts @@ -841,6 +841,31 @@ export interface InternshipInfoVO { */ companyAddress?: string; + /** + * 实习津贴 + */ + internshipAllowance?: number; + + /** + * 单位联系人 + */ + contactPersonName?: string; + + /** + * 联系人电话 + */ + contactPersonPhone?: string; + + /** + * 协议状态 + */ + agreementStatus?: string; + + /** + * 备注信息 + */ + remark?: string; + /** * 创建时间 */ diff --git a/web/src/views/zsjy/internship/msgmanage/index.vue b/web/src/views/zsjy/internship/msgmanage/index.vue index 2e72b55f..88ac5fa0 100644 --- a/web/src/views/zsjy/internship/msgmanage/index.vue +++ b/web/src/views/zsjy/internship/msgmanage/index.vue @@ -93,7 +93,7 @@ {{ statisticsData.internshipCount || 0 }} - 实习中 + 已实习 @@ -103,9 +103,9 @@ - {{ statisticsData.internshipCount || 0 }} - 已完成 - 实习率:{{ statisticsData.internshipRate || '0.00%' }} + {{ statisticsData.internshipRate || '0.00%' }} + 实习率 + 已实习学生占比 @@ -194,17 +194,17 @@ - + {{ studentDetail.studentNo }} {{ studentDetail.studentName }} {{ studentDetail.gender }} - {{ studentDetail.mobile }} + {{ studentDetail.phone }} {{ studentDetail.collegeName }} {{ studentDetail.majorName }} {{ studentDetail.className }} - {{ studentDetail.classMasterName }} + {{ studentDetail.classTeacherName }} @@ -212,17 +212,29 @@ 未实习 - {{ studentDetail.internshipCompany || '-' }} + {{ studentDetail.companyName || '-' }} {{ studentDetail.internshipPosition || '-' }} - {{ studentDetail.internshipLocation || '-' }} + {{ studentDetail.companyAddress || '-' }} - {{ parseTime(studentDetail.internshipStartTime, '{y}-{m}-{d}') }} + {{ parseTime(studentDetail.internshipStartDate, '{y}-{m}-{d}') }} - - {{ parseTime(studentDetail.internshipEndTime, '{y}-{m}-{d}') }} + {{ parseTime(studentDetail.internshipEndDate, '{y}-{m}-{d}') }} - + {{ studentDetail.contactPersonName || '-' }} + {{ studentDetail.contactPersonPhone || '-' }} + + {{ studentDetail.internshipAllowance }}元/月 + - + + + 已签署 + 未签署 + - + + {{ studentDetail.remark || '-' }} @@ -498,6 +510,12 @@ const cancel = () => { opacity: 0.8; margin-top: 2px; } + + .statistics-description { + font-size: 12px; + opacity: 0.8; + margin-top: 2px; + } } .statistics-icon { From d30086a7c3f8fb9cec047c977767456def1b2d41 Mon Sep 17 00:00:00 2001 From: wuzhen <52326163@qq.com> Date: Wed, 13 Aug 2025 21:54:13 +0800 Subject: [PATCH 3/3] wuzhen update --- .../ZsjyInternshipDailyController.java | 101 ++ .../zsjy/domain/ZsjyInternshipDaily.java | 99 ++ .../zsjy/domain/ZsjyInternshipInfo.java | 163 ++++ .../zsjy/domain/bo/InternshipInfoAddBO.java | 167 ++++ .../zsjy/domain/bo/InternshipInfoEditBO.java | 174 ++++ .../domain/bo/ZsjyInternshipDailyAddBo.java | 119 +++ .../domain/bo/ZsjyInternshipDailyQueryBo.java | 85 ++ .../zsjy/domain/vo/ZsjyInternshipDailyVo.java | 164 ++++ .../mapper/ZsjyInternshipDailyMapper.java | 64 ++ .../zsjy/mapper/ZsjyInternshipInfoMapper.java | 16 + .../service/IZsjyInternshipDailyService.java | 64 ++ .../impl/ZsjyInternshipDailyServiceImpl.java | 164 ++++ .../mapper/ZsjyInternshipDailyMapper.xml | 168 ++++ web/src/api/zsjy/internshipDaily.js | 46 + .../views/zsjy/internship/daily/checkin.vue | 695 ++++++++++++++ web/src/views/zsjy/internship/daily/index.vue | 899 ++++++++++++++++++ .../msgmanage/components/AddDialog.vue | 366 +++++++ .../msgmanage/components/EditDialog.vue | 437 +++++++++ 18 files changed, 3991 insertions(+) create mode 100644 backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/controller/ZsjyInternshipDailyController.java create mode 100644 backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/ZsjyInternshipDaily.java create mode 100644 backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/ZsjyInternshipInfo.java create mode 100644 backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/bo/InternshipInfoAddBO.java create mode 100644 backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/bo/InternshipInfoEditBO.java create mode 100644 backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/bo/ZsjyInternshipDailyAddBo.java create mode 100644 backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/bo/ZsjyInternshipDailyQueryBo.java create mode 100644 backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/vo/ZsjyInternshipDailyVo.java create mode 100644 backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/ZsjyInternshipDailyMapper.java create mode 100644 backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/ZsjyInternshipInfoMapper.java create mode 100644 backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/service/IZsjyInternshipDailyService.java create mode 100644 backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/service/impl/ZsjyInternshipDailyServiceImpl.java create mode 100644 backend/ruoyi-modules/ruoyi-zsjy/src/main/resources/mapper/ZsjyInternshipDailyMapper.xml create mode 100644 web/src/api/zsjy/internshipDaily.js create mode 100644 web/src/views/zsjy/internship/daily/checkin.vue create mode 100644 web/src/views/zsjy/internship/daily/index.vue create mode 100644 web/src/views/zsjy/internship/msgmanage/components/AddDialog.vue create mode 100644 web/src/views/zsjy/internship/msgmanage/components/EditDialog.vue diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/controller/ZsjyInternshipDailyController.java b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/controller/ZsjyInternshipDailyController.java new file mode 100644 index 00000000..2c11b2fe --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/controller/ZsjyInternshipDailyController.java @@ -0,0 +1,101 @@ +package org.dromara.zsjy.controller; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.web.core.BaseController; +import org.dromara.zsjy.domain.bo.ZsjyInternshipDailyAddBo; +import org.dromara.zsjy.domain.bo.ZsjyInternshipDailyQueryBo; +import org.dromara.zsjy.domain.vo.ZsjyInternshipDailyVo; +import org.dromara.zsjy.service.IZsjyInternshipDailyService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; + +/** + * 实习日常管理Controller + * + * @author system + * @date 2025-01-03 + */ +@Slf4j +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/zsjy/internship/daily") +@Tag(name = "实习日常管理", description = "学生实习日常打卡签到管理") +public class ZsjyInternshipDailyController extends BaseController { + + private final IZsjyInternshipDailyService dailyService; + + /** + * 查询实习日常记录列表 + */ + @Operation(summary = "查询实习日常记录列表", description = "班主任查看学生实习日常记录") + @SaCheckPermission("zsjy:internshipdaily:list") + @GetMapping("/list") + public TableDataInfo list(@Validated ZsjyInternshipDailyQueryBo queryBo, PageQuery pageQuery) { + log.info("=== Controller层调试 ==="); + log.info("接口被调用: /zsjy/internship/daily/list"); + log.info("查询参数: {}", queryBo); + log.info("分页参数: {}", pageQuery); + + return dailyService.queryPageList(queryBo, pageQuery); + } + + /** + * 学生签到打卡 + */ + @Operation(summary = "学生签到打卡", description = "学生进行实习日常签到打卡") + @SaCheckPermission("zsjy:internshipdaily:checkin") + @PostMapping("/checkin") + public R checkIn(@Validated(AddGroup.class) @RequestBody ZsjyInternshipDailyAddBo addBo) { + log.info("=== Controller层调试 ==="); + log.info("接口被调用: /zsjy/internship/daily/checkin"); + log.info("签到参数: {}", addBo); + + return dailyService.checkIn(addBo); + } + + /** + * 获取学生考勤日历 + */ + @Operation(summary = "获取学生考勤日历", description = "查看指定学生的考勤日历数据") + @SaCheckPermission("zsjy:internshipdaily:calendar") + @GetMapping("/calendar/{studentId}") + public R>> getCalendar( + @Parameter(description = "学生ID", required = true) @PathVariable Long studentId, + @Parameter(description = "年份") @RequestParam(required = false) Integer year, + @Parameter(description = "月份") @RequestParam(required = false) Integer month) { + + log.info("=== Controller层调试 ==="); + log.info("接口被调用: /zsjy/internship/daily/calendar/{}", studentId); + log.info("查询年月: {}-{}", year, month); + + return dailyService.getCalendarData(studentId, year, month); + } + + /** + * 获取考勤统计数据 + */ + @Operation(summary = "获取考勤统计数据", description = "查看实习生考勤统计分析") + @SaCheckPermission("zsjy:internshipdaily:statistics") + @GetMapping("/statistics") + public R> getStatistics(@Validated ZsjyInternshipDailyQueryBo queryBo) { + log.info("=== Controller层调试 ==="); + log.info("接口被调用: /zsjy/internship/daily/statistics"); + log.info("统计参数: {}", queryBo); + + return dailyService.getStatistics(queryBo); + } + +} diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/ZsjyInternshipDaily.java b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/ZsjyInternshipDaily.java new file mode 100644 index 00000000..38a5c471 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/ZsjyInternshipDaily.java @@ -0,0 +1,99 @@ +package org.dromara.zsjy.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.mybatis.core.domain.BaseEntity; + +import java.io.Serial; +import java.math.BigDecimal; +import java.sql.Time; +import java.util.Date; + +/** + * 实习日常管理实体对象 zsjy_internship_daily + * + * @author system + * @date 2025-01-03 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("zsjy_internship_daily") +public class ZsjyInternshipDaily extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 日常记录ID + */ + @TableId(value = "daily_id") + private Long dailyId; + + /** + * 实习ID + */ + private Long internshipId; + + /** + * 学生ID + */ + private Long studentId; + + /** + * 打卡日期 + */ + private Date checkDate; + + /** + * 签到时间 + */ + private Time checkInTime; + + /** + * 签到位置 + */ + private String checkInLocation; + + /** + * 纬度 + */ + private BigDecimal latitude; + + /** + * 经度 + */ + private BigDecimal longitude; + + /** + * 日总结 + */ + private String dailySummary; + + /** + * 图片附件(JSON格式) + */ + private String images; + + /** + * 是否异常(0正常 1异常) + */ + private String isException; + + /** + * 异常原因 + */ + private String exceptionReason; + + /** + * 异常处理状态(0待处理 1已处理) + */ + private String exceptionStatus; + + /** + * 状态(0正常 1停用) + */ + private String status; + +} diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/ZsjyInternshipInfo.java b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/ZsjyInternshipInfo.java new file mode 100644 index 00000000..ab08c3b3 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/ZsjyInternshipInfo.java @@ -0,0 +1,163 @@ +package org.dromara.zsjy.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.mybatis.core.domain.BaseEntity; + +import java.io.Serial; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 实习信息实体对象 zsjy_internship_info + * + * @author system + * @date 2025-01-03 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("zsjy_internship_info") +public class ZsjyInternshipInfo extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 实习信息ID + */ + @TableId(value = "internship_id") + private Long internshipId; + + /** + * 学生ID + */ + private Long studentId; + + /** + * 学号 + */ + private String studentNo; + + /** + * 学生姓名 + */ + private String studentName; + + /** + * 性别 + */ + private String gender; + + /** + * 学院ID + */ + private Long collegeId; + + /** + * 专业ID + */ + private Long majorId; + + /** + * 班级ID + */ + private Long classId; + + /** + * 联系电话 + */ + private String phone; + + /** + * 实习单位名称 + */ + private String companyName; + + /** + * 实习单位地址 + */ + private String companyAddress; + + /** + * 行业类型 + */ + private String companyIndustry; + + /** + * 单位规模 + */ + private String companyScale; + + /** + * 单位联系人 + */ + private String companyContact; + + /** + * 联系人电话 + */ + private String companyPhone; + + /** + * 岗位名称 + */ + private String positionName; + + /** + * 岗位职责 + */ + private String positionDuties; + + /** + * 实习津贴 + */ + private BigDecimal internshipAllowance; + + /** + * 工作时长 + */ + private String workHours; + + /** + * 住宿地址 + */ + private String accommodationAddress; + + /** + * 住宿类型 + */ + private String accommodationType; + + /** + * 住宿费用 + */ + private BigDecimal accommodationCost; + + /** + * 实习开始日期 + */ + private Date startDate; + + /** + * 实习结束日期 + */ + private Date endDate; + + /** + * 实际结束日期 + */ + private Date actualEndDate; + + /** + * 状态(0正常 1停用) + */ + private String status; + + /** + * 实习状态(1进行中 2已完成 3中断) + */ + private String internshipStatus; +} + \ No newline at end of file diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/bo/InternshipInfoAddBO.java b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/bo/InternshipInfoAddBO.java new file mode 100644 index 00000000..752666cd --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/bo/InternshipInfoAddBO.java @@ -0,0 +1,167 @@ +package org.dromara.zsjy.domain.bo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.dromara.common.core.validate.AddGroup; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Positive; +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 实习信息新增业务对象 InternshipInfoAddBO + * + * @author system + * @date 2025-01-03 + */ +@Data +@Schema(description = "实习信息新增业务对象") +public class InternshipInfoAddBO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 学生ID + */ + @Schema(description = "学生ID") + @NotNull(message = "学生ID不能为空", groups = {AddGroup.class}) + private Long studentId; + + /** + * 实习状态:1-进行中,2-已完成,3-已暂停,4-已终止 + */ + @Schema(description = "实习状态:1-进行中,2-已完成,3-已暂停,4-已终止") + @NotBlank(message = "实习状态不能为空", groups = {AddGroup.class}) + @Pattern(regexp = "^[1-4]$", message = "实习状态只能是1-进行中,2-已完成,3-已暂停,4-已终止", groups = {AddGroup.class}) + private String internshipStatus; + + /** + * 实习单位名称 + */ + @Schema(description = "实习单位名称") + @NotBlank(message = "实习单位名称不能为空", groups = {AddGroup.class}) + private String companyName; + + /** + * 实习单位地址 + */ + @Schema(description = "实习单位地址") + private String companyAddress; + + /** + * 单位联系人 + */ + @Schema(description = "单位联系人") + private String companyContact; + + /** + * 联系人电话 + */ + @Schema(description = "联系人电话") + @Pattern(regexp = "^1[3-9]\\d{9}$", message = "联系人电话格式不正确", groups = {AddGroup.class}) + private String companyPhone; + + /** + * 行业类型 + */ + @Schema(description = "行业类型") + private String companyIndustry; + + /** + * 单位规模 + */ + @Schema(description = "单位规模") + private String companyScale; + + /** + * 实习岗位 + */ + @Schema(description = "实习岗位") + @NotBlank(message = "实习岗位不能为空", groups = {AddGroup.class}) + private String internshipPosition; + + /** + * 实习薪资 + */ + @Schema(description = "实习薪资") + @Positive(message = "实习薪资必须大于0", groups = {AddGroup.class}) + private BigDecimal internshipAllowance; + + /** + * 实习开始时间 + */ + @Schema(description = "实习开始时间") + @JsonFormat(pattern = "yyyy-MM-dd") + @NotNull(message = "实习开始时间不能为空", groups = {AddGroup.class}) + private Date internshipStartDate; + + /** + * 实习结束时间 + */ + @Schema(description = "实习结束时间") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date internshipEndDate; + + /** + * 联系人姓名 + */ + @Schema(description = "联系人姓名") + private String contactPersonName; + + /** + * 联系人电话 + */ + @Schema(description = "联系人电话") + @Pattern(regexp = "^1[3-9]\\d{9}$", message = "联系人电话格式不正确", groups = {AddGroup.class}) + private String contactPersonPhone; + + /** + * 岗位职责 + */ + @Schema(description = "岗位职责") + private String positionDuties; + + /** + * 工作时长 + */ + @Schema(description = "工作时长") + private String workHours; + + /** + * 住宿地址 + */ + @Schema(description = "住宿地址") + private String accommodationAddress; + + /** + * 住宿类型 + */ + @Schema(description = "住宿类型") + private String accommodationType; + + /** + * 住宿费用 + */ + @Schema(description = "住宿费用") + private BigDecimal accommodationCost; + + /** + * 实习协议状态:1-已签署,2-未签署 + */ + @Schema(description = "实习协议状态:1-已签署,2-未签署") + @Pattern(regexp = "^[1-2]$", message = "实习协议状态只能是1-已签署,2-未签署", groups = {AddGroup.class}) + private String agreementStatus; + + /** + * 备注信息 + */ + @Schema(description = "备注信息") + private String remark; +} diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/bo/InternshipInfoEditBO.java b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/bo/InternshipInfoEditBO.java new file mode 100644 index 00000000..ca56629d --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/bo/InternshipInfoEditBO.java @@ -0,0 +1,174 @@ +package org.dromara.zsjy.domain.bo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.dromara.common.core.validate.EditGroup; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Positive; +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 实习信息修改业务对象 InternshipInfoEditBO + * + * @author system + * @date 2025-01-03 + */ +@Data +@Schema(description = "实习信息修改业务对象") +public class InternshipInfoEditBO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 实习信息ID + */ + @Schema(description = "实习信息ID") + @NotNull(message = "实习信息ID不能为空", groups = {EditGroup.class}) + private Long internshipId; + + /** + * 学生ID + */ + @Schema(description = "学生ID") + @NotNull(message = "学生ID不能为空", groups = {EditGroup.class}) + private Long studentId; + + /** + * 实习状态:1-进行中,2-已完成,3-已暂停,4-已终止 + */ + @Schema(description = "实习状态:1-进行中,2-已完成,3-已暂停,4-已终止") + @NotBlank(message = "实习状态不能为空", groups = {EditGroup.class}) + @Pattern(regexp = "^[1-4]$", message = "实习状态只能是1-进行中,2-已完成,3-已暂停,4-已终止", groups = {EditGroup.class}) + private String internshipStatus; + + /** + * 实习单位名称 + */ + @Schema(description = "实习单位名称") + @NotBlank(message = "实习单位名称不能为空", groups = {EditGroup.class}) + private String companyName; + + /** + * 实习单位地址 + */ + @Schema(description = "实习单位地址") + private String companyAddress; + + /** + * 单位联系人 + */ + @Schema(description = "单位联系人") + private String companyContact; + + /** + * 联系人电话 + */ + @Schema(description = "联系人电话") + @Pattern(regexp = "^1[3-9]\\d{9}$", message = "联系人电话格式不正确", groups = {EditGroup.class}) + private String companyPhone; + + /** + * 行业类型 + */ + @Schema(description = "行业类型") + private String companyIndustry; + + /** + * 单位规模 + */ + @Schema(description = "单位规模") + private String companyScale; + + /** + * 实习岗位 + */ + @Schema(description = "实习岗位") + @NotBlank(message = "实习岗位不能为空", groups = {EditGroup.class}) + private String internshipPosition; + + /** + * 实习薪资 + */ + @Schema(description = "实习薪资") + @Positive(message = "实习薪资必须大于0", groups = {EditGroup.class}) + private BigDecimal internshipAllowance; + + /** + * 实习开始时间 + */ + @Schema(description = "实习开始时间") + @JsonFormat(pattern = "yyyy-MM-dd") + @NotNull(message = "实习开始时间不能为空", groups = {EditGroup.class}) + private Date internshipStartDate; + + /** + * 实习结束时间 + */ + @Schema(description = "实习结束时间") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date internshipEndDate; + + /** + * 联系人姓名 + */ + @Schema(description = "联系人姓名") + private String contactPersonName; + + /** + * 联系人电话 + */ + @Schema(description = "联系人电话") + @Pattern(regexp = "^1[3-9]\\d{9}$", message = "联系人电话格式不正确", groups = {EditGroup.class}) + private String contactPersonPhone; + + /** + * 岗位职责 + */ + @Schema(description = "岗位职责") + private String positionDuties; + + /** + * 工作时长 + */ + @Schema(description = "工作时长") + private String workHours; + + /** + * 住宿地址 + */ + @Schema(description = "住宿地址") + private String accommodationAddress; + + /** + * 住宿类型 + */ + @Schema(description = "住宿类型") + private String accommodationType; + + /** + * 住宿费用 + */ + @Schema(description = "住宿费用") + private BigDecimal accommodationCost; + + /** + * 实习协议状态:1-已签署,2-未签署 + */ + @Schema(description = "实习协议状态:1-已签署,2-未签署") + @Pattern(regexp = "^[1-2]$", message = "实习协议状态只能是1-已签署,2-未签署", groups = {EditGroup.class}) + private String agreementStatus; + + /** + * 备注信息 + */ + @Schema(description = "备注信息") + private String remark; +} diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/bo/ZsjyInternshipDailyAddBo.java b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/bo/ZsjyInternshipDailyAddBo.java new file mode 100644 index 00000000..49e037d7 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/bo/ZsjyInternshipDailyAddBo.java @@ -0,0 +1,119 @@ +package org.dromara.zsjy.domain.bo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.mybatis.core.domain.BaseEntity; + +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.io.Serial; +import java.math.BigDecimal; +import java.sql.Time; +import java.util.Date; + +/** + * 实习日常管理新增业务对象 ZsjyInternshipDailyAddBo + * + * @author system + * @date 2025-01-03 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Schema(description = "实习日常管理新增业务对象") +public class ZsjyInternshipDailyAddBo extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 实习ID + */ + @Schema(description = "实习ID", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "实习ID不能为空", groups = {AddGroup.class}) + private Long internshipId; + + /** + * 学生ID + */ + @Schema(description = "学生ID", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "学生ID不能为空", groups = {AddGroup.class}) + private Long studentId; + + /** + * 打卡日期 + */ + @Schema(description = "打卡日期", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "打卡日期不能为空", groups = {AddGroup.class}) + private Date checkDate; + + /** + * 签到时间 + */ + @Schema(description = "签到时间") + private Time checkInTime; + + /** + * 签到位置 + */ + @Schema(description = "签到位置") + @Size(max = 200, message = "签到位置长度不能超过200个字符") + private String checkInLocation; + + /** + * 纬度 + */ + @Schema(description = "纬度") + private BigDecimal latitude; + + /** + * 经度 + */ + @Schema(description = "经度") + private BigDecimal longitude; + + /** + * 日总结 + */ + @Schema(description = "日总结") + private String dailySummary; + + /** + * 图片附件(JSON格式) + */ + @Schema(description = "图片附件") + private String images; + + /** + * 是否异常(0正常 1异常) + */ + @Schema(description = "是否异常") + private String isException; + + /** + * 异常原因 + */ + @Schema(description = "异常原因") + @Size(max = 500, message = "异常原因长度不能超过500个字符") + private String exceptionReason; + + /** + * 异常处理状态(0待处理 1已处理) + */ + @Schema(description = "异常处理状态") + private String exceptionStatus; + + /** + * 状态(0正常 1停用) + */ + @Schema(description = "状态") + private String status; + + /** + * 备注 + */ + @Schema(description = "备注") + private String remark; + +} diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/bo/ZsjyInternshipDailyQueryBo.java b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/bo/ZsjyInternshipDailyQueryBo.java new file mode 100644 index 00000000..6f0f040c --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/bo/ZsjyInternshipDailyQueryBo.java @@ -0,0 +1,85 @@ +package org.dromara.zsjy.domain.bo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.mybatis.core.domain.BaseEntity; + +import java.io.Serial; +import java.util.Date; + +/** + * 实习日常管理查询业务对象 ZsjyInternshipDailyQueryBo + * + * @author system + * @date 2025-01-03 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Schema(description = "实习日常管理查询业务对象") +public class ZsjyInternshipDailyQueryBo extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 学生ID + */ + @Schema(description = "学生ID") + private Long studentId; + + /** + * 学号 + */ + @Schema(description = "学号") + private String studentNo; + + /** + * 学生姓名 + */ + @Schema(description = "学生姓名") + private String studentName; + + /** + * 实习ID + */ + @Schema(description = "实习ID") + private Long internshipId; + + /** + * 打卡开始日期 + */ + @Schema(description = "打卡开始日期") + private Date checkDateStart; + + /** + * 打卡结束日期 + */ + @Schema(description = "打卡结束日期") + private Date checkDateEnd; + + /** + * 是否异常(0正常 1异常) + */ + @Schema(description = "是否异常") + private String isException; + + /** + * 异常处理状态(0待处理 1已处理) + */ + @Schema(description = "异常处理状态") + private String exceptionStatus; + + /** + * 状态(0正常 1停用) + */ + @Schema(description = "状态") + private String status; + + /** + * 公司名称 + */ + @Schema(description = "公司名称") + private String companyName; + +} diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/vo/ZsjyInternshipDailyVo.java b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/vo/ZsjyInternshipDailyVo.java new file mode 100644 index 00000000..8f7e4844 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/domain/vo/ZsjyInternshipDailyVo.java @@ -0,0 +1,164 @@ +package org.dromara.zsjy.domain.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; +import java.sql.Time; +import java.util.Date; + +/** + * 实习日常管理视图对象 ZsjyInternshipDailyVo + * + * @author system + * @date 2025-01-03 + */ +@Data +@Schema(description = "实习日常管理视图对象") +public class ZsjyInternshipDailyVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 日常记录ID + */ + @Schema(description = "日常记录ID") + private Long dailyId; + + /** + * 实习ID + */ + @Schema(description = "实习ID") + private Long internshipId; + + /** + * 学生ID + */ + @Schema(description = "学生ID") + private Long studentId; + + /** + * 打卡日期 + */ + @Schema(description = "打卡日期") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date checkDate; + + /** + * 签到时间 + */ + @Schema(description = "签到时间") + @JsonFormat(pattern = "HH:mm:ss") + private Time checkInTime; + + /** + * 签到位置 + */ + @Schema(description = "签到位置") + private String checkInLocation; + + /** + * 纬度 + */ + @Schema(description = "纬度") + private BigDecimal latitude; + + /** + * 经度 + */ + @Schema(description = "经度") + private BigDecimal longitude; + + /** + * 日总结 + */ + @Schema(description = "日总结") + private String dailySummary; + + /** + * 图片附件(JSON格式) + */ + @Schema(description = "图片附件") + private String images; + + /** + * 是否异常(0正常 1异常) + */ + @Schema(description = "是否异常") + private String isException; + + /** + * 异常原因 + */ + @Schema(description = "异常原因") + private String exceptionReason; + + /** + * 异常处理状态(0待处理 1已处理) + */ + @Schema(description = "异常处理状态") + private String exceptionStatus; + + /** + * 状态(0正常 1停用) + */ + @Schema(description = "状态") + private String status; + + /** + * 备注 + */ + @Schema(description = "备注") + private String remark; + + // ============ VO类基础字段规范(强制性) ============ + /** + * 创建者 + */ + @Schema(description = "创建者") + private Long createBy; + + /** + * 创建时间 + */ + @Schema(description = "创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** + * 更新者 + */ + @Schema(description = "更新者") + private Long updateBy; + + /** + * 更新时间 + */ + @Schema(description = "更新时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + // ============ 扩展字段(用于页面显示) ============ + /** + * 学生姓名 + */ + @Schema(description = "学生姓名") + private String studentName; + + /** + * 学号 + */ + @Schema(description = "学号") + private String studentNo; + + /** + * 公司名称 + */ + @Schema(description = "公司名称") + private String companyName; + +} diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/ZsjyInternshipDailyMapper.java b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/ZsjyInternshipDailyMapper.java new file mode 100644 index 00000000..7af7458d --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/ZsjyInternshipDailyMapper.java @@ -0,0 +1,64 @@ +package org.dromara.zsjy.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.dromara.zsjy.domain.ZsjyInternshipDaily; +import org.dromara.zsjy.domain.bo.ZsjyInternshipDailyQueryBo; +import org.dromara.zsjy.domain.vo.ZsjyInternshipDailyVo; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 实习日常管理Mapper接口 + * + * @author system + * @date 2025-01-03 + */ +@Mapper +public interface ZsjyInternshipDailyMapper extends BaseMapper { + + /** + * 查询实习日常记录列表 + * + * @param page 分页参数(可选) + * @param queryBo 查询条件 + * @return 实习日常记录列表 + */ + List selectDailyList(@Param("page") Page page, + @Param("queryBo") ZsjyInternshipDailyQueryBo queryBo); + + /** + * 根据学生ID获取考勤日历数据 + * + * @param studentId 学生ID + * @param startDate 开始日期 + * @param endDate 结束日期 + * @return 考勤日历数据 + */ + List> selectCalendarData(@Param("studentId") Long studentId, + @Param("startDate") Date startDate, + @Param("endDate") Date endDate); + + /** + * 获取考勤统计数据 + * + * @param queryBo 查询条件 + * @return 统计数据 + */ + Map selectStatistics(@Param("queryBo") ZsjyInternshipDailyQueryBo queryBo); + + /** + * 检查学生当日是否已签到 + * + * @param studentId 学生ID + * @param checkDate 打卡日期 + * @return 是否已签到 + */ + boolean existsByStudentAndDate(@Param("studentId") Long studentId, + @Param("checkDate") Date checkDate); + +} diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/ZsjyInternshipInfoMapper.java b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/ZsjyInternshipInfoMapper.java new file mode 100644 index 00000000..f04bce61 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/mapper/ZsjyInternshipInfoMapper.java @@ -0,0 +1,16 @@ +package org.dromara.zsjy.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.dromara.zsjy.domain.ZsjyInternshipInfo; +import org.apache.ibatis.annotations.Mapper; + +/** + * 实习信息Mapper接口 + * + * @author system + * @date 2025-01-03 + */ +@Mapper +public interface ZsjyInternshipInfoMapper extends BaseMapper { + +} diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/service/IZsjyInternshipDailyService.java b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/service/IZsjyInternshipDailyService.java new file mode 100644 index 00000000..a5d0dbed --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/service/IZsjyInternshipDailyService.java @@ -0,0 +1,64 @@ +package org.dromara.zsjy.service; + +import org.dromara.common.core.domain.R; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.zsjy.domain.bo.ZsjyInternshipDailyAddBo; +import org.dromara.zsjy.domain.bo.ZsjyInternshipDailyQueryBo; +import org.dromara.zsjy.domain.vo.ZsjyInternshipDailyVo; + +import java.util.List; +import java.util.Map; + +/** + * 实习日常管理Service接口 + * + * @author system + * @date 2025-01-03 + */ +public interface IZsjyInternshipDailyService { + + /** + * 查询实习日常记录分页列表 + * + * @param queryBo 查询条件 + * @param pageQuery 分页参数 + * @return 实习日常记录分页列表 + */ + TableDataInfo queryPageList(ZsjyInternshipDailyQueryBo queryBo, PageQuery pageQuery); + + /** + * 查询实习日常记录列表(不分页) + * + * @param queryBo 查询条件 + * @return 实习日常记录列表 + */ + List queryList(ZsjyInternshipDailyQueryBo queryBo); + + /** + * 学生签到打卡 + * + * @param addBo 签到信息 + * @return 签到结果 + */ + R checkIn(ZsjyInternshipDailyAddBo addBo); + + /** + * 根据学生ID获取考勤日历数据 + * + * @param studentId 学生ID + * @param year 年份 + * @param month 月份 + * @return 考勤日历数据 + */ + R>> getCalendarData(Long studentId, Integer year, Integer month); + + /** + * 获取考勤统计数据 + * + * @param queryBo 查询条件 + * @return 统计数据 + */ + R> getStatistics(ZsjyInternshipDailyQueryBo queryBo); + +} diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/service/impl/ZsjyInternshipDailyServiceImpl.java b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/service/impl/ZsjyInternshipDailyServiceImpl.java new file mode 100644 index 00000000..20ba3a91 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/java/org/dromara/zsjy/service/impl/ZsjyInternshipDailyServiceImpl.java @@ -0,0 +1,164 @@ +package org.dromara.zsjy.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.exception.ServiceException; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.zsjy.domain.ZsjyInternshipDaily; +import org.dromara.zsjy.domain.bo.ZsjyInternshipDailyAddBo; +import org.dromara.zsjy.domain.bo.ZsjyInternshipDailyQueryBo; +import org.dromara.zsjy.domain.vo.ZsjyInternshipDailyVo; +import org.dromara.zsjy.mapper.ZsjyInternshipDailyMapper; +import org.dromara.zsjy.service.IZsjyInternshipDailyService; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.sql.Time; +import java.time.LocalDateTime; +import java.time.YearMonth; +import java.util.*; + +/** + * 实习日常管理Service业务层处理 + * + * @author system + * @date 2025-01-03 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class ZsjyInternshipDailyServiceImpl implements IZsjyInternshipDailyService { + + private final ZsjyInternshipDailyMapper baseMapper; + + /** + * 查询实习日常记录分页列表 + */ + @Override + public TableDataInfo queryPageList(ZsjyInternshipDailyQueryBo queryBo, PageQuery pageQuery) { + Page page = pageQuery.build(); + List list = baseMapper.selectDailyList(page, queryBo); + return TableDataInfo.build(page); + } + + /** + * 查询实习日常记录列表(不分页) + */ + @Override + public List queryList(ZsjyInternshipDailyQueryBo queryBo) { + return baseMapper.selectDailyList(null, queryBo); + } + + /** + * 学生签到打卡 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public R checkIn(ZsjyInternshipDailyAddBo addBo) { + try { + // 1. 验证学生当日是否已签到 + boolean exists = baseMapper.existsByStudentAndDate(addBo.getStudentId(), addBo.getCheckDate()); + if (exists) { + return R.fail("今日已签到,请勿重复签到"); + } + + // 2. 构建实体对象 + ZsjyInternshipDaily entity = MapstructUtils.convert(addBo, ZsjyInternshipDaily.class); + + // 3. 设置签到时间为当前时间 + if (ObjectUtil.isNull(entity.getCheckInTime())) { + entity.setCheckInTime(Time.valueOf(DateUtil.format(new Date(), "HH:mm:ss"))); + } + + // 4. 设置默认值 + if (ObjectUtil.isNull(entity.getIsException())) { + entity.setIsException("0"); // 默认正常 + } + if (ObjectUtil.isNull(entity.getExceptionStatus())) { + entity.setExceptionStatus("0"); // 默认待处理 + } + if (ObjectUtil.isNull(entity.getStatus())) { + entity.setStatus("0"); // 默认正常 + } + + // 5. 保存签到记录 + boolean result = baseMapper.insert(entity) > 0; + if (!result) { + return R.fail("签到失败,请稍后重试"); + } + + log.info("学生[{}]于{}成功签到", addBo.getStudentId(), addBo.getCheckDate()); + return R.ok("签到成功"); + + } catch (Exception e) { + log.error("学生签到失败: {}", e.getMessage(), e); + throw new ServiceException("签到失败: " + e.getMessage()); + } + } + + /** + * 根据学生ID获取考勤日历数据 + */ + @Override + public R>> getCalendarData(Long studentId, Integer year, Integer month) { + try { + // 1. 参数校验 + if (ObjectUtil.isNull(studentId)) { + return R.fail("学生ID不能为空"); + } + if (ObjectUtil.isNull(year) || ObjectUtil.isNull(month)) { + return R.fail("年份和月份不能为空"); + } + + // 2. 计算日期范围 + YearMonth yearMonth = YearMonth.of(year, month); + Date startDate = DateUtil.beginOfMonth(DateUtil.parse(yearMonth + "-01")); + Date endDate = DateUtil.endOfMonth(startDate); + + // 3. 查询考勤数据 + List> calendarData = baseMapper.selectCalendarData(studentId, startDate, endDate); + + return R.ok(calendarData); + + } catch (Exception e) { + log.error("获取考勤日历数据失败: {}", e.getMessage(), e); + return R.fail("获取考勤日历数据失败: " + e.getMessage()); + } + } + + /** + * 获取考勤统计数据 + */ + @Override + public R> getStatistics(ZsjyInternshipDailyQueryBo queryBo) { + try { + // 1. 查询统计数据 + Map statistics = baseMapper.selectStatistics(queryBo); + + // 2. 补充统计信息 + if (ObjectUtil.isNull(statistics)) { + statistics = new HashMap<>(); + statistics.put("totalDays", 0); + statistics.put("attendanceDays", 0); + statistics.put("exceptionDays", 0); + statistics.put("pendingExceptions", 0); + statistics.put("attendanceRate", 0.0); + } + + return R.ok(statistics); + + } catch (Exception e) { + log.error("获取考勤统计数据失败: {}", e.getMessage(), e); + return R.fail("获取考勤统计数据失败: " + e.getMessage()); + } + } + +} diff --git a/backend/ruoyi-modules/ruoyi-zsjy/src/main/resources/mapper/ZsjyInternshipDailyMapper.xml b/backend/ruoyi-modules/ruoyi-zsjy/src/main/resources/mapper/ZsjyInternshipDailyMapper.xml new file mode 100644 index 00000000..55e10ec7 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-zsjy/src/main/resources/mapper/ZsjyInternshipDailyMapper.xml @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SELECT + d.daily_id, + d.internship_id, + d.student_id, + d.check_date, + d.check_in_time, + d.check_in_location, + d.latitude, + d.longitude, + d.daily_summary, + d.images, + d.is_exception, + d.exception_reason, + d.exception_status, + d.status, + d.remark, + d.create_by, + d.create_time, + d.update_by, + d.update_time, + -- 关联查询扩展字段 + i.student_name, + i.student_no, + i.company_name + FROM zsjy_internship_daily d + LEFT JOIN zsjy_internship_info i ON d.internship_id = i.internship_id + + + + + + + d.deleted = 0 + + AND d.student_id = #{queryBo.studentId} + + + AND i.student_no LIKE CONCAT('%', #{queryBo.studentNo}, '%') + + + AND i.student_name LIKE CONCAT('%', #{queryBo.studentName}, '%') + + + AND d.internship_id = #{queryBo.internshipId} + + + AND d.check_date >= #{queryBo.checkDateStart} + + + AND d.check_date <= #{queryBo.checkDateEnd} + + + AND d.is_exception = #{queryBo.isException} + + + AND d.exception_status = #{queryBo.exceptionStatus} + + + AND d.status = #{queryBo.status} + + + AND i.company_name LIKE CONCAT('%', #{queryBo.companyName}, '%') + + + ORDER BY d.check_date DESC, d.create_time DESC + + + + + SELECT + DATE_FORMAT(check_date, '%Y-%m-%d') as date, + CASE + WHEN check_in_time IS NOT NULL THEN '1' + WHEN is_exception = '1' THEN '2' + ELSE '0' + END as status, + check_in_time, + is_exception, + exception_reason, + daily_summary + FROM zsjy_internship_daily + WHERE student_id = #{studentId} + AND deleted = 0 + + AND check_date >= #{startDate} + + + AND check_date <= #{endDate} + + ORDER BY check_date ASC + + + + + SELECT + COUNT(*) as totalDays, + SUM(CASE WHEN check_in_time IS NOT NULL THEN 1 ELSE 0 END) as attendanceDays, + SUM(CASE WHEN is_exception = '1' THEN 1 ELSE 0 END) as exceptionDays, + SUM(CASE WHEN is_exception = '1' AND exception_status = '0' THEN 1 ELSE 0 END) as pendingExceptions, + ROUND( + SUM(CASE WHEN check_in_time IS NOT NULL THEN 1 ELSE 0 END) * 100.0 / + NULLIF(COUNT(*), 0), 2 + ) as attendanceRate + FROM zsjy_internship_daily d + LEFT JOIN zsjy_internship_info i ON d.internship_id = i.internship_id + + d.deleted = 0 + + AND d.student_id = #{queryBo.studentId} + + + AND d.internship_id = #{queryBo.internshipId} + + + AND d.check_date >= #{queryBo.checkDateStart} + + + AND d.check_date <= #{queryBo.checkDateEnd} + + + AND i.company_name LIKE CONCAT('%', #{queryBo.companyName}, '%') + + + + + + + SELECT COUNT(*) > 0 + FROM zsjy_internship_daily + WHERE student_id = #{studentId} + AND check_date = #{checkDate} + AND deleted = 0 + + + diff --git a/web/src/api/zsjy/internshipDaily.js b/web/src/api/zsjy/internshipDaily.js new file mode 100644 index 00000000..2772d03d --- /dev/null +++ b/web/src/api/zsjy/internshipDaily.js @@ -0,0 +1,46 @@ +import request from '@/utils/request' + +// 查询实习日常记录列表 +export function listInternshipDaily(query) { + return request({ + url: '/zsjy/internship/daily/list', + method: 'get', + params: query + }) +} + +// 学生签到打卡 +export function checkIn(data) { + return request({ + url: '/zsjy/internship/daily/checkin', + method: 'post', + data: data + }) +} + +// 新增实习日常记录 +export function addInternshipDaily(data) { + return request({ + url: '/zsjy/internship/daily', + method: 'post', + data: data + }) +} + +// 获取学生考勤日历 +export function getCalendar(studentId, params) { + return request({ + url: `/zsjy/internship/daily/calendar/${studentId}`, + method: 'get', + params: params + }) +} + +// 获取考勤统计数据 +export function getStatistics(query) { + return request({ + url: '/zsjy/internship/daily/statistics', + method: 'get', + params: query + }) +} diff --git a/web/src/views/zsjy/internship/daily/checkin.vue b/web/src/views/zsjy/internship/daily/checkin.vue new file mode 100644 index 00000000..0c736d48 --- /dev/null +++ b/web/src/views/zsjy/internship/daily/checkin.vue @@ -0,0 +1,695 @@ + + + + + + + + + {{ userInfo.studentName || userInfo.nickName }} + 学号:{{ userInfo.studentNumber || '未设置' }} + 班级:{{ userInfo.className || '未设置' }} + + + + {{ currentTime }} + {{ currentDate }} + + + + + + + + + + + + 签到打卡 + + + + + + + + + + 已签到 + {{ parseTime(todayRecord.checkInTime, '{h}:{i}') }} + + + + + + 未签到 + 请点击下方按钮进行签到 + + + + + + + + + {{ todayRecord.checkInTime ? '已签到' : '立即签到' }} + + + + + + + {{ locationInfo.address }} + + + + + + + + + + + 签退打卡 + + + + + + + + + + 已签退 + {{ parseTime(todayRecord.checkOutTime, '{h}:{i}') }} + + + + + + 未签退 + {{ todayRecord.checkInTime ? '可以进行签退' : '请先签到' }} + + + + + + + + + {{ todayRecord.checkOutTime ? '已签退' : '立即签退' }} + + + + + + + 工作时长:{{ todayRecord.workDuration }}小时 + + + + + + + + + + + + 今日工作内容 + + + + + + + + + + + + + + + 保存工作内容 + + + + + + + + + + + + 最近考勤记录 + + + + + + + + {{ parseTime(scope.row.checkDate, '{m}-{d}') }} + + + + + {{ scope.row.checkInTime ? parseTime(scope.row.checkInTime, '{h}:{i}') : '-' }} + + + + + {{ scope.row.checkOutTime ? parseTime(scope.row.checkOutTime, '{h}:{i}') : '-' }} + + + + + {{ scope.row.workDuration ? scope.row.workDuration + 'h' : '-' }} + + + + + + {{ getStatusText(scope.row.status) }} + + + + + + {{ scope.row.workContent || '-' }} + + + + + + + + + + + diff --git a/web/src/views/zsjy/internship/daily/index.vue b/web/src/views/zsjy/internship/daily/index.vue new file mode 100644 index 00000000..5a132e2b --- /dev/null +++ b/web/src/views/zsjy/internship/daily/index.vue @@ -0,0 +1,899 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 搜索 + 重置 + + + + + + + + + + + + + + + + + + + {{ statistics.totalStudents || 0 }} + 实习学生总数 + + + + + + + + + + + + {{ statistics.todayCheckedIn || 0 }} + 今日已签到 + + + + + + + + + + + + {{ statistics.todayLate || 0 }} + 今日迟到 + + + + + + + + + + + + {{ statistics.attendanceRate || '0%' }} + 本月出勤率 + + + + + + + + + + + 实习日常管理 + + 新增签到 + 搜索 + 导出 + + + + + + + + + + + + + + + {{ scope.row.studentName }} + 学号:{{ scope.row.studentNumber }} + 班级:{{ scope.row.className }} + + + + + + + + + + {{ parseTime(scope.row.checkInTime, '{y}-{m}-{d}') }} + {{ parseTime(scope.row.checkInTime, '{h}:{i}') }} + + 未签到 + + + + + + + {{ parseTime(scope.row.checkOutTime, '{y}-{m}-{d}') }} + {{ parseTime(scope.row.checkOutTime, '{h}:{i}') }} + + 未签退 + + + + + + {{ scope.row.workDuration }}小时 + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{ currentRecord.studentName }} + {{ currentRecord.studentNumber }} + {{ currentRecord.className }} + {{ currentRecord.companyName }} + + {{ currentRecord.checkInTime ? parseTime(currentRecord.checkInTime) : '未签到' }} + + + {{ currentRecord.checkOutTime ? parseTime(currentRecord.checkOutTime) : '未签退' }} + + + {{ currentRecord.workDuration ? currentRecord.workDuration + '小时' : '-' }} + + + + + {{ currentRecord.checkInLocation || '-' }} + + {{ currentRecord.workContent || '-' }} + + + {{ currentRecord.remark || '-' }} + + + + + + + + + + + + + {{ currentStudent.studentName }}({{ currentStudent.studentNumber }})的考勤记录 + + + + + + {{ data.day.split('-').slice(2).join('') }} + + + {{ getStatusText(getAttendanceStatus(data.day)) }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/src/views/zsjy/internship/msgmanage/components/AddDialog.vue b/web/src/views/zsjy/internship/msgmanage/components/AddDialog.vue new file mode 100644 index 00000000..fa6cbe23 --- /dev/null +++ b/web/src/views/zsjy/internship/msgmanage/components/AddDialog.vue @@ -0,0 +1,366 @@ + + + + + + + 基本信息 + + + + + + + + + + + + + + + + + + + + + + + + + + + 实习单位信息 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 岗位信息 + + + + + + + + + + + + + + + + + + + + 实习周期 + + + + + + + + + + + + + + + 联系方式和其他信息 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 取消 + 保存 + + + + + + + + + \ No newline at end of file diff --git a/web/src/views/zsjy/internship/msgmanage/components/EditDialog.vue b/web/src/views/zsjy/internship/msgmanage/components/EditDialog.vue new file mode 100644 index 00000000..ed0071c3 --- /dev/null +++ b/web/src/views/zsjy/internship/msgmanage/components/EditDialog.vue @@ -0,0 +1,437 @@ + + + + + + + 基本信息 + + + + + + + + + + + + + + + + + + + + + + + + + + + 实习单位信息 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 岗位信息 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 实习时间信息 + + + + + + + + + + + + + + + + + + + + + + + + + 联系方式和其他信息 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 取消 + 保存 + 删除 + + + + + + + + + \ No newline at end of file
学号:{{ userInfo.studentNumber || '未设置' }}
班级:{{ userInfo.className || '未设置' }}
{{ parseTime(todayRecord.checkInTime, '{h}:{i}') }}
请点击下方按钮进行签到
{{ parseTime(todayRecord.checkOutTime, '{h}:{i}') }}
{{ todayRecord.checkInTime ? '可以进行签退' : '请先签到' }}