From 2e51d1154d50ef83c39d9f5cdc2875d18db7bdea Mon Sep 17 00:00:00 2001 From: zlwu <704541015@qq.com> Date: Mon, 4 Aug 2025 13:09:12 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/XgStudentLeaveController.java | 105 ++ .../workflow/domain/XgStudentLeave.java | 193 +++ .../workflow/domain/bo/XgStudentLeaveBo.java | 204 +++ .../workflow/domain/vo/XgStudentLeaveVo.java | 236 +++ .../workflow/mapper/XgStudentLeaveMapper.java | 15 + .../service/IXgStudentLeaveService.java | 68 + .../impl/XgStudentLeaveServiceImpl.java | 163 ++ .../studentLeave/XgStudentLeaveMapper.xml | 7 + .../XgLeaveTypeConfigController.java | 105 ++ .../xg/controller/XgStudentMsgController.java | 22 + .../dromara/xg/domain/XgLeaveTypeConfig.java | 96 ++ .../xg/domain/bo/XgLeaveTypeConfigBo.java | 103 ++ .../xg/domain/vo/XgLeaveTypeConfigVo.java | 119 ++ .../xg/mapper/XgLeaveTypeConfigMapper.java | 15 + .../xg/service/IXgLeaveTypeConfigService.java | 68 + .../xg/service/IXgStudentMsgService.java | 8 + .../impl/XgLeaveTypeConfigServiceImpl.java | 138 ++ .../service/impl/XgStudentMsgServiceImpl.java | 14 + .../XgLeaveTypeConfigMapper.xml | 7 + .../code-adjust-record-2025-01-20-wuzilong.md | 90 + .../code-adjust-record-2025-01-27-cursor.md | 1456 ++++++++++++++++ ...d-2025-01-27-xgLeaveTypeConfig-dict-fix.md | 99 ++ docs/设计文档/database/学生请假/README.md | 173 ++ .../学生请假/xg_leave_type_config.sql | 48 + .../database/学生请假/xg_student_leave.sql | 101 ++ .../学生请假/xg_student_leave_sample_data.sql | 91 + .../studentLeave/studentLeave/index.ts | 63 + .../studentLeave/studentLeave/types.ts | 511 ++++++ .../xgLeaveTypeConfig/index.ts | 63 + .../xgLeaveTypeConfig/types.ts | 166 ++ web/src/components/Process/approvalButton.vue | 4 +- web/src/views/hq/pm/repairOrder/index.vue | 40 +- .../xgLeaveTypeConfig/index.vue | 375 ++++ web/src/views/xg/xsjcxx/xsqj/dialog.vue | 1506 +++++++++++++++++ web/src/views/xg/xsjcxx/xsqj/index-bak.vue | 236 +++ web/src/views/xg/xsjcxx/xsqj/index.vue | 543 ++++-- .../views/xg/xsjcxx/xsqj/leaveEdit-bak.vue | 314 ++++ 37 files changed, 7428 insertions(+), 137 deletions(-) create mode 100644 backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/XgStudentLeaveController.java create mode 100644 backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/XgStudentLeave.java create mode 100644 backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/XgStudentLeaveBo.java create mode 100644 backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/XgStudentLeaveVo.java create mode 100644 backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/XgStudentLeaveMapper.java create mode 100644 backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IXgStudentLeaveService.java create mode 100644 backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/XgStudentLeaveServiceImpl.java create mode 100644 backend/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/studentLeave/XgStudentLeaveMapper.xml create mode 100644 backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgLeaveTypeConfigController.java create mode 100644 backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgLeaveTypeConfig.java create mode 100644 backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/bo/XgLeaveTypeConfigBo.java create mode 100644 backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgLeaveTypeConfigVo.java create mode 100644 backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgLeaveTypeConfigMapper.java create mode 100644 backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgLeaveTypeConfigService.java create mode 100644 backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgLeaveTypeConfigServiceImpl.java create mode 100644 backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xgLeaveTypeConfig/XgLeaveTypeConfigMapper.xml create mode 100644 docs/变更管理/code-adjust-record-2025-01-20-wuzilong.md create mode 100644 docs/变更管理/code-adjust-record-2025-01-27-xgLeaveTypeConfig-dict-fix.md create mode 100644 docs/设计文档/database/学生请假/README.md create mode 100644 docs/设计文档/database/学生请假/xg_leave_type_config.sql create mode 100644 docs/设计文档/database/学生请假/xg_student_leave.sql create mode 100644 docs/设计文档/database/学生请假/xg_student_leave_sample_data.sql create mode 100644 web/src/api/workflow/studentLeave/studentLeave/index.ts create mode 100644 web/src/api/workflow/studentLeave/studentLeave/types.ts create mode 100644 web/src/api/xg/xsjcxx/xgLeaveTypeConfig/xgLeaveTypeConfig/index.ts create mode 100644 web/src/api/xg/xsjcxx/xgLeaveTypeConfig/xgLeaveTypeConfig/types.ts create mode 100644 web/src/views/xg/xsjcxx/xgLeaveTypeConfig/xgLeaveTypeConfig/index.vue create mode 100644 web/src/views/xg/xsjcxx/xsqj/dialog.vue create mode 100644 web/src/views/xg/xsjcxx/xsqj/index-bak.vue create mode 100644 web/src/views/xg/xsjcxx/xsqj/leaveEdit-bak.vue diff --git a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/XgStudentLeaveController.java b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/XgStudentLeaveController.java new file mode 100644 index 00000000..75a495c2 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/XgStudentLeaveController.java @@ -0,0 +1,105 @@ +package org.dromara.workflow.controller; + +import java.util.List; + +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.web.core.BaseController; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.workflow.domain.vo.XgStudentLeaveVo; +import org.dromara.workflow.domain.bo.XgStudentLeaveBo; +import org.dromara.workflow.service.IXgStudentLeaveService; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +/** + * 学生请假 - 记录学生的请假申请、审批和销假信息 + * + * @author zlwu + * @date 2025-08-03 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/studentLeave/studentLeave") +public class XgStudentLeaveController extends BaseController { + + private final IXgStudentLeaveService xgStudentLeaveService; + + /** + * 查询学生请假 - 记录学生的请假申请、审批和销假信息列表 + */ + @SaCheckPermission("studentLeave:studentLeave:list") + @GetMapping("/list") + public TableDataInfo list(XgStudentLeaveBo bo, PageQuery pageQuery) { + return xgStudentLeaveService.queryPageList(bo, pageQuery); + } + + /** + * 导出学生请假 - 记录学生的请假申请、审批和销假信息列表 + */ + @SaCheckPermission("studentLeave:studentLeave:export") + @Log(title = "学生请假 - 记录学生的请假申请、审批和销假信息", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(XgStudentLeaveBo bo, HttpServletResponse response) { + List list = xgStudentLeaveService.queryList(bo); + ExcelUtil.exportExcel(list, "学生请假 - 记录学生的请假申请、审批和销假信息", XgStudentLeaveVo.class, response); + } + + /** + * 获取学生请假 - 记录学生的请假申请、审批和销假信息详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("studentLeave:studentLeave:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(xgStudentLeaveService.queryById(id)); + } + + /** + * 新增学生请假 - 记录学生的请假申请、审批和销假信息 + */ + @SaCheckPermission("studentLeave:studentLeave:add") + @Log(title = "学生请假 - 记录学生的请假申请、审批和销假信息", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody XgStudentLeaveBo bo) { + return toAjax(xgStudentLeaveService.insertByBo(bo)); + } + + /** + * 修改学生请假 - 记录学生的请假申请、审批和销假信息 + */ + @SaCheckPermission("studentLeave:studentLeave:edit") + @Log(title = "学生请假 - 记录学生的请假申请、审批和销假信息", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody XgStudentLeaveBo bo) { + return toAjax(xgStudentLeaveService.updateByBo(bo)); + } + + /** + * 删除学生请假 - 记录学生的请假申请、审批和销假信息 + * + * @param ids 主键串 + */ + @SaCheckPermission("studentLeave:studentLeave:remove") + @Log(title = "学生请假 - 记录学生的请假申请、审批和销假信息", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(xgStudentLeaveService.deleteWithValidByIds(List.of(ids), true)); + } +} diff --git a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/XgStudentLeave.java b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/XgStudentLeave.java new file mode 100644 index 00000000..464fe842 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/XgStudentLeave.java @@ -0,0 +1,193 @@ +package org.dromara.workflow.domain; + +import org.dromara.common.tenant.core.TenantEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.io.Serial; + +/** + * 学生请假 - 记录学生的请假申请、审批和销假信息对象 xg_student_leave + * + * @author zlwu + * @date 2025-08-03 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("xg_student_leave") +public class XgStudentLeave extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID(雪花ID) + */ + @TableId(value = "id") + private Long id; + + /** + * 删除标志(0代表存在 1代表删除) + */ + @TableLogic(value = "0", delval = "1") + private Long deleted; + + /** + * 学生ID + */ + private Long studentId; + + /** + * 学生姓名 + */ + private String studentName; + + /** + * 学号 + */ + private String studentNo; + + /** + * 班级ID + */ + private Long classId; + + /** + * 班级名称 + */ + private String className; + + /** + * 专业ID + */ + private Long majorId; + + /** + * 专业名称 + */ + private String majorName; + + /** + * 学院ID + */ + private Long collegeId; + + /** + * 学院名称 + */ + private String collegeName; + + /** + * 请假类型编码 + */ + private String leaveTypeCode; + + /** + * 请假类型名称 + */ + private String leaveTypeName; + + /** + * 开始时间(年月日时分秒) + */ + private Date startTime; + + /** + * 结束时间(年月日时分秒) + */ + private Date endTime; + + /** + * 请假时长(天) + */ + private Double leaveDuration; + + /** + * 是否离校:0-否,1-是 + */ + private String isLeaveSchool; + + /** + * 是否需要销假:0-否,1-是 + */ + private String needCancel; + + /** + * 紧急联系人 + */ + private String emergencyContact; + + /** + * 紧急联系电话 + */ + private String emergencyPhone; + + /** + * 请假原因 + */ + private String leaveReason; + + /** + * 请假时地理位置 + */ + private String leaveLocation; + + /** + * 附件OSS文件ID(逗号分隔) + */ + private String attachmentOssIds; + + /** + * 审批状态:0-待审批,1-已通过,2-已拒绝,3-已取消 + */ + private String approvalStatus; + + /** + * 审批意见 + */ + private String approvalOpinion; + + /** + * 审批时间 + */ + private Date approvalTime; + + /** + * 审批人ID + */ + private Long approvalBy; + + /** + * 审批人姓名 + */ + private String approvalByName; + + /** + * 销假状态:0-未销假,1-已销假,2-逾期未销假 + */ + private String cancelStatus; + + /** + * 销假时间 + */ + private Date cancelTime; + + /** + * 销假地理位置 + */ + private String cancelLocation; + + /** + * 销假照片OSS文件ID(逗号分隔) + */ + private String cancelPhotoOssIds; + + /** + * 销假备注 + */ + private String cancelRemark; + +} diff --git a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/XgStudentLeaveBo.java b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/XgStudentLeaveBo.java new file mode 100644 index 00000000..c41e3aec --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/XgStudentLeaveBo.java @@ -0,0 +1,204 @@ +package org.dromara.workflow.domain.bo; + +import org.dromara.workflow.domain.XgStudentLeave; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +/** + * 学生请假 - 记录学生的请假申请、审批和销假信息业务对象 xg_student_leave + * + * @author zlwu + * @date 2025-08-03 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = XgStudentLeave.class, reverseConvertGenerate = false) +public class XgStudentLeaveBo extends BaseEntity { + + /** + * 主键ID(雪花ID) + */ + @NotNull(message = "主键ID(雪花ID)不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 删除标志(0代表存在 1代表删除) + */ + private Long deleted; + + /** + * 学生ID + */ + @NotNull(message = "学生ID不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long studentId; + + /** + * 学生姓名 + */ + @NotBlank(message = "学生姓名不能为空", groups = { AddGroup.class, EditGroup.class }) + private String studentName; + + /** + * 学号 + */ + @NotBlank(message = "学号不能为空", groups = { AddGroup.class, EditGroup.class }) + private String studentNo; + + /** + * 班级ID + */ + private Long classId; + + /** + * 班级名称 + */ + private String className; + + /** + * 专业ID + */ + private Long majorId; + + /** + * 专业名称 + */ + private String majorName; + + /** + * 学院ID + */ + private Long collegeId; + + /** + * 学院名称 + */ + private String collegeName; + + /** + * 请假类型编码 + */ + @NotBlank(message = "请假类型编码不能为空", groups = { AddGroup.class, EditGroup.class }) + private String leaveTypeCode; + + /** + * 请假类型名称 + */ + @NotBlank(message = "请假类型名称不能为空", groups = { AddGroup.class, EditGroup.class }) + private String leaveTypeName; + + /** + * 开始时间(年月日时分秒) + */ + @NotNull(message = "开始时间(年月日时分秒)不能为空", groups = { AddGroup.class, EditGroup.class }) + private Date startTime; + + /** + * 结束时间(年月日时分秒) + */ + @NotNull(message = "结束时间(年月日时分秒)不能为空", groups = { AddGroup.class, EditGroup.class }) + private Date endTime; + + /** + * 请假时长(天) + */ + @NotNull(message = "请假时长(天)不能为空", groups = { AddGroup.class, EditGroup.class }) + private Double leaveDuration; + + /** + * 是否离校:0-否,1-是 + */ + @NotBlank(message = "是否离校:0-否,1-是不能为空", groups = { AddGroup.class, EditGroup.class }) + private String isLeaveSchool; + + /** + * 是否需要销假:0-否,1-是 + */ + @NotBlank(message = "是否需要销假:0-否,1-是不能为空", groups = { AddGroup.class, EditGroup.class }) + private String needCancel; + + /** + * 紧急联系人 + */ + private String emergencyContact; + + /** + * 紧急联系电话 + */ + private String emergencyPhone; + + /** + * 请假原因 + */ + @NotBlank(message = "请假原因不能为空", groups = { AddGroup.class, EditGroup.class }) + private String leaveReason; + + /** + * 请假时地理位置 + */ + private String leaveLocation; + + /** + * 附件OSS文件ID(逗号分隔) + */ + private String attachmentOssIds; + + /** + * 审批状态 + */ + @NotBlank(message = "审批状态不能为空", groups = { AddGroup.class, EditGroup.class }) + private String approvalStatus; + + /** + * 审批意见 + */ + private String approvalOpinion; + + /** + * 审批时间 + */ + private Date approvalTime; + + /** + * 审批人ID + */ + private Long approvalBy; + + /** + * 审批人姓名 + */ + private String approvalByName; + + /** + * 销假状态:0-未销假,1-已销假,2-逾期未销假 3-无需销假 + */ + @NotBlank(message = "销假状态:0-未销假,1-已销假,2-逾期未销假 3-无需销假 不能为空", groups = { AddGroup.class, EditGroup.class }) + private String cancelStatus; + + /** + * 销假时间 + */ + private Date cancelTime; + + /** + * 销假地理位置 + */ + private String cancelLocation; + + /** + * 销假照片OSS文件ID(逗号分隔) + */ + private String cancelPhotoOssIds; + + /** + * 销假备注 + */ + private String cancelRemark; + +} diff --git a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/XgStudentLeaveVo.java b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/XgStudentLeaveVo.java new file mode 100644 index 00000000..d51f783a --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/XgStudentLeaveVo.java @@ -0,0 +1,236 @@ +package org.dromara.workflow.domain.vo; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.dromara.workflow.domain.XgStudentLeave; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +/** + * 学生请假 - 记录学生的请假申请、审批和销假信息视图对象 xg_student_leave + * + * @author zlwu + * @date 2025-08-03 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = XgStudentLeave.class) +public class XgStudentLeaveVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID(雪花ID) + */ + @ExcelProperty(value = "主键ID", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "雪=花ID") + private Long id; + + /** + * 删除标志(0代表存在 1代表删除) + */ + @ExcelProperty(value = "删除标志", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "0=代表存在,1=代表删除") + private Long deleted; + + /** + * 学生ID + */ + @ExcelProperty(value = "学生ID") + private Long studentId; + + /** + * 学生姓名 + */ + @ExcelProperty(value = "学生姓名") + private String studentName; + + /** + * 学号 + */ + @ExcelProperty(value = "学号") + private String studentNo; + + /** + * 班级ID + */ + @ExcelProperty(value = "班级ID") + private Long classId; + + /** + * 班级名称 + */ + @ExcelProperty(value = "班级名称") + private String className; + + /** + * 专业ID + */ + @ExcelProperty(value = "专业ID") + private Long majorId; + + /** + * 专业名称 + */ + @ExcelProperty(value = "专业名称") + private String majorName; + + /** + * 学院ID + */ + @ExcelProperty(value = "学院ID") + private Long collegeId; + + /** + * 学院名称 + */ + @ExcelProperty(value = "学院名称") + private String collegeName; + + /** + * 请假类型编码 + */ + @ExcelProperty(value = "请假类型编码") + private String leaveTypeCode; + + /** + * 请假类型名称 + */ + @ExcelProperty(value = "请假类型名称") + private String leaveTypeName; + + /** + * 开始时间(年月日时分秒) + */ + @ExcelProperty(value = "开始时间", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "年=月日时分秒") + private Date startTime; + + /** + * 结束时间(年月日时分秒) + */ + @ExcelProperty(value = "结束时间", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "年=月日时分秒") + private Date endTime; + + /** + * 请假时长(天) + */ + @ExcelProperty(value = "请假时长", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "天=") + private Double leaveDuration; + + /** + * 是否离校:0-否,1-是 + */ + @ExcelProperty(value = "是否离校:0-否,1-是") + private String isLeaveSchool; + + /** + * 是否需要销假:0-否,1-是 + */ + @ExcelProperty(value = "是否需要销假:0-否,1-是") + private String needCancel; + + /** + * 紧急联系人 + */ + @ExcelProperty(value = "紧急联系人") + private String emergencyContact; + + /** + * 紧急联系电话 + */ + @ExcelProperty(value = "紧急联系电话") + private String emergencyPhone; + + /** + * 请假原因 + */ + @ExcelProperty(value = "请假原因") + private String leaveReason; + + /** + * 请假时地理位置 + */ + @ExcelProperty(value = "请假时地理位置") + private String leaveLocation; + + /** + * 附件OSS文件ID(逗号分隔) + */ + @ExcelProperty(value = "附件OSS文件ID", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "逗=号分隔") + private String attachmentOssIds; + + /** + * 审批状态 + */ + @ExcelProperty(value = "审批状态") + private String approvalStatus; + + /** + * 审批意见 + */ + @ExcelProperty(value = "审批意见") + private String approvalOpinion; + + /** + * 审批时间 + */ + @ExcelProperty(value = "审批时间") + private Date approvalTime; + + /** + * 审批人ID + */ + @ExcelProperty(value = "审批人ID") + private Long approvalBy; + + /** + * 审批人姓名 + */ + @ExcelProperty(value = "审批人姓名") + private String approvalByName; + + /** + * 销假状态:0-未销假,1-已销假,2-逾期未销假 3 - 无需销假 + */ + @ExcelProperty(value = "销假状态:0-未销假,1-已销假,2-逾期未销假 3 - 无需销假") + private String cancelStatus; + + /** + * 销假时间 + */ + @ExcelProperty(value = "销假时间") + private Date cancelTime; + + /** + * 销假地理位置 + */ + @ExcelProperty(value = "销假地理位置") + private String cancelLocation; + + /** + * 销假照片OSS文件ID(逗号分隔) + */ + @ExcelProperty(value = "销假照片OSS文件ID", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "逗=号分隔") + private String cancelPhotoOssIds; + + /** + * 销假备注 + */ + @ExcelProperty(value = "销假备注") + private String cancelRemark; + +} diff --git a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/XgStudentLeaveMapper.java b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/XgStudentLeaveMapper.java new file mode 100644 index 00000000..e22919d7 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/XgStudentLeaveMapper.java @@ -0,0 +1,15 @@ +package org.dromara.workflow.mapper; + +import org.dromara.workflow.domain.XgStudentLeave; +import org.dromara.workflow.domain.vo.XgStudentLeaveVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 学生请假 - 记录学生的请假申请、审批和销假信息Mapper接口 + * + * @author zlwu + * @date 2025-08-03 + */ +public interface XgStudentLeaveMapper extends BaseMapperPlus { + +} diff --git a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IXgStudentLeaveService.java b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IXgStudentLeaveService.java new file mode 100644 index 00000000..2ca51f87 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IXgStudentLeaveService.java @@ -0,0 +1,68 @@ +package org.dromara.workflow.service; + +import org.dromara.workflow.domain.vo.XgStudentLeaveVo; +import org.dromara.workflow.domain.bo.XgStudentLeaveBo; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 学生请假 - 记录学生的请假申请、审批和销假信息Service接口 + * + * @author zlwu + * @date 2025-08-03 + */ +public interface IXgStudentLeaveService { + + /** + * 查询学生请假 - 记录学生的请假申请、审批和销假信息 + * + * @param id 主键 + * @return 学生请假 - 记录学生的请假申请、审批和销假信息 + */ + XgStudentLeaveVo queryById(Long id); + + /** + * 分页查询学生请假 - 记录学生的请假申请、审批和销假信息列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 学生请假 - 记录学生的请假申请、审批和销假信息分页列表 + */ + TableDataInfo queryPageList(XgStudentLeaveBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的学生请假 - 记录学生的请假申请、审批和销假信息列表 + * + * @param bo 查询条件 + * @return 学生请假 - 记录学生的请假申请、审批和销假信息列表 + */ + List queryList(XgStudentLeaveBo bo); + + /** + * 新增学生请假 - 记录学生的请假申请、审批和销假信息 + * + * @param bo 学生请假 - 记录学生的请假申请、审批和销假信息 + * @return 是否新增成功 + */ + Boolean insertByBo(XgStudentLeaveBo bo); + + /** + * 修改学生请假 - 记录学生的请假申请、审批和销假信息 + * + * @param bo 学生请假 - 记录学生的请假申请、审批和销假信息 + * @return 是否修改成功 + */ + Boolean updateByBo(XgStudentLeaveBo bo); + + /** + * 校验并批量删除学生请假 - 记录学生的请假申请、审批和销假信息信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/XgStudentLeaveServiceImpl.java b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/XgStudentLeaveServiceImpl.java new file mode 100644 index 00000000..d39937ab --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/XgStudentLeaveServiceImpl.java @@ -0,0 +1,163 @@ +package org.dromara.workflow.service.impl; + +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.dromara.workflow.domain.bo.XgStudentLeaveBo; +import org.dromara.workflow.domain.vo.XgStudentLeaveVo; +import org.dromara.workflow.domain.XgStudentLeave; +import org.dromara.workflow.mapper.XgStudentLeaveMapper; +import org.dromara.workflow.service.IXgStudentLeaveService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 学生请假 - 记录学生的请假申请、审批和销假信息Service业务层处理 + * + * @author zlwu + * @date 2025-08-03 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class XgStudentLeaveServiceImpl implements IXgStudentLeaveService { + + private final XgStudentLeaveMapper baseMapper; + + /** + * 查询学生请假 - 记录学生的请假申请、审批和销假信息 + * + * @param id 主键 + * @return 学生请假 - 记录学生的请假申请、审批和销假信息 + */ + @Override + public XgStudentLeaveVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + /** + * 分页查询学生请假 - 记录学生的请假申请、审批和销假信息列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 学生请假 - 记录学生的请假申请、审批和销假信息分页列表 + */ + @Override + public TableDataInfo queryPageList(XgStudentLeaveBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的学生请假 - 记录学生的请假申请、审批和销假信息列表 + * + * @param bo 查询条件 + * @return 学生请假 - 记录学生的请假申请、审批和销假信息列表 + */ + @Override + public List queryList(XgStudentLeaveBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(XgStudentLeaveBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.orderByAsc(XgStudentLeave::getId); + lqw.eq(bo.getDeleted() != null, XgStudentLeave::getDeleted, bo.getDeleted()); + lqw.eq(bo.getStudentId() != null, XgStudentLeave::getStudentId, bo.getStudentId()); + lqw.like(StringUtils.isNotBlank(bo.getStudentName()), XgStudentLeave::getStudentName, bo.getStudentName()); + lqw.eq(StringUtils.isNotBlank(bo.getStudentNo()), XgStudentLeave::getStudentNo, bo.getStudentNo()); + lqw.eq(bo.getClassId() != null, XgStudentLeave::getClassId, bo.getClassId()); + lqw.like(StringUtils.isNotBlank(bo.getClassName()), XgStudentLeave::getClassName, bo.getClassName()); + lqw.eq(bo.getMajorId() != null, XgStudentLeave::getMajorId, bo.getMajorId()); + lqw.like(StringUtils.isNotBlank(bo.getMajorName()), XgStudentLeave::getMajorName, bo.getMajorName()); + lqw.eq(bo.getCollegeId() != null, XgStudentLeave::getCollegeId, bo.getCollegeId()); + lqw.like(StringUtils.isNotBlank(bo.getCollegeName()), XgStudentLeave::getCollegeName, bo.getCollegeName()); + lqw.eq(StringUtils.isNotBlank(bo.getLeaveTypeCode()), XgStudentLeave::getLeaveTypeCode, bo.getLeaveTypeCode()); + lqw.like(StringUtils.isNotBlank(bo.getLeaveTypeName()), XgStudentLeave::getLeaveTypeName, bo.getLeaveTypeName()); + lqw.eq(bo.getStartTime() != null, XgStudentLeave::getStartTime, bo.getStartTime()); + lqw.eq(bo.getEndTime() != null, XgStudentLeave::getEndTime, bo.getEndTime()); + lqw.eq(bo.getLeaveDuration() != null, XgStudentLeave::getLeaveDuration, bo.getLeaveDuration()); + lqw.eq(StringUtils.isNotBlank(bo.getIsLeaveSchool()), XgStudentLeave::getIsLeaveSchool, bo.getIsLeaveSchool()); + lqw.eq(StringUtils.isNotBlank(bo.getNeedCancel()), XgStudentLeave::getNeedCancel, bo.getNeedCancel()); + lqw.eq(StringUtils.isNotBlank(bo.getEmergencyContact()), XgStudentLeave::getEmergencyContact, bo.getEmergencyContact()); + lqw.eq(StringUtils.isNotBlank(bo.getEmergencyPhone()), XgStudentLeave::getEmergencyPhone, bo.getEmergencyPhone()); + lqw.eq(StringUtils.isNotBlank(bo.getLeaveReason()), XgStudentLeave::getLeaveReason, bo.getLeaveReason()); + lqw.eq(StringUtils.isNotBlank(bo.getLeaveLocation()), XgStudentLeave::getLeaveLocation, bo.getLeaveLocation()); + lqw.eq(StringUtils.isNotBlank(bo.getAttachmentOssIds()), XgStudentLeave::getAttachmentOssIds, bo.getAttachmentOssIds()); + lqw.eq(StringUtils.isNotBlank(bo.getApprovalStatus()), XgStudentLeave::getApprovalStatus, bo.getApprovalStatus()); + lqw.eq(StringUtils.isNotBlank(bo.getApprovalOpinion()), XgStudentLeave::getApprovalOpinion, bo.getApprovalOpinion()); + lqw.eq(bo.getApprovalTime() != null, XgStudentLeave::getApprovalTime, bo.getApprovalTime()); + lqw.eq(bo.getApprovalBy() != null, XgStudentLeave::getApprovalBy, bo.getApprovalBy()); + lqw.like(StringUtils.isNotBlank(bo.getApprovalByName()), XgStudentLeave::getApprovalByName, bo.getApprovalByName()); + lqw.eq(StringUtils.isNotBlank(bo.getCancelStatus()), XgStudentLeave::getCancelStatus, bo.getCancelStatus()); + lqw.eq(bo.getCancelTime() != null, XgStudentLeave::getCancelTime, bo.getCancelTime()); + lqw.eq(StringUtils.isNotBlank(bo.getCancelLocation()), XgStudentLeave::getCancelLocation, bo.getCancelLocation()); + lqw.eq(StringUtils.isNotBlank(bo.getCancelPhotoOssIds()), XgStudentLeave::getCancelPhotoOssIds, bo.getCancelPhotoOssIds()); + lqw.eq(StringUtils.isNotBlank(bo.getCancelRemark()), XgStudentLeave::getCancelRemark, bo.getCancelRemark()); + return lqw; + } + + /** + * 新增学生请假 - 记录学生的请假申请、审批和销假信息 + * + * @param bo 学生请假 - 记录学生的请假申请、审批和销假信息 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(XgStudentLeaveBo bo) { + XgStudentLeave add = MapstructUtils.convert(bo, XgStudentLeave.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改学生请假 - 记录学生的请假申请、审批和销假信息 + * + * @param bo 学生请假 - 记录学生的请假申请、审批和销假信息 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(XgStudentLeaveBo bo) { + XgStudentLeave update = MapstructUtils.convert(bo, XgStudentLeave.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(XgStudentLeave entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除学生请假 - 记录学生的请假申请、审批和销假信息信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/backend/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/studentLeave/XgStudentLeaveMapper.xml b/backend/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/studentLeave/XgStudentLeaveMapper.xml new file mode 100644 index 00000000..b9ca4c58 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/studentLeave/XgStudentLeaveMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgLeaveTypeConfigController.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgLeaveTypeConfigController.java new file mode 100644 index 00000000..5c096a7c --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgLeaveTypeConfigController.java @@ -0,0 +1,105 @@ +package org.dromara.xg.controller; + +import java.util.List; + +import lombok.RequiredArgsConstructor; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.*; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import org.dromara.common.idempotent.annotation.RepeatSubmit; +import org.dromara.common.log.annotation.Log; +import org.dromara.common.web.core.BaseController; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.core.domain.R; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.log.enums.BusinessType; +import org.dromara.common.excel.utils.ExcelUtil; +import org.dromara.xg.domain.vo.XgLeaveTypeConfigVo; +import org.dromara.xg.domain.bo.XgLeaveTypeConfigBo; +import org.dromara.xg.service.IXgLeaveTypeConfigService; +import org.dromara.common.mybatis.core.page.TableDataInfo; + +/** + * 学生请假类型配置 + * + * @author zlwu + * @date 2025-08-03 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/xgLeaveTypeConfig/xgLeaveTypeConfig") +public class XgLeaveTypeConfigController extends BaseController { + + private final IXgLeaveTypeConfigService xgLeaveTypeConfigService; + + /** + * 查询学生请假类型配置列表 + */ + @SaCheckPermission("xgLeaveTypeConfig:xgLeaveTypeConfig:list") + @GetMapping("/list") + public TableDataInfo list(XgLeaveTypeConfigBo bo, PageQuery pageQuery) { + return xgLeaveTypeConfigService.queryPageList(bo, pageQuery); + } + + /** + * 导出学生请假类型配置列表 + */ + @SaCheckPermission("xgLeaveTypeConfig:xgLeaveTypeConfig:export") + @Log(title = "学生请假类型配置", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(XgLeaveTypeConfigBo bo, HttpServletResponse response) { + List list = xgLeaveTypeConfigService.queryList(bo); + ExcelUtil.exportExcel(list, "学生请假类型配置", XgLeaveTypeConfigVo.class, response); + } + + /** + * 获取学生请假类型配置详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("xgLeaveTypeConfig:xgLeaveTypeConfig:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(xgLeaveTypeConfigService.queryById(id)); + } + + /** + * 新增学生请假类型配置 + */ + @SaCheckPermission("xgLeaveTypeConfig:xgLeaveTypeConfig:add") + @Log(title = "学生请假类型配置", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody XgLeaveTypeConfigBo bo) { + return toAjax(xgLeaveTypeConfigService.insertByBo(bo)); + } + + /** + * 修改学生请假类型配置 + */ + @SaCheckPermission("xgLeaveTypeConfig:xgLeaveTypeConfig:edit") + @Log(title = "学生请假类型配置", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody XgLeaveTypeConfigBo bo) { + return toAjax(xgLeaveTypeConfigService.updateByBo(bo)); + } + + /** + * 删除学生请假类型配置 + * + * @param ids 主键串 + */ + @SaCheckPermission("xgLeaveTypeConfig:xgLeaveTypeConfig:remove") + @Log(title = "学生请假类型配置", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(xgLeaveTypeConfigService.deleteWithValidByIds(List.of(ids), true)); + } +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentMsgController.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentMsgController.java index 9a35ac4b..b27b4f33 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentMsgController.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentMsgController.java @@ -39,6 +39,7 @@ import org.dromara.common.excel.convert.ExcelDictPreloadConvert; import org.dromara.common.excel.service.SqlCacheConfigService; import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.xg.domain.vo.XgStudentMsgVo; import org.dromara.xg.domain.bo.XgStudentMsgBo; import org.dromara.xg.domain.bo.XgStudentMsgAdvancedSearchBo; @@ -615,6 +616,27 @@ public class XgStudentMsgController extends BaseController { } } + /** + * 获取当前登录用户的学生信息 + */ + @SaCheckPermission("studentMsg:studentMsg:query") + @GetMapping("/currentUserInfo") + public R getCurrentUserInfo() { + // 获取当前登录用户ID + Long userId = LoginHelper.getUserId(); + if (userId == null) { + return R.fail("用户未登录"); + } + + // 根据用户ID查询学生信息 + XgStudentMsgVo studentInfo = xgStudentMsgService.queryByUserId(userId); + if (studentInfo == null) { + return R.fail("未找到当前用户的学生信息"); + } + + return R.ok(studentInfo); + } + /** * 获取学生信息详细信息 * diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgLeaveTypeConfig.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgLeaveTypeConfig.java new file mode 100644 index 00000000..375c84b8 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgLeaveTypeConfig.java @@ -0,0 +1,96 @@ +package org.dromara.xg.domain; + +import org.dromara.common.tenant.core.TenantEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; + +/** + * 学生请假类型配置对象 xg_leave_type_config + * + * @author zlwu + * @date 2025-08-03 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("xg_leave_type_config") +public class XgLeaveTypeConfig extends TenantEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID(雪花ID) + */ + @TableId(value = "id") + private Long id; + + /** + * 删除标志(0代表存在 1代表删除) + */ + @TableLogic(value = "0", delval = "1") + private Long deleted; + + /** + * 请假类型名称 + */ + private String leaveTypeName; + + /** + * 请假类型编码 + */ + private String leaveTypeCode; + + /** + * 请假类型描述 + */ + private String leaveTypeDesc; + + /** + * 排序号 + */ + private Long sortOrder; + + /** + * 请假是否需要上传地理位置:0-否,1-是 + */ + private String needLocationOnApply; + + /** + * 销假是否必须上传照片:0-否,1-是 + */ + private String needPhotoOnCancel; + + /** + * 销假是否需要上传地理位置:0-否,1-是 + */ + private String needLocationOnCancel; + + /** + * 非离校请假是否需要销假:0-否,1-是 + */ + private String needCancelForNonLeave; + + /** + * 是否可以提前请假:0-否,1-是 + */ + private String canApplyInAdvance; + + /** + * 是否开启:0-关闭,1-开启 + */ + private String isEnabled; + + /** + * 请假最大申请时长(天) + */ + private Double maxApplyDuration; + + /** + * 销假逾期多少时长给予提醒(天) + */ + private Double cancelOverdueReminder; + +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/bo/XgLeaveTypeConfigBo.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/bo/XgLeaveTypeConfigBo.java new file mode 100644 index 00000000..e930733e --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/bo/XgLeaveTypeConfigBo.java @@ -0,0 +1,103 @@ +package org.dromara.xg.domain.bo; + +import org.dromara.xg.domain.XgLeaveTypeConfig; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; + +/** + * 学生请假类型配置业务对象 xg_leave_type_config + * + * @author zlwu + * @date 2025-08-03 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = XgLeaveTypeConfig.class, reverseConvertGenerate = false) +public class XgLeaveTypeConfigBo extends BaseEntity { + + /** + * 主键ID(雪花ID) + */ + @NotNull(message = "主键ID(雪花ID)不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 删除标志(0代表存在 1代表删除) + */ + private Long deleted; + + /** + * 请假类型名称 + */ + @NotBlank(message = "请假类型名称不能为空", groups = { AddGroup.class, EditGroup.class }) + private String leaveTypeName; + + /** + * 请假类型编码 + */ + @NotBlank(message = "请假类型编码不能为空", groups = { AddGroup.class, EditGroup.class }) + private String leaveTypeCode; + + /** + * 请假类型描述 + */ + private String leaveTypeDesc; + + /** + * 排序号 + */ + private Long sortOrder; + + /** + * 请假是否需要上传地理位置:0-否,1-是 + */ + @NotBlank(message = "请假是否需要上传地理位置:0-否,1-是不能为空", groups = { AddGroup.class, EditGroup.class }) + private String needLocationOnApply; + + /** + * 销假是否必须上传照片:0-否,1-是 + */ + @NotBlank(message = "销假是否必须上传照片:0-否,1-是不能为空", groups = { AddGroup.class, EditGroup.class }) + private String needPhotoOnCancel; + + /** + * 销假是否需要上传地理位置:0-否,1-是 + */ + @NotBlank(message = "销假是否需要上传地理位置:0-否,1-是不能为空", groups = { AddGroup.class, EditGroup.class }) + private String needLocationOnCancel; + + /** + * 非离校请假是否需要销假:0-否,1-是 + */ + @NotBlank(message = "非离校请假是否需要销假:0-否,1-是不能为空", groups = { AddGroup.class, EditGroup.class }) + private String needCancelForNonLeave; + + /** + * 是否可以提前请假:0-否,1-是 + */ + @NotBlank(message = "是否可以提前请假:0-否,1-是不能为空", groups = { AddGroup.class, EditGroup.class }) + private String canApplyInAdvance; + + /** + * 是否开启:0-关闭,1-开启 + */ + @NotBlank(message = "是否开启:0-关闭,1-开启不能为空", groups = { AddGroup.class, EditGroup.class }) + private String isEnabled; + + /** + * 请假最大申请时长(天) + */ + private Double maxApplyDuration; + + /** + * 销假逾期多少时长给予提醒(天) + */ + private Double cancelOverdueReminder; + + +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgLeaveTypeConfigVo.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgLeaveTypeConfigVo.java new file mode 100644 index 00000000..2e70562c --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgLeaveTypeConfigVo.java @@ -0,0 +1,119 @@ +package org.dromara.xg.domain.vo; + +import org.dromara.xg.domain.XgLeaveTypeConfig; +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; +import cn.idev.excel.annotation.ExcelProperty; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 学生请假类型配置视图对象 xg_leave_type_config + * + * @author zlwu + * @date 2025-08-03 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = XgLeaveTypeConfig.class) +public class XgLeaveTypeConfigVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID(雪花ID) + */ + @ExcelProperty(value = "主键ID", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "雪=花ID") + private Long id; + + /** + * 请假类型名称 + */ + @ExcelProperty(value = "请假类型名称") + private String leaveTypeName; + + /** + * 请假类型编码 + */ + @ExcelProperty(value = "请假类型编码") + private String leaveTypeCode; + + /** + * 请假类型描述 + */ + @ExcelProperty(value = "请假类型描述") + private String leaveTypeDesc; + + /** + * 排序号 + */ + @ExcelProperty(value = "排序号") + private Long sortOrder; + + /** + * 请假是否需要上传地理位置:0-否,1-是 + */ + @ExcelProperty(value = "请假是否需要上传地理位置:0-否,1-是", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "sys_yesno") + private String needLocationOnApply; + + /** + * 销假是否必须上传照片:0-否,1-是 + */ + @ExcelProperty(value = "销假是否必须上传照片:0-否,1-是", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "sys_yesno") + private String needPhotoOnCancel; + + /** + * 销假是否需要上传地理位置:0-否,1-是 + */ + @ExcelProperty(value = "销假是否需要上传地理位置:0-否,1-是", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "sys_yesno") + private String needLocationOnCancel; + + /** + * 非离校请假是否需要销假:0-否,1-是 + */ + @ExcelProperty(value = "非离校请假是否需要销假:0-否,1-是", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "sys_yesno") + private String needCancelForNonLeave; + + /** + * 是否可以提前请假:0-否,1-是 + */ + @ExcelProperty(value = "是否可以提前请假:0-否,1-是", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "sys_yesno") + private String canApplyInAdvance; + + /** + * 是否开启:0-关闭,1-开启 + */ + @ExcelProperty(value = "是否开启:0-关闭,1-开启", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "sys_yesno") + private String isEnabled; + + /** + * 请假最大申请时长(天) + */ + @ExcelProperty(value = "请假最大申请时长", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "天=") + private Double maxApplyDuration; + + /** + * 销假逾期多少时长给予提醒(天) + */ + @ExcelProperty(value = "销假逾期多少时长给予提醒", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "天=") + private Double cancelOverdueReminder; + + +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgLeaveTypeConfigMapper.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgLeaveTypeConfigMapper.java new file mode 100644 index 00000000..db2f7436 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgLeaveTypeConfigMapper.java @@ -0,0 +1,15 @@ +package org.dromara.xg.mapper; + +import org.dromara.xg.domain.XgLeaveTypeConfig; +import org.dromara.xg.domain.vo.XgLeaveTypeConfigVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 学生请假类型配置Mapper接口 + * + * @author zlwu + * @date 2025-08-03 + */ +public interface XgLeaveTypeConfigMapper extends BaseMapperPlus { + +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgLeaveTypeConfigService.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgLeaveTypeConfigService.java new file mode 100644 index 00000000..1ceb8bf2 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgLeaveTypeConfigService.java @@ -0,0 +1,68 @@ +package org.dromara.xg.service; + +import org.dromara.xg.domain.vo.XgLeaveTypeConfigVo; +import org.dromara.xg.domain.bo.XgLeaveTypeConfigBo; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 学生请假类型配置Service接口 + * + * @author zlwu + * @date 2025-08-03 + */ +public interface IXgLeaveTypeConfigService { + + /** + * 查询学生请假类型配置 + * + * @param id 主键 + * @return 学生请假类型配置 + */ + XgLeaveTypeConfigVo queryById(Long id); + + /** + * 分页查询学生请假类型配置列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 学生请假类型配置分页列表 + */ + TableDataInfo queryPageList(XgLeaveTypeConfigBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的学生请假类型配置列表 + * + * @param bo 查询条件 + * @return 学生请假类型配置列表 + */ + List queryList(XgLeaveTypeConfigBo bo); + + /** + * 新增学生请假类型配置 + * + * @param bo 学生请假类型配置 + * @return 是否新增成功 + */ + Boolean insertByBo(XgLeaveTypeConfigBo bo); + + /** + * 修改学生请假类型配置 + * + * @param bo 学生请假类型配置 + * @return 是否修改成功 + */ + Boolean updateByBo(XgLeaveTypeConfigBo bo); + + /** + * 校验并批量删除学生请假类型配置信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentMsgService.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentMsgService.java index 32b919a2..fa2c5cf6 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentMsgService.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentMsgService.java @@ -98,6 +98,14 @@ public interface IXgStudentMsgService { */ XgStudentMsgVo queryPersonalInfo(Long userId); + /** + * 根据用户ID查询学生信息 + * + * @param userId 用户ID + * @return 学生信息 + */ + XgStudentMsgVo queryByUserId(Long userId); + /** * 根据班级ID和姓名查询学生信息列表 * diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgLeaveTypeConfigServiceImpl.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgLeaveTypeConfigServiceImpl.java new file mode 100644 index 00000000..6f747092 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgLeaveTypeConfigServiceImpl.java @@ -0,0 +1,138 @@ +package org.dromara.xg.service.impl; + +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.dromara.xg.domain.bo.XgLeaveTypeConfigBo; +import org.dromara.xg.domain.vo.XgLeaveTypeConfigVo; +import org.dromara.xg.domain.XgLeaveTypeConfig; +import org.dromara.xg.mapper.XgLeaveTypeConfigMapper; +import org.dromara.xg.service.IXgLeaveTypeConfigService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 学生请假类型配置Service业务层处理 + * + * @author zlwu + * @date 2025-08-03 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class XgLeaveTypeConfigServiceImpl implements IXgLeaveTypeConfigService { + + private final XgLeaveTypeConfigMapper baseMapper; + + /** + * 查询学生请假类型配置 + * + * @param id 主键 + * @return 学生请假类型配置 + */ + @Override + public XgLeaveTypeConfigVo queryById(Long id) { + return baseMapper.selectVoById(id); + } + + /** + * 分页查询学生请假类型配置列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 学生请假类型配置分页列表 + */ + @Override + public TableDataInfo queryPageList(XgLeaveTypeConfigBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的学生请假类型配置列表 + * + * @param bo 查询条件 + * @return 学生请假类型配置列表 + */ + @Override + public List queryList(XgLeaveTypeConfigBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(XgLeaveTypeConfigBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.orderByAsc(XgLeaveTypeConfig::getSortOrder); + lqw.orderByAsc(XgLeaveTypeConfig::getId); + lqw.eq(bo.getDeleted() != null, XgLeaveTypeConfig::getDeleted, bo.getDeleted()); + lqw.eq(bo.getIsEnabled() != null, XgLeaveTypeConfig::getIsEnabled, bo.getIsEnabled()); + lqw.like(StringUtils.isNotBlank(bo.getLeaveTypeName()), XgLeaveTypeConfig::getLeaveTypeName, + bo.getLeaveTypeName()); + lqw.like(StringUtils.isNotBlank(bo.getLeaveTypeCode()), XgLeaveTypeConfig::getLeaveTypeCode, + bo.getLeaveTypeCode()); + return lqw; + } + + /** + * 新增学生请假类型配置 + * + * @param bo 学生请假类型配置 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(XgLeaveTypeConfigBo bo) { + XgLeaveTypeConfig add = MapstructUtils.convert(bo, XgLeaveTypeConfig.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改学生请假类型配置 + * + * @param bo 学生请假类型配置 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(XgLeaveTypeConfigBo bo) { + XgLeaveTypeConfig update = MapstructUtils.convert(bo, XgLeaveTypeConfig.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(XgLeaveTypeConfig entity) { + // TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除学生请假类型配置信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if (isValid) { + // TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentMsgServiceImpl.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentMsgServiceImpl.java index 99311821..f962cdbc 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentMsgServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentMsgServiceImpl.java @@ -663,6 +663,20 @@ public class XgStudentMsgServiceImpl implements IXgStudentMsgService { .eq(XgStudentMsg::getId, userId)); } + /** + * 根据用户ID查询学生信息 + * + * @param userId 用户ID + * @return 学生信息 + */ + @Override + public XgStudentMsgVo queryByUserId(Long userId) { + // deleted 为0 且 用户ID为userId + return baseMapper.selectVoOne(new LambdaQueryWrapper() + .eq(XgStudentMsg::getDeleted, 0) + .eq(XgStudentMsg::getId, userId)); + } + /** * 根据班级ID和姓名查询学生信息列表 * diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xgLeaveTypeConfig/XgLeaveTypeConfigMapper.xml b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xgLeaveTypeConfig/XgLeaveTypeConfigMapper.xml new file mode 100644 index 00000000..14c3a87a --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xgLeaveTypeConfig/XgLeaveTypeConfigMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/docs/变更管理/code-adjust-record-2025-01-20-wuzilong.md b/docs/变更管理/code-adjust-record-2025-01-20-wuzilong.md new file mode 100644 index 00000000..c98fb54c --- /dev/null +++ b/docs/变更管理/code-adjust-record-2025-01-20-wuzilong.md @@ -0,0 +1,90 @@ +# 代码调整记录 - 2025-01-20 - wuzilong + +## 📅 变更时间 +2025-01-20 16:30:00 + +## 🎯 变更内容 +创建学生请假管理系统的数据库设计文件 + +## 📁 新增文件 + +### 1. 学生请假表结构文件 +- **文件路径**: `docs/设计文档/database/学生请假/xg_student_leave.sql` +- **功能**: 学生请假表结构定义 +- **主要字段**: + - 基础字段:id、tenant_id、create_dept、create_by、create_time、update_by、update_time、deleted + - 学生信息:student_id、student_name、student_no、class_id、class_name、major_id、major_name、college_id、college_name + - 请假信息:leave_type_code、leave_type_name、start_time、end_time、leave_duration、is_leave_school + - 联系信息:emergency_contact、emergency_phone + - 请假详情:leave_reason、leave_location、attachment_oss_ids + - 审批信息:approval_status、approval_opinion、approval_time、approval_by、approval_by_name + - 销假信息:cancel_status、cancel_time、cancel_location、cancel_photo_oss_ids、cancel_remark + +### 2. 示例数据文件 +- **文件路径**: `docs/设计文档/database/学生请假/xg_student_leave_sample_data.sql` +- **功能**: 提供8条不同类型的请假记录示例 +- **示例类型**: + - 事假申请(已审批通过,未销假) + - 病假申请(已审批通过,已销假) + - 外出请假(待审批) + - 回家请假(审批拒绝) + - 其他请假(已审批通过,已销假) + - 事假申请(待审批) + - 病假申请(已审批通过,逾期未销假) + - 外出请假(已取消) + +### 3. 设计说明文档 +- **文件路径**: `docs/设计文档/database/学生请假/README.md` +- **功能**: 详细说明数据库设计和使用方法 +- **内容包含**: + - 数据表设计说明 + - 索引设计(单列索引和复合索引) + - 示例数据说明 + - 使用说明和常见查询示例 + - 注意事项和版本历史 + +## 🔍 索引设计 + +### 单列索引 +- 租户索引:`idx_tenant_id` +- 学生索引:`idx_student_id` +- 学号索引:`idx_student_no` +- 班级索引:`idx_class_id` +- 学院索引:`idx_college_id` +- 请假类型索引:`idx_leave_type_code` +- 时间索引:`idx_start_time`、`idx_end_time` +- 状态索引:`idx_approval_status`、`idx_cancel_status` +- 创建时间索引:`idx_create_time` +- 离校状态索引:`idx_is_leave_school` + +### 复合索引 +- 学生+时间范围:`idx_student_time_range` +- 班级+审批状态:`idx_class_approval_status` +- 学院+请假类型:`idx_college_leave_type` +- 时间范围+审批状态:`idx_time_approval_status` + +## ✅ 设计特点 + +1. **符合项目规范**: 包含统一的基础字段,支持多租户和逻辑删除 +2. **完整业务覆盖**: 涵盖请假申请、审批、销假全流程 +3. **性能优化**: 合理的索引设计,支持高效查询 +4. **扩展性强**: 支持附件上传、地理位置记录等扩展功能 +5. **数据完整性**: 包含审批状态、销假状态等完整状态管理 + +## 🔗 关联文件 + +- **请假类型配置表**: `docs/设计文档/database/学生请假/xg_leave_type_config.sql`(已存在) +- **项目规范**: `.cursor/cursorrules-backend.md`(数据库开发规范) + +## 📝 后续工作 + +1. 基于此表结构开发后端API接口 +2. 开发前端请假申请和审批页面 +3. 开发移动端请假功能 +4. 编写API文档和测试脚本 + +--- + +**变更人**: wuzilong +**审核人**: - +**状态**: 已完成 \ No newline at end of file diff --git a/docs/变更管理/code-adjust-record-2025-01-27-cursor.md b/docs/变更管理/code-adjust-record-2025-01-27-cursor.md index 98c0e96c..b485a581 100644 --- a/docs/变更管理/code-adjust-record-2025-01-27-cursor.md +++ b/docs/变更管理/code-adjust-record-2025-01-27-cursor.md @@ -1180,3 +1180,1459 @@ import { Loading } from '@element-plus/icons-vue'; **变更状态**: ✅ 已完成 **测试状态**: 🔄 待测试 **文档状态**: ✅ 已更新 + +# 学生请假管理页面重构变更记录 + +**变更时间**: 2025-01-27 14:30:00 +**变更人员**: Cursor AI +**变更类型**: 代码重构 + +## 变更概述 + +将学生请假管理页面(`web/src/views/xg/xsjcxx/xsqj/index.vue`)中的对话框组件提取到独立的dialog.vue文件中,实现组件化重构。 + +## 变更详情 + +### 1. 新增文件 +- **文件路径**: `web/src/views/xg/xsjcxx/xsqj/dialog.vue` +- **文件类型**: Vue 3 组件 +- **功能**: 学生请假信息的新增和修改对话框 + +### 2. 修改文件 +- **文件路径**: `web/src/views/xg/xsjcxx/xsqj/index.vue` +- **修改内容**: + - 移除原有的el-dialog对话框代码(245-348行) + - 引入新的StudentLeaveDialog组件 + - 使用组件化方式调用对话框 + +### 3. 组件设计 + +#### dialog.vue组件特性 +- **Props接口**: + - `dialog`: 对话框显示状态和标题 + - `form`: 表单数据对象 + - `rules`: 表单验证规则 + - `buttonLoading`: 按钮加载状态 + +- **Events接口**: + - `update:dialog`: 更新对话框状态 + - `submit`: 提交表单事件 + - `cancel`: 取消操作事件 + +- **功能**: + - 表单验证 + - 数据双向绑定 + - 统一的提交和取消处理 + +### 4. 重构优势 + +1. **代码分离**: 将对话框逻辑从主页面中分离,提高代码可维护性 +2. **组件复用**: dialog组件可以在其他页面中复用 +3. **职责清晰**: 主页面专注于列表展示,对话框专注于表单操作 +4. **易于测试**: 独立的组件更容易进行单元测试 + +## 技术实现 + +### 组件通信方式 +- 使用Vue 3的Props和Emits进行父子组件通信 +- 采用v-model语法糖实现双向数据绑定 + +### 类型定义 +- 使用TypeScript接口定义Props和Emits类型 +- 暂时使用any类型避免类型导入问题 + +## 注意事项 + +1. **类型导入**: 当前存在API类型导入问题,需要后续完善 +2. **表单验证**: 保持原有的表单验证逻辑不变 +3. **样式兼容**: 保持原有的样式和布局 + +## 后续优化建议 + +1. 完善TypeScript类型定义 +2. 添加组件单元测试 +3. 考虑将表单字段配置化,提高灵活性 +4. 优化表单验证规则的传递方式 + +## 验证要点 + +- [ ] 新增学生请假功能正常 +- [ ] 修改学生请假功能正常 +- [ ] 表单验证功能正常 +- [ ] 对话框显示/隐藏正常 +- [ ] 数据双向绑定正常 + +--- + +**变更状态**: 已完成 +**影响范围**: 学生请假管理模块 +**回滚方案**: 可恢复原有的内联对话框代码 + +# 变更记录 - 2025-01-27 + +## 修改内容 + +### 文件:web/src/views/xg/xsjcxx/xsqj/dialog.vue + +#### 修改描述 +参考 `web/src/views/hq/pm/repairOrder/index.vue` 中的附件上传模块,对 `dialog.vue` 中的附件区域进行修改,保持样式一致。 + +#### 具体修改内容 + +1. **附件上传组件升级**: + - 将简单的文件选择按钮升级为完整的拖拽上传组件 + - 添加了 `list-type="picture-card"` 支持卡片式文件展示 + - 实现了拖拽上传功能 + +2. **文件管理功能**: + - 添加文件预览功能(图片预览,其他文件下载) + - 添加文件删除确认对话框 + - 添加文件下载功能 + - 支持多文件上传(最多15个文件) + +3. **文件类型和大小限制**: + - 支持图片、视频、PDF、Word文档等格式 + - 单个文件大小限制为10MB + - 文件上传前进行格式和大小验证 + +4. **UI样式优化**: + - 自定义文件卡片样式,包含缩略图、文件名、操作按钮 + - 图片文件显示缩略图,其他文件显示文件类型图标 + - 上传进度显示和加载状态 + - 悬停效果和操作按钮显示 + +5. **业务逻辑完善**: + - 文件上传成功后自动关联到请假申请 + - 提交表单时自动处理附件数据 + - 支持新增和编辑两种模式的文件上传提示 + +#### 新增功能 +- 拖拽上传支持 +- 文件卡片预览 +- 文件操作(下载、删除) +- 上传进度显示 +- 文件类型图标显示 + +#### 技术实现 +- 使用 Element Plus 的 `el-upload` 组件 +- 集成 `ImagePreview` 组件用于图片预览 +- 使用 `getToken` 进行文件上传认证 +- 响应式数据管理附件列表 + +#### 样式特点 +- 与 `index.vue` 中的附件上传模块保持完全一致的样式 +- 现代化的卡片式布局 +- 良好的用户体验和交互反馈 + +## 影响范围 +- 学生请假申请对话框的附件上传功能 +- 提升了用户体验和功能完整性 +- 与物业报修模块的附件上传功能保持一致性 + +## 备注 +- 修改后的附件上传功能与物业报修模块完全一致 +- 支持多种文件格式,满足请假申请的实际需求 +- 提供了完整的文件管理功能 + +## 样式修复记录 + +### 问题描述 +用户反馈附件上传区域的样式不正确,特别是图片加载失败和布局问题。 + +### 修复内容 +1. **样式结构优化**: + - 将嵌套的 SCSS 语法改为标准的 CSS 语法 + - 修复了样式选择器的语法错误 + - 确保样式与 `index.vue` 完全一致 + +2. **布局修复**: + - 修复了拖拽上传区域的样式 + - 优化了文件卡片的网格布局(一行4个) + - 修复了文件占位符的显示样式 + +3. **样式细节调整**: + - 统一了颜色、间距、字体大小等样式属性 + - 修复了悬停效果和过渡动画 + - 确保文件卡片的自适应布局 + +### 技术细节 +- 使用标准的 CSS 语法替代 SCSS 嵌套语法 +- 保持与 `index.vue` 中附件上传模块的完全一致性 +- 修复了 `:deep()` 选择器的使用方式 + +### 验证结果 +- 样式语法错误已全部修复 +- 布局与参考模块保持一致 +- 文件上传和预览功能正常工作 + +## 布局优化记录 + +### 问题描述 +用户反馈上传后的文件卡片布局有问题: +1. 下载和删除按钮位置不正确,显示在文件名下方 +2. 文件预览区域过大,导致文件名和按钮放不下 +3. 整体布局不够紧凑 + +### 修复内容 + +1. **按钮位置调整**: + - 将操作按钮(下载、删除)移到文件卡片的右上角 + - 使用绝对定位确保按钮始终在正确位置 + - 添加 z-index 确保按钮在最上层 + +2. **预览区域优化**: + - 将文件预览区域高度从 120px 调整为 100px + - 为文件名区域设置最小高度 32px + - 优化文件名显示,使用 flex 布局居中显示 + +3. **按钮样式优化**: + - 减小按钮内边距,从 4px 6px 调整为 3px 5px + - 调整按钮组位置,从 top: 4px, right: 4px 调整为 top: 2px, right: 2px + - 增强按钮背景透明度,从 0.9 调整为 0.95 + - 添加阴影效果提升视觉层次 + +4. **文件名显示优化**: + - 减小字体大小,从 12px 调整为 11px + - 调整内边距,从 8px 调整为 6px 8px + - 设置行高为 1.2,确保文字垂直居中 + - 使用 flex 布局确保文件名在容器中居中显示 + +### 技术细节 +- 调整了文件卡片的整体高度分配 +- 优化了按钮的定位和样式 +- 改进了文件名的显示效果 +- 保持了与参考模块的一致性 + +### 最终效果 +- ✅ 按钮位置正确,显示在文件卡片右上角 +- ✅ 文件预览区域大小合适 +- ✅ 文件名和按钮都能正常显示 +- ✅ 整体布局紧凑美观 + +## 按钮位置调整记录 + +### 问题描述 +用户反馈下载和删除按钮的样式不对,应该固定在文件名的下方,而不是在右上角。 + +### 修复内容 + +1. **按钮位置调整**: + - 将操作按钮从右上角绝对定位改为固定在文件名下方 + - 按钮区域作为文件卡片的最后一个元素,自然排列在文件名下方 + - 移除了绝对定位和悬停显示效果 + +2. **按钮样式优化**: + - 使用 flex 布局,按钮在容器中居中显示 + - 为按钮区域添加背景色和上边框,与文件名区域区分 + - 调整按钮内边距为 4px 8px,提供更好的点击区域 + - 为按钮添加边框和圆角,提升视觉效果 + +3. **布局结构优化**: + - 文件卡片布局:预览区域 → 文件名 → 操作按钮 + - 按钮区域有独立背景,与文件名区域有明确分隔 + - 按钮组在容器中水平居中显示 + +4. **交互效果调整**: + - 移除了悬停显示按钮的效果,按钮始终可见 + - 优化了按钮的悬停效果,边框颜色变化 + - 保持了禁用状态的样式 + +### 技术细节 +- 将按钮从绝对定位改为正常文档流布局 +- 使用 flex 布局实现按钮居中 +- 调整了按钮的边框、背景和间距样式 +- 保持了与整体设计风格的一致性 + +### 最终效果 +- ✅ 按钮固定在文件名下方,位置正确 +- ✅ 按钮样式美观,有边框和背景 +- ✅ 按钮始终可见,无需悬停 +- ✅ 整体布局更加清晰和易用 + +## 卡片高度调整记录 + +### 问题描述 +用户反馈按钮没有显示出来,需要增加附件卡片的高度让按钮显示出来。 + +### 修复内容 + +1. **卡片整体高度调整**: + - 将附件卡片的高度从默认调整为 180px + - 确保卡片宽度为 100%,自适应容器 + - 使用 `!important` 确保样式优先级 + +2. **内部区域高度分配**: + - **预览区域**:从 100px 调整为 110px + - **文件名区域**:固定高度 32px + - **按钮区域**:固定高度 38px,内边距调整为 6px 8px + +3. **高度分配明细**: + - 预览区域:110px + - 文件名区域:32px + - 按钮区域:38px + - 总计:180px + +4. **布局优化**: + - 确保每个区域都有足够的空间显示内容 + - 按钮区域有足够的高度显示按钮和图标 + - 文件名区域有固定高度,避免内容挤压 + +### 技术细节 +- 使用 `:deep()` 选择器确保样式能够穿透到 Element Plus 组件 +- 设置 `!important` 确保高度样式不被覆盖 +- 精确计算各区域高度,确保总高度为 180px + +### 最终效果 +- ✅ 附件卡片高度增加到 180px +- ✅ 按钮区域有足够空间显示(38px) +- ✅ 预览区域和文件名区域比例合理 +- ✅ 按钮能够正常显示和操作 + +## 文件名显示优化记录 + +### 问题描述 +用户反馈附件卡片中的文件名太长了,显示不下,需要考虑使用省略号的方式缩写名称,同时把文件的后缀显示出来。 + +### 修复内容 + +1. **文件名缩写函数**: + - 新增 `getShortFileName` 函数,智能处理文件名缩写 + - 保留文件后缀,确保文件类型可见 + - 对没有后缀的文件名进行特殊处理 + +2. **缩写规则**: + - **有后缀的文件**:保留前8个字符 + "..." + 完整后缀 + - **无后缀的文件**:保留前12个字符 + "..." + - **短文件名**:直接显示完整名称 + +3. **样式优化**: + - 添加 `word-break: break-all` 确保长文件名正确换行 + - 设置 `max-width: 100%` 防止文件名溢出 + - 保持 `text-overflow: ellipsis` 和 `white-space: nowrap` 确保省略号显示 + +4. **显示效果**: + - 文件名示例:`very_long_filename.pdf` → `very_lon...pdf` + - 文件名示例:`document.docx` → `document.docx`(短文件名直接显示) + - 文件名示例:`no_extension_file` → `no_extensi...`(无后缀文件) + +### 技术细节 +- 使用 `lastIndexOf('.')` 准确识别文件后缀 +- 保留点号,确保后缀格式正确 +- 在模板中使用 `getShortFileName(file.name)` 替换直接显示 +- 保持 `title` 属性显示完整文件名,鼠标悬停可见 + +### 最终效果 +- ✅ 长文件名使用省略号缩写显示 +- ✅ 文件后缀始终可见,便于识别文件类型 +- ✅ 短文件名直接显示,无需缩写 +- ✅ 鼠标悬停显示完整文件名 +- ✅ 文件名区域布局更加合理 + +# 代码调整记录 - 2025-01-27 + +## 调整概述 +优化编辑报修单弹窗中的附件文件名显示,当文件名很长时使用省略号缩写,同时保留文件后缀名。 + +## 调整时间 +2025-01-27 15:30:00 + +## 调整人员 +Cursor AI + +## 调整内容 + +### 1. 新增文件名格式化函数 +**文件**: `web/src/views/hq/pm/repairOrder/index.vue` + +**新增函数**: `formatFileName` +```typescript +/** 格式化文件名显示 - 长文件名用省略号缩写,保留后缀名 */ +const formatFileName = (fileName: string): string => { + if (!fileName) return ''; + + const maxLength = 15; // 最大显示长度(包含后缀名) + const idx = fileName.lastIndexOf('.'); + + if (idx === -1) { + // 没有后缀名的情况 + return fileName.length > maxLength ? fileName.substring(0, maxLength - 3) + '...' : fileName; + } + + const name = fileName.substring(0, idx); + const ext = fileName.substring(idx); // 包含点号的后缀名 + + // 如果文件名(不含后缀)长度超过限制 + if (name.length > maxLength - ext.length - 3) { + const truncatedName = name.substring(0, maxLength - ext.length - 3); + return truncatedName + '...' + ext; + } + + return fileName; +}; +``` + +### 2. 修改附件文件名显示 +**修改位置**: 编辑报修单弹窗中的附件卡片 + +**原代码**: +```vue +
+ {{ file.name }} +
+``` + +**修改后**: +```vue +
+ {{ formatFileName(file.name) }} +
+``` + +### 3. 修改详情对话框中的附件文件名显示 +**修改位置**: 工单详情对话框中的附件信息 + +**原代码**: +```vue +
+ {{ attachment.fileName }} +
+``` + +**修改后**: +```vue +
+ {{ formatFileName(attachment.fileName) }} +
+``` + +### 4. 修改附件查看对话框中的文件名显示 +**修改位置**: 附件查看对话框中的文件信息 + +**原代码**: +```vue +
{{ attachment.fileName }}
+``` + +**修改后**: +```vue +
{{ formatFileName(attachment.fileName) }}
+``` + +## 功能说明 + +### 文件名格式化规则 +1. **最大显示长度**: 15个字符(包含后缀名) +2. **保留后缀名**: 无论文件名多长,都会保留完整的文件后缀名 +3. **省略号处理**: 当文件名超过限制时,在文件名中间添加"...",后缀名完整显示 +4. **无后缀处理**: 对于没有后缀名的文件,直接在末尾添加"..." + +### 示例效果 +- `very_long_filename_that_is_too_long.txt` → `very_long...txt` +- `short.txt` → `short.txt` (不变) +- `no_extension_file` → `no_extension...` (无后缀) +- `medium_length_file.pdf` → `medium_length...pdf` + +## 技术实现 +- 使用 `lastIndexOf('.')` 查找最后一个点号位置 +- 分离文件名和后缀名 +- 计算可用长度(总长度 - 后缀名长度 - 省略号长度) +- 截断文件名并添加省略号 +- 保持 `title` 属性显示完整文件名,便于用户查看 + +## 影响范围 +- 编辑报修单弹窗中的附件上传区域 +- 工单详情对话框中的附件信息显示 +- 附件查看对话框中的文件列表 + +## 测试建议 +1. 上传不同长度的文件名进行测试 +2. 验证后缀名是否正确保留 +3. 检查鼠标悬停时是否显示完整文件名 +4. 测试无后缀名文件的显示效果 + +## 备注 +- 最大显示长度设置为15个字符,可根据实际UI需求调整 +- 保持了原有的 `title` 属性,用户仍可通过鼠标悬停查看完整文件名 +- 函数具有良好的容错性,处理空字符串和异常情况 + +# 学生请假申请对话框请假类型下拉选择功能实现 + +**变更时间**: 2025-01-27 15:30:00 +**变更人员**: Cursor AI +**变更类型**: 功能优化 + +## 📋 变更概述 + +将学生请假申请对话框中的请假类型字段从输入框改为下拉选择模式,通过调用后端API获取启用的请假类型配置数据。 + +## 🔧 具体修改内容 + +### 1. 前端界面修改 (web/src/views/xg/xsjcxx/xsqj/dialog.vue) + +#### 模板部分修改 +- **请假类型字段**: 将 `el-input` 改为 `el-select` 下拉选择框 +- **添加功能**: + - 支持清空选择 (`clearable`) + - 添加选择变更事件处理 (`@change="handleLeaveTypeChange"`) + - 动态渲染请假类型选项 + +#### 脚本部分修改 +- **新增导入**: 添加 `onMounted` 生命周期钩子 +- **新增响应式数据**: `leaveTypeList` 用于存储请假类型列表 +- **新增方法**: + - `handleLeaveTypeChange()`: 处理请假类型选择变更,自动填充类型编码 + - `getLeaveTypeList()`: 调用API获取请假类型列表 +- **生命周期**: 在组件挂载时自动获取请假类型数据 + +### 2. 后端查询条件优化 (backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgLeaveTypeConfigServiceImpl.java) + +#### 查询条件增强 +- **新增排序**: 按 `sortOrder` 升序排列,然后按 `id` 升序排列 +- **新增过滤条件**: 添加 `isEnabled` 字段查询条件 +- **查询逻辑**: `deleted = 0` 且 `isEnabled = 1` 的记录 + +### 3. 前端类型定义完善 (web/src/api/xg/xsjcxx/xgLeaveTypeConfig/xgLeaveTypeConfig/types.ts) + +#### 查询接口类型扩展 +- **新增字段**: 在 `XgLeaveTypeConfigQuery` 接口中添加 `isEnabled?: string` 字段 +- **类型安全**: 确保API调用参数类型正确 + +## 🎯 功能特性 + +### 下拉选择功能 +- ✅ **数据源**: 从后端API动态获取启用的请假类型 +- ✅ **自动填充**: 选择请假类型后自动填充对应的类型编码 +- ✅ **同步清空**: 清空请假类型选择时,类型编码也同步清空 +- ✅ **清空功能**: 支持清空选择 +- ✅ **排序显示**: 按配置的排序号显示选项 + +### API调用规范 +- ✅ **请求方法**: 使用 `request` 方法调用API +- ✅ **参数设置**: + - `deleted: 0` (未删除) + - `isEnabled: '1'` (已启用) + - `pageSize: 1000` (获取所有数据) +- ✅ **错误处理**: 完善的错误提示和异常处理 + +### 数据同步 +- ✅ **实时更新**: 组件挂载时自动获取最新数据 +- ✅ **状态同步**: 选择变更时自动更新相关字段 +- ✅ **数据验证**: 确保数据格式正确 + +## 🔄 技术实现细节 + +### 前端实现 +```typescript +// 请假类型列表数据 +const leaveTypeList = ref([]); + +// 获取请假类型列表 +const getLeaveTypeList = async () => { + const response = await request({ + url: '/xgLeaveTypeConfig/xgLeaveTypeConfig/list', + method: 'get', + params: { + deleted: 0, + isEnabled: '1', + pageSize: 1000 + } + }); + leaveTypeList.value = response.rows || []; +}; + +// 请假类型变更处理 - 支持同步清空 +const handleLeaveTypeChange = (value: string) => { + if (value) { + // 有选择值时,查找对应的请假类型并填充编码 + const leaveType = leaveTypeList.value.find(item => item.leaveTypeName === value); + if (leaveType) { + props.form.leaveTypeCode = leaveType.leaveTypeCode; + } + } else { + // 清空选择时,同时清空类型编码 + props.form.leaveTypeCode = ''; + } +}; +``` + +### 后端查询优化 +```java +private LambdaQueryWrapper buildQueryWrapper(XgLeaveTypeConfigBo bo) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.orderByAsc(XgLeaveTypeConfig::getSortOrder); + lqw.orderByAsc(XgLeaveTypeConfig::getId); + lqw.eq(bo.getDeleted() != null, XgLeaveTypeConfig::getDeleted, bo.getDeleted()); + lqw.eq(bo.getIsEnabled() != null, XgLeaveTypeConfig::getIsEnabled, bo.getIsEnabled()); + // ... 其他查询条件 + return lqw; +} +``` + +## ✅ 测试验证 + +### 功能测试 +- ✅ 下拉选择框正常显示 +- ✅ 请假类型数据正确加载 +- ✅ 选择后自动填充类型编码 +- ✅ 清空选择时类型编码同步清空 +- ✅ 清空功能正常工作 +- ✅ 错误处理机制有效 + +### 数据验证 +- ✅ 只显示已启用的请假类型 (`isEnabled = '1'`) +- ✅ 只显示未删除的记录 (`deleted = 0`) +- ✅ 按排序号正确排序显示 +- ✅ API响应数据格式正确 + +## 📝 相关文档 + +- **API文档**: `docs/开发文档/API/学生请假管理API.md` +- **数据库设计**: `docs/设计文档/database/学生请假/xg_leave_type_config.sql` +- **前端规范**: `.cursor/cursorrules-frontend.md` + +## 🎉 变更总结 + +本次变更成功实现了请假类型的下拉选择功能,提升了用户体验和数据准确性: + +1. **用户体验提升**: 从手动输入改为下拉选择,减少输入错误 +2. **数据一致性**: 通过API获取标准数据,确保数据准确性 +3. **维护性增强**: 请假类型配置统一管理,便于维护 +4. **扩展性良好**: 支持动态添加新的请假类型配置 + +变更已完成并通过测试验证,功能正常运行。 + +# 代码调整记录 - 2025-01-27 + +## 修改概述 +优化学生请假对话框 (`web/src/views/xg/xsjcxx/xsqj/dialog.vue`) 中的时间选择功能,参考 `leaveEdit.vue` 的实现方式,将分离的开始时间和结束时间选择器改为日期时间范围选择器,并添加精确的自动计算请假时长功能,支持时分秒选择和小数天数计算。 + +## 修改详情 + +### 1. 界面布局调整 +- **文件**: `web/src/views/xg/xsjcxx/xsqj/dialog.vue` +- **修改内容**: + - 将原来的两个独立时间选择器(开始时间、结束时间)合并为一个日期时间范围选择器 + - 支持时分秒精确选择:使用 `type="datetimerange"` 替代 `type="daterange"` + - 调整布局:请假时间占12列,请假时长占12列 + - 请假时长输入框设置为禁用状态,显示"自动计算请假时长" + +### 2. 功能实现 +- **新增响应式数据**: `leaveTime` - 用于存储日期时间范围选择器的值 +- **新增方法**: `changeLeaveTime()` - 精确计算请假时长 + - 精确计算天数:`diffInMilliseconds / (1000 * 60 * 60 * 24)` (支持小数) + - 计算整数天数:`Math.floor(totalDays)` + - 计算剩余小时数:`(totalDays - fullDays) * 24` + - 计算剩余分钟数:`(remainingHours - fullHours) * 60` + - 智能格式化显示:优先显示"X天Y小时Z分钟",不足1分钟时显示小数天数 + - 自动同步:将开始时间和结束时间同步到表单数据中 + +### 3. 数据同步 +- **组件挂载时**: 如果表单中已有开始时间和结束时间,自动初始化时间选择器 +- **提交验证**: 确保请假时间已选择,并在提交前同步时间数据到表单 +- **实时更新**: 时间选择变更时自动更新请假时长和表单数据 + +### 4. 用户体验优化 +- **精确时间选择**: 支持时分秒精确选择,满足精确请假需求 +- **默认时间**: 设置默认时间(开始时间00:00:00,结束时间23:59:59) +- **必填验证**: 请假时间设置为必填项 +- **智能提示**: 请假时长输入框显示"自动计算请假时长"提示 +- **精确计算**: 支持小数天数计算,如"0.5天"、"1.25天"等 + +## 技术实现要点 + +### 日期时间范围选择器配置 +```vue + +``` + +### 精确时间计算逻辑 +```javascript +const changeLeaveTime = () => { + if (leaveTime.value && leaveTime.value.length === 2) { + const startDate = new Date(leaveTime.value[0]).getTime(); + const endDate = new Date(leaveTime.value[1]).getTime(); + const diffInMilliseconds = endDate - startDate; + + // 计算精确的天数(包含小数) + const totalDays = diffInMilliseconds / (1000 * 60 * 60 * 24); + const fullDays = Math.floor(totalDays); + const remainingHours = (totalDays - fullDays) * 24; + const fullHours = Math.floor(remainingHours); + const remainingMinutes = (remainingHours - fullHours) * 60; + const fullMinutes = Math.floor(remainingMinutes); + + // 智能格式化显示 + let durationText = ''; + if (fullDays > 0) durationText += `${fullDays}天`; + if (fullHours > 0) durationText += `${fullHours}小时`; + if (fullMinutes > 0) durationText += `${fullMinutes}分钟`; + + // 如果没有完整时间单位,显示小数天数 + if (durationText === '') { + props.form.leaveDuration = `${totalDays.toFixed(2)}天`; + } else { + props.form.leaveDuration = durationText; + } + + // 同步到表单 + props.form.startTime = leaveTime.value[0]; + props.form.endTime = leaveTime.value[1]; + } +}; +``` + +## 参考文件 +- **参考实现**: `web/src/views/xg/xsjcxx/xsqj/leaveEdit.vue` +- **修改文件**: `web/src/views/xg/xsjcxx/xsqj/dialog.vue` + +## 测试要点 +1. 日期时间范围选择器正常显示和选择(支持时分秒) +2. 请假时长精确计算准确性(支持小数天数) +3. 时间数据正确同步到表单 +4. 提交验证正常工作 +5. 编辑时已有数据正确回显 +6. 短时间请假(如几小时)正确显示 +7. 长时间请假(如几天几小时)正确显示 + +## 变更时间 +- **修改时间**: 2025-01-27 +- **修改人员**: Cursor AI +- **修改类型**: 功能优化 + +# 代码调整记录 - 2025-01-27 + +## 修改概述 +将工作流相关功能从 `leaveEdit.vue` 移植到 `dialog.vue` 中,实现学生请假对话框的完整工作流支持。 + +## 修改文件 +- `web/src/views/xg/xsjcxx/xsqj/dialog.vue` + +## 主要变更内容 + +### 1. 新增工作流组件引入 +```typescript +import SubmitVerify from '@/components/Process/submitVerify.vue'; +import ApprovalRecord from '@/components/Process/approvalRecord.vue'; +import ApprovalButton from '@/components/Process/approvalButton.vue'; +import { startWorkFlow } from '@/api/workflow/task'; +import { addStudentLeave, getStudentLeave, updateStudentLeave } from '@/api/workflow/studentLeave/studentLeave'; +import { StudentLeaveForm, StudentLeaveVO } from '@/api/workflow/studentLeave/studentLeave/types'; +``` + +### 2. 新增类型定义 +```typescript +interface DialogOption { + visible: boolean; + title: string; +} + +interface ElFormInstance { + validate: (callback?: (valid: boolean) => void) => Promise; + resetFields: () => void; +} + +interface PageData { + form: T; + queryParams: Q; + rules: Record; +} + +interface BaseEntity { + id?: string | number; + createBy?: number; + createTime?: string; + updateBy?: number; + updateTime?: string; + remark?: string; +} +``` + +### 3. 扩展Props和Emits接口 +```typescript +interface Emits { + (e: 'update:dialog', value: { visible: boolean; title: string }): void; + (e: 'submit'): void; + (e: 'cancel'): void; + (e: 'update:buttonLoading', value: boolean): void; + (e: 'update:form', value: any): void; +} +``` + +### 4. 新增工作流相关状态管理 +```typescript +const flowCode = ref(''); +const dialogVisible = reactive({ + visible: false, + title: '流程定义' +}); +const submitFormData = ref({ + businessId: '', + flowCode: '', + variables: {} +}); +const taskVariables = ref>({}); +``` + +### 5. 新增流程代码选项 +```typescript +const flowCodeOptions = [ + { value: 'hzdyjs-qj', label: '学生请假流程-杭州第一技师' }, + { value: 'leave1', label: '请假申请-普通' }, + { value: 'leave2', label: '请假申请-排他网关' }, + { value: 'leave3', label: '请假申请-并行网关' }, + { value: 'leave4', label: '请假申请-会签' }, + { value: 'leave5', label: '请假申请-并行会签网关' }, + { value: 'leave6', label: '请假申请-排他并行会签' } +]; +``` + +### 6. 新增工作流核心方法 +- `handleClose()`: 关闭流程选择对话框 +- `submitFlow()`: 提交流程选择 +- `handleStartWorkFlow()`: 启动工作流 +- `handleApprovalRecord()`: 查看审批记录 +- `submitCallback()`: 提交回调处理 +- `approvalVerifyOpen()`: 打开审批窗口 + +### 7. 重构提交表单方法 +```typescript +const submitForm = (status: string) => { + // 表单验证 + // 保存业务数据 + // 根据状态处理工作流 + // 支持暂存和提交两种模式 +} +``` + +### 8. 模板更新 +- 添加工作流组件到模板中 +- 添加流程选择对话框 +- 更新审批按钮组件使用 + +## 技术要点 + +### 1. Props只读属性处理 +由于Vue 3中props是只读的,使用emit来更新父组件状态: +```typescript +emit('update:buttonLoading', true); +emit('update:form', res.data); +``` + +### 2. 工作流变量配置 +```typescript +taskVariables.value = { + qjts: data.leaveDuration, // hzdyjs-qj流程变量 + leaveDays: data.leaveDuration, // leave2/6流程变量 + userList: ['1', '3', '4'] // leave4/5流程变量 +}; +``` + +### 3. 流程状态管理 +- draft: 草稿状态 +- waiting: 待审批状态 +- complete: 已完成状态 +- cancel: 已取消状态 +- back: 已退回状态 + +## 功能特性 + +### 1. 完整的工作流支持 +- 支持多种流程类型(普通、排他网关、并行网关、会签等) +- 自动流程变量配置 +- 审批记录查看 +- 流程进度跟踪 + +### 2. 文件上传功能 +- 支持多种文件格式 +- 文件预览和下载 +- 上传进度显示 +- 文件管理操作 + +### 3. 表单验证 +- 完整的表单验证规则 +- 实时验证反馈 +- 自定义验证逻辑 + +### 4. 用户体验优化 +- 加载状态管理 +- 错误处理和提示 +- 响应式布局 +- 无障碍访问支持 + +## 测试建议 + +### 1. 功能测试 +- 测试各种流程类型的启动 +- 验证流程变量传递 +- 检查审批记录显示 +- 测试文件上传功能 + +### 2. 集成测试 +- 与后端API集成测试 +- 与工作流引擎集成测试 +- 与文件存储服务集成测试 + +### 3. 兼容性测试 +- 不同浏览器兼容性 +- 不同设备响应式测试 +- 网络异常情况处理 + +## 后续优化建议 + +### 1. 性能优化 +- 组件懒加载 +- 文件上传分片处理 +- 数据缓存策略 + +### 2. 功能增强 +- 批量操作支持 +- 高级搜索功能 +- 数据导出功能 + +### 3. 用户体验 +- 更丰富的交互反馈 +- 快捷键支持 +- 主题定制 + +## 相关文档 +- [Warm-Flow工作流开发指南](../开发文档/warm-flow工作流框架开发指南.md) +- [学生请假API文档](../开发文档/API/学生请假管理API.md) +- [工作流组件使用规范](../.cursor/cursorrules-workflow.md) + +--- +**修改人**: Cursor AI +**修改时间**: 2025-01-27 15:30:00 +**修改类型**: 功能增强 +**影响范围**: 学生请假管理模块 + +# 学生请假对话框添加学生基础信息API调用功能 + +**修改时间**: 2025-01-27 15:30:00 +**修改人**: cursor +**修改类型**: 功能增强 + +## 修改概述 + +在学生请假对话框(`web/src/views/xg/xsjcxx/xsqj/dialog.vue`)中添加了通过API获取当前登录用户学生信息的功能,实现学生基础信息的自动填充。 + +## 详细修改内容 + +### 1. 后端API新增 + +#### 文件: `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentMsgController.java` + +**新增方法**: `getCurrentUserInfo()` +- **接口路径**: `GET /studentMsg/studentMsg/currentUserInfo` +- **功能**: 获取当前登录用户的学生信息 +- **权限**: `@SaCheckPermission("studentMsg:studentMsg:query")` +- **实现逻辑**: + - 通过`LoginHelper.getUserId()`获取当前登录用户ID + - 调用`xgStudentMsgService.queryByUserId(userId)`查询学生信息 + - 返回学生信息或错误提示 + +#### 文件: `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentMsgService.java` + +**新增接口方法**: `queryByUserId(Long userId)` +- **功能**: 根据用户ID查询学生信息 +- **参数**: `userId` - 用户ID +- **返回值**: `XgStudentMsgVo` - 学生信息视图对象 + +#### 文件: `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentMsgServiceImpl.java` + +**新增实现方法**: `queryByUserId(Long userId)` +- **实现逻辑**: 使用MyBatis-Plus查询条件,根据用户ID和删除标记查询学生信息 +- **查询条件**: `deleted = 0 AND id = userId` + +### 2. 前端界面修改 + +#### 文件: `web/src/views/xg/xsjcxx/xsqj/dialog.vue` + +**新增方法**: `getCurrentUserStudentInfo()` +- **功能**: 调用API获取当前登录用户的学生信息 +- **API调用**: `GET /studentMsg/studentMsg/currentUserInfo` +- **数据处理**: 将返回的学生信息填入表单字段 + - `studentName` - 学生姓名 + - `studentNo` - 学号 + - `className` - 班级名称 + - `majorName` - 专业名称 + - `collegeName` - 学院名称 + - `studentId` - 学生ID + +**修改生命周期**: `onMounted()` +- 在组件挂载时调用`getCurrentUserStudentInfo()`方法 +- 确保学生基础信息在页面加载时自动填充 + +## 技术实现要点 + +### 1. 权限控制 +- 使用`@SaCheckPermission`注解确保只有有权限的用户才能访问 +- 通过`LoginHelper.getUserId()`获取当前登录用户ID,确保数据安全 + +### 2. 错误处理 +- 后端API包含完整的错误处理逻辑 +- 前端包含try-catch错误处理,确保界面稳定性 + +### 3. 数据映射 +- 后端返回完整的`XgStudentMsgVo`对象 +- 前端选择性地映射需要的字段到表单中 + +## 测试验证 + +### 1. API测试 +- 验证`GET /studentMsg/studentMsg/currentUserInfo`接口正常返回 +- 验证权限控制是否生效 +- 验证错误处理是否正常 + +### 2. 前端测试 +- 验证学生请假对话框打开时自动填充学生信息 +- 验证学生基础信息展示区域正确显示数据 +- 验证API调用失败时的错误处理 + +## 影响范围 + +- **新增功能**: 学生请假对话框学生基础信息自动填充 +- **无破坏性变更**: 不影响现有功能 +- **向后兼容**: 完全兼容现有代码 + +## 相关文档 + +- 学生信息管理API文档 +- 请假管理功能文档 +- 前端组件开发规范 + +--- + +**备注**: 此修改提升了用户体验,减少了手动输入学生信息的工作量,提高了数据准确性。 + +# 请假类型切换功能实现变更记录 + +**变更时间**: 2025-01-27 15:30:00 +**变更人员**: Cursor AI +**变更文件**: `web/src/views/xg/xsjcxx/xsqj/dialog.vue` +**变更类型**: 功能增强 + +## 变更概述 + +在学生请假申请对话框中,实现了请假类型切换时的智能逻辑处理,包括销假状态自动设置、时间选择限制和时长验证功能。 + +## 详细变更内容 + +### 1. 新增计算属性 +- **文件位置**: `web/src/views/xg/xsjcxx/xsqj/dialog.vue` (第 320-324 行) +- **功能**: 添加 `currentLeaveType` 计算属性,用于获取当前选中的请假类型配置信息 + +```typescript +// 当前选中的请假类型配置 +const currentLeaveType = computed(() => { + if (!props.form.leaveTypeName) return null; + return leaveTypeList.value.find((item) => item.leaveTypeName === props.form.leaveTypeName); +}); +``` + +### 2. 增强请假类型变更处理逻辑 +- **文件位置**: `web/src/views/xg/xsjcxx/xsqj/dialog.vue` (第 570-610 行) +- **功能**: 在 `handleLeaveTypeChange` 方法中实现三个核心逻辑: + +#### 2.1 销假状态自动设置 +- 当 `need_cancel_for_non_leave` 为 `0-否` 时: + - 如果 `isLeaveSchool = 0`,则 `cancelStatus = 3` (无需销假) + - 其他情况,`cancelStatus = 0` (未销假) +- 当 `need_cancel_for_non_leave` 为 `1-是` 时,保持原有逻辑 + +#### 2.2 提前请假限制 +- 当 `can_apply_in_advance` 为 `0-否` 时,通过日期选择器的 `disabledDate` 控制开始时间只能选择当前天之前 + +#### 2.3 最大申请时长限制 +- 当 `max_apply_duration` 有值时,在时间选择时进行时长验证 + +### 3. 新增日期禁用逻辑 +- **文件位置**: `web/src/views/xg/xsjcxx/xsqj/dialog.vue` (第 612-628 行) +- **功能**: 实现 `disabledDate` 方法,处理是否可以提前请假的日期限制 + +```typescript +// 日期禁用逻辑 +const disabledDate = (time: Date) => { + if (!currentLeaveType.value) return false; + + const today = new Date(); + today.setHours(0, 0, 0, 0); + + // 2. 处理是否可以提前请假的逻辑 + if (currentLeaveType.value.canApplyInAdvance === '0') { + // 不可以提前请假,开始时间只能是当前天之前 + if (time.getTime() > today.getTime()) { + return true; // 禁用今天之后的日期 + } + } + + return false; +}; +``` + +### 4. 增强时间变更处理逻辑 +- **文件位置**: `web/src/views/xg/xsjcxx/xsqj/dialog.vue` (第 630-670 行) +- **功能**: 在 `changeLeaveTime` 方法中添加最大申请时长验证 + +```typescript +// 3. 处理最大申请时长的逻辑 +if (currentLeaveType.value && currentLeaveType.value.maxApplyDuration && currentLeaveType.value.maxApplyDuration > 0) { + if (totalDays > currentLeaveType.value.maxApplyDuration) { + ElMessage.warning(`请假时长不能超过${currentLeaveType.value.maxApplyDuration}天`); + // 清空时间选择 + leaveTime.value = []; + props.form.leaveDuration = ''; + props.form.startTime = ''; + props.form.endTime = ''; + return; + } +} +``` + +### 5. 新增字段变化监听器 +- **文件位置**: `web/src/views/xg/xsjcxx/xsqj/dialog.vue` (第 800-815 行) +- **功能**: 监听 `isLeaveSchool` 字段变化,自动更新销假状态 + +```typescript +// 监听 isLeaveSchool 字段变化,更新销假状态 +watch(() => props.form.isLeaveSchool, (newValue) => { + if (currentLeaveType.value && currentLeaveType.value.needCancelForNonLeave === '0') { + if (newValue === '0') { + // 当 isLeaveSchool = 0 时,cancelStatus = 3 (无需销假) + props.form.cancelStatus = '3'; + } else { + // 其他时候,cancelStatus = 0 (未销假) + props.form.cancelStatus = '0'; + } + } +}); +``` + +### 6. 更新日期选择器配置 +- **文件位置**: `web/src/views/xg/xsjcxx/xsqj/dialog.vue` (第 89-99 行) +- **功能**: 在日期选择器中添加 `disabled-date` 属性,启用日期限制功能 + +```vue + +``` + +## 功能特性 + +### 1. 智能销假状态管理 +- 根据请假类型配置和离校状态自动设置销假状态 +- 支持实时更新,当用户修改离校状态时自动调整 + +### 2. 灵活的时间选择限制 +- 支持提前请假限制:不允许选择未来日期作为开始时间 +- 支持最大申请时长限制:防止超过配置的最大请假天数 +- 提供友好的用户提示和自动清空功能 + +### 3. 响应式配置更新 +- 请假类型切换时立即应用相关配置 +- 支持动态更新,无需刷新页面 + +## 技术实现要点 + +1. **计算属性**: 使用 Vue 3 的 `computed` 实现响应式的请假类型配置获取 +2. **监听器**: 使用 `watch` 监听字段变化,实现自动状态更新 +3. **日期验证**: 通过 `disabledDate` 函数实现日期选择限制 +4. **时长验证**: 在时间变更时进行实时验证和用户提示 +5. **状态管理**: 自动管理销假状态,减少用户操作错误 + +## 测试建议 + +1. **销假状态测试**: 测试不同请假类型和离校状态组合下的销假状态设置 +2. **时间限制测试**: 测试提前请假限制和最大时长限制功能 +3. **用户体验测试**: 验证提示信息和自动清空功能是否友好 +4. **边界条件测试**: 测试空值、无效配置等边界情况 + +## 相关文档 + +- 请假类型配置表结构: `docs/设计文档/database/学生请假/xg_leave_type_config.sql` +- 学生请假表结构: `docs/设计文档/database/学生请假/xg_student_leave.sql` +- 请假类型配置API: `web/src/api/xg/xsjcxx/xgLeaveTypeConfig/xgLeaveTypeConfig/types.ts` + +--- + +**变更状态**: ✅ 已完成 +**代码审查**: 待审查 +**测试状态**: 待测试 + +# 学生请假管理页面附件数据展示问题修复 + +**修复时间**: 2025-01-27 15:30:00 +**修复人员**: Cursor AI +**修复文件**: `web/src/views/xg/xsjcxx/xsqj/dialog.vue` + +## 问题描述 + +在学生请假管理页面(`web/src/views/xg/xsjcxx/xsqj/index.vue`)中,点击表格中的"修改"按钮时,弹窗界面(`web/src/views/xg/xsjcxx/xsqj/dialog.vue`)中的附件数据未正确展示。 + +## 问题分析 + +1. **数据获取正常**: `index.vue` 中的 `handleUpdate` 方法正确获取了学生请假数据,包括 `attachmentOssIds` 字段 +2. **数据传递正常**: 数据通过 props 正确传递给了 `dialog.vue` 组件 +3. **附件处理缺失**: `dialog.vue` 中当弹窗打开时,只处理了学生信息,没有处理已有的附件数据 +4. **附件列表为空**: 导致 `attachmentList` 为空,附件无法在界面上显示 + +## 修复方案 + +### 1. 添加附件数据处理逻辑 + +在 `dialog.vue` 中添加了 `handleAttachmentData` 方法,用于处理已有的附件数据: + +```javascript +// 处理附件数据 +const handleAttachmentData = async () => { + try { + // 如果有附件ID,则获取附件信息 + if (props.form.attachmentOssIds && props.form.attachmentOssIds.toString().trim()) { + console.log('开始处理附件数据:', props.form.attachmentOssIds); + + // 调用接口获取附件信息 + const response = await request({ + url: '/resource/oss/listByIds', + method: 'get', + params: { + ossIds: props.form.attachmentOssIds + } + }); + + if (response.code === 200 && response.data) { + console.log('获取到的附件信息:', response.data); + + // 将附件信息转换为上传组件需要的格式 + const attachmentFiles = response.data.map((item: any, index: number) => ({ + uid: `existing_${index}_${Date.now()}`, + name: item.originalName || `附件${index + 1}`, + url: item.url, + ossId: item.ossId, + status: 'success', // 标记为已上传成功 + response: { + code: 200, + data: { + url: item.url, + ossId: item.ossId + } + } + })); + + // 设置附件列表 + attachmentList.value = attachmentFiles; + console.log('设置附件列表成功:', attachmentList.value); + } else { + console.warn('获取附件信息失败:', response.msg); + attachmentList.value = []; + } + } else { + console.log('没有附件数据,清空附件列表'); + attachmentList.value = []; + } + } catch (error) { + console.error('处理附件数据失败:', error); + ElMessage.error('获取附件信息失败,请稍后重试'); + attachmentList.value = []; + } +}; +``` + +### 2. 在弹窗打开时调用附件处理 + +修改了弹窗显示状态的监听器,在获取学生信息后调用附件处理: + +```javascript +// 监听弹窗显示状态,当弹窗打开时获取学生信息 +watch( + () => props.dialog.visible, + async (visible) => { + if (visible) { + console.log('弹窗打开,开始获取学生信息...'); + + // 获取当前登录用户的学生信息 + await getCurrentUserStudentInfo(); + + // 处理附件数据 + await handleAttachmentData(); + } + }, + { immediate: false } +); +``` + +### 3. 修复类型定义问题 + +添加了 `UploadFile` 接口定义,修复了类型错误: + +```typescript +// 扩展文件类型定义 +interface UploadFile { + uid: string; + name: string; + url?: string; + ossId?: string; + status?: string; + response?: any; + raw?: File; +} +``` + +### 4. 修复其他类型错误 + +- 修复了 `ElLoading` 的导入方式 +- 修复了 `attachmentList` 的类型定义 +- 修复了 `status` 字段问题,使用 `approvalStatus` 替代 + +## 修复效果 + +修复后,当点击修改按钮时: +1. ✅ 正确获取学生请假数据(包括附件ID) +2. ✅ 调用 `/resource/oss/listByIds` 接口获取附件详细信息 +3. ✅ 将附件信息转换为上传组件需要的格式 +4. ✅ 在附件上传区域正确显示已有的附件 +5. ✅ 支持附件的预览、下载、删除等操作 + +## 测试建议 + +1. **新增测试**: 新增学生请假申请,上传附件后保存 +2. **修改测试**: 点击修改按钮,验证附件是否正确显示 +3. **附件操作测试**: 验证附件的预览、下载、删除功能 +4. **边界测试**: 测试无附件、多个附件、附件格式异常等情况 + +## 相关文件 + +- `web/src/views/xg/xsjcxx/xsqj/index.vue` - 学生请假管理页面 +- `web/src/views/xg/xsjcxx/xsqj/dialog.vue` - 学生请假弹窗组件 +- `web/src/api/workflow/studentLeave/studentLeave/types.ts` - 类型定义文件 + +# 学生请假对话框接口调用修复记录 + +**变更时间**: 2025-01-27 15:30:00 +**变更人员**: Cursor AI +**变更类型**: 接口调用修复 + +## 🔧 变更内容 + +### 问题描述 +学生请假对话框(`web/src/views/xg/xsjcxx/xsqj/dialog.vue`)中调用附件信息接口时,使用了错误的请求方式。 + +### 问题分析 +1. **接口路径不匹配**: 前端使用查询参数方式调用 `/resource/oss/listByIds?ossIds=xxx` +2. **后端接口定义**: `SysOssController.java` 中的 `listByIds` 方法定义为路径参数 `/listByIds/{ossIds}` +3. **参数类型不匹配**: 后端需要 `Long[]` 数组,前端传递的是逗号分隔字符串 +4. **类型错误**: 文件上传组件存在TypeScript类型不兼容问题 + +### 修复方案 + +#### 1. 修复接口调用方式 +```javascript +// 修复前 +const response = await request({ + url: '/resource/oss/listByIds', + method: 'get', + params: { + ossIds: props.form.attachmentOssIds + } +}); + +// 修复后 - 处理逗号分隔字符串转数组 +const ossIdsArray = props.form.attachmentOssIds + .split(',') + .map((id) => id.trim()) + .filter((id) => id); + +const response = await request({ + url: `/resource/oss/listByIds/${ossIdsArray.join(',')}`, + method: 'get' +}); +``` + +#### 2. 修复TypeScript类型定义 +```typescript +// 简化类型定义,使用any[]避免类型冲突 +const attachmentList = ref([]); +``` + +#### 3. 修复文件下载类型转换 +```javascript +// 修复前 +const url = window.URL.createObjectURL(response as Blob); + +// 修复后 +const url = window.URL.createObjectURL(response.data as Blob); +``` + +## 📋 变更文件 + +### 主要修改文件 +- `web/src/views/xg/xsjcxx/xsqj/dialog.vue` + +### 修改行数 +- 第895-900行: 接口调用方式修复,添加字符串转数组处理 +- 第325行: TypeScript类型定义简化 +- 第570行: 文件下载类型转换修复 + +## ✅ 验证结果 + +### 功能验证 +- ✅ 附件信息获取接口调用正常 +- ✅ 文件上传组件类型兼容性解决 +- ✅ 文件下载功能正常工作 +- ✅ TypeScript编译错误消除 + +### 接口兼容性 +- ✅ 与后端 `SysOssController.listByIds` 接口完全匹配 +- ✅ 支持路径参数传递方式 +- ✅ 正确处理逗号分隔字符串转数组 +- ✅ 保持原有业务逻辑不变 + +## 🔄 影响范围 + +### 直接影响 +- 学生请假对话框的附件管理功能 +- 文件上传和下载功能 +- TypeScript类型检查 + +### 间接影响 +- 无其他模块影响 +- 保持向后兼容性 + +## 📝 技术要点 + +### 接口调用规范 +1. **路径参数**: 使用模板字符串拼接路径参数 +2. **查询参数**: 使用 `params` 对象传递查询参数 +3. **请求方式**: 根据后端接口定义选择合适的请求方式 +4. **参数转换**: 将逗号分隔字符串转换为数组格式传递给后端 + +### TypeScript类型扩展 +1. **模块声明**: 使用 `declare module` 扩展第三方库类型 +2. **接口合并**: 通过接口扩展添加自定义属性 +3. **类型安全**: 确保类型定义与实际使用一致 + +## 🎯 总结 + +本次修复解决了学生请假对话框中附件管理功能的接口调用问题,确保了前后端接口的正确对接,同时修复了TypeScript类型兼容性问题,提升了代码的类型安全性和可维护性。 + +**修复状态**: ✅ 已完成 +**测试状态**: ✅ 通过 +**部署状态**: ⏳ 待部署 diff --git a/docs/变更管理/code-adjust-record-2025-01-27-xgLeaveTypeConfig-dict-fix.md b/docs/变更管理/code-adjust-record-2025-01-27-xgLeaveTypeConfig-dict-fix.md new file mode 100644 index 00000000..b84e9d02 --- /dev/null +++ b/docs/变更管理/code-adjust-record-2025-01-27-xgLeaveTypeConfig-dict-fix.md @@ -0,0 +1,99 @@ +# 学生请假类型配置页面字典显示问题修复记录 + +## 修改时间 +2025-01-27 10:30:00 + +## 变更内容 +修复了学生请假类型配置管理页面中字典数据显示错误的问题。 + +## 变更原因 +通过分析发现,页面中使用了 `dict-tag` 组件显示字典数据,但缺少字典数据的加载,导致出现 `Cannot read properties of undefined (reading 'some')` 错误。 + +## 问题分析 +1. **错误信息**: `index.vue:61 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'some')` +2. **问题根因**: 页面中使用了 `sys_yesno` 字典,但没有通过 `useDict` 加载字典数据 +3. **影响范围**: 表格中的字典字段显示异常,表单中的字典选择器无法正常工作 + +## 解决方案 +1. **添加字典数据加载**: 在script部分添加 `sys_yesno` 字典的加载 +2. **修复表单选择器**: 将表单中的输入框改为下拉选择器,使用字典数据 + +## 变更详情 + +### 1. 添加字典数据加载 +**文件**: `web/src/views/xg/xsjcxx/xgLeaveTypeConfig/xgLeaveTypeConfig/index.vue` + +**添加内容**: +```javascript +// 加载字典数据 +const { sys_yesno } = toRefs( + proxy?.useDict('sys_yesno') +); +``` + +### 2. 修复表单选择器 +**修改前**: +```vue + + + +``` + +**修改后**: +```vue + + + + + +``` + +### 3. 添加必要的类型定义 +**添加内容**: +```typescript +interface DialogOption { + visible: boolean; + title: string; +} + +interface PageData { + form: T; + queryParams: Q; + rules: Record; +} +``` + +## 修复的字段 +- 请假是否需要上传地理位置 (needLocationOnApply) +- 销假是否必须上传照片 (needPhotoOnCancel) +- 销假是否需要上传地理位置 (needLocationOnCancel) +- 非离校请假是否需要销假 (needCancelForNonLeave) +- 是否可以提前请假 (canApplyInAdvance) +- 是否开启 (isEnabled) + +## 技术说明 +1. **字典数据**: 使用 `sys_yesno` 字典,值为 "0"-否,"1"-是 +2. **组件使用**: 表格中使用 `dict-tag` 组件,表单中使用 `el-select` 组件 +3. **数据格式**: 接口返回的数据为字符串类型("0"、"1"),与字典值匹配 + +## 验证结果 +- ✅ 表格中的字典字段正常显示(是/否) +- ✅ 表单中的下拉选择器正常工作 +- ✅ 新增和修改功能正常 +- ✅ 字典数据加载成功 + +## 相关文件 +- `web/src/views/xg/xsjcxx/xgLeaveTypeConfig/xgLeaveTypeConfig/index.vue` +- `web/src/api/xg/xsjcxx/xgLeaveTypeConfig/xgLeaveTypeConfig/index.ts` +- `web/src/api/xg/xsjcxx/xgLeaveTypeConfig/xgLeaveTypeConfig/types.ts` + +--- + +**修复人员**: Cursor AI +**审核状态**: 待审核 +**测试状态**: 待测试 \ No newline at end of file diff --git a/docs/设计文档/database/学生请假/README.md b/docs/设计文档/database/学生请假/README.md new file mode 100644 index 00000000..573aff14 --- /dev/null +++ b/docs/设计文档/database/学生请假/README.md @@ -0,0 +1,173 @@ +# 学生请假数据库设计 + +## 📋 概述 + +本目录包含学生请假管理系统的数据库设计文件,包括请假类型配置表和请假记录表。 + +## 📁 文件结构 + +``` +学生请假/ +├── README.md # 本说明文档 +├── xg_leave_type_config.sql # 请假类型配置表 +├── xg_student_leave.sql # 学生请假表 +└── xg_student_leave_sample_data.sql # 示例数据 +``` + +## 🗄️ 数据表设计 + +### 1. 请假类型配置表 (`xg_leave_type_config`) + +**功能**: 配置不同类型的请假规则和参数 + +**主要字段**: +- `leave_type_code`: 请假类型编码(如:PERSONAL_LEAVE、SICK_LEAVE) +- `leave_type_name`: 请假类型名称(如:事假、病假) +- `need_location_on_apply`: 请假是否需要上传地理位置 +- `need_photo_on_cancel`: 销假是否必须上传照片 +- `need_location_on_cancel`: 销假是否需要上传地理位置 +- `need_cancel_for_non_leave`: 非离校请假是否需要销假 +- `can_apply_in_advance`: 是否可以提前请假 +- `max_apply_duration`: 请假最大申请时长(天) +- `cancel_overdue_reminder`: 销假逾期提醒时长(天) + +### 2. 学生请假表 (`xg_student_leave`) + +**功能**: 记录学生的请假申请、审批和销假信息 + +**主要字段**: + +#### 基础信息 +- `student_id`: 学生ID +- `student_name`: 学生姓名 +- `student_no`: 学号 +- `class_id/class_name`: 班级信息 +- `major_id/major_name`: 专业信息 +- `college_id/college_name`: 学院信息 + +#### 请假信息 +- `leave_type_code/leave_type_name`: 请假类型 +- `start_time/end_time`: 开始/结束时间(年月日时分秒) +- `leave_duration`: 请假时长(天) +- `is_leave_school`: 是否离校(0-否,1-是) + +#### 联系信息 +- `emergency_contact`: 紧急联系人 +- `emergency_phone`: 紧急联系电话 + +#### 请假详情 +- `leave_reason`: 请假原因 +- `leave_location`: 请假时地理位置 +- `attachment_oss_ids`: 附件OSS文件ID(逗号分隔) + +#### 审批信息 +- `approval_status`: 审批状态(0-待审批,1-已通过,2-已拒绝,3-已取消) +- `approval_opinion`: 审批意见 +- `approval_time`: 审批时间 +- `approval_by/approval_by_name`: 审批人信息 + +#### 销假信息 +- `cancel_status`: 销假状态(0-未销假,1-已销假,2-逾期未销假) +- `cancel_time`: 销假时间 +- `cancel_location`: 销假地理位置 +- `cancel_photo_oss_ids`: 销假照片OSS文件ID +- `cancel_remark`: 销假备注 + +## 🔍 索引设计 + +### 单列索引 +- 租户索引:`idx_tenant_id` +- 学生索引:`idx_student_id` +- `student_no`: 学号 +- 班级索引:`idx_class_id` +- 学院索引:`idx_college_id` +- 请假类型索引:`idx_leave_type_code` +- 时间索引:`idx_start_time`、`idx_end_time` +- 状态索引:`idx_approval_status`、`idx_cancel_status` +- 创建时间索引:`idx_create_time` +- 离校状态索引:`idx_is_leave_school` + +### 复合索引 +- 学生+时间范围:`idx_student_time_range` +- 班级+审批状态:`idx_class_approval_status` +- 学院+请假类型:`idx_college_leave_type` +- 时间范围+审批状态:`idx_time_approval_status` + +## 📊 示例数据说明 + +示例数据包含8条不同类型的请假记录: + +1. **事假申请** - 已审批通过,未销假 +2. **病假申请** - 已审批通过,已销假 +3. **外出请假** - 待审批 +4. **回家请假** - 审批拒绝 +5. **其他请假** - 已审批通过,已销假 +6. **事假申请** - 待审批 +7. **病假申请** - 已审批通过,逾期未销假 +8. **外出请假** - 已取消 + +## 🔧 使用说明 + +### 1. 创建表结构 +```sql +-- 先创建请假类型配置表 +source xg_leave_type_config.sql; + +-- 再创建学生请假表 +source xg_student_leave.sql; +``` + +### 2. 插入示例数据 +```sql +-- 插入示例数据(可选) +source xg_student_leave_sample_data.sql; +``` + +### 3. 常见查询示例 + +#### 查询某个学生的请假记录 +```sql +SELECT * FROM xg_student_leave +WHERE student_id = 10001 +ORDER BY create_time DESC; +``` + +#### 查询待审批的请假申请 +```sql +SELECT * FROM xg_student_leave +WHERE approval_status = '0' +ORDER BY create_time ASC; +``` + +#### 查询逾期未销假的记录 +```sql +SELECT * FROM xg_student_leave +WHERE cancel_status = '2' +AND end_time < NOW(); +``` + +#### 按班级统计请假情况 +```sql +SELECT + class_name, + COUNT(*) as total_count, + SUM(CASE WHEN approval_status = '1' THEN 1 ELSE 0 END) as approved_count, + SUM(CASE WHEN approval_status = '2' THEN 1 ELSE 0 END) as rejected_count +FROM xg_student_leave +WHERE create_time >= DATE_SUB(NOW(), INTERVAL 30 DAY) +GROUP BY class_id, class_name; +``` + +## ⚠️ 注意事项 + +1. **基础字段规范**: 所有表都包含统一的基础字段(id、tenant_id、create_dept等) +2. **逻辑删除**: 使用`deleted`字段进行逻辑删除,禁止物理删除 +3. **多租户支持**: 所有表都包含`tenant_id`字段,支持多租户 +4. **外键约束**: 外键约束已注释,可根据实际需要启用 +5. **字符集**: 统一使用utf8mb4字符集,支持emoji等特殊字符 + +## 🔄 版本历史 + +- **2024-01-20**: 初始版本,创建请假类型配置表和请假记录表 +- **2024-01-21**: 添加示例数据和查询示例 +- **2024-01-22**: 完善索引设计和文档说明 \ No newline at end of file diff --git a/docs/设计文档/database/学生请假/xg_leave_type_config.sql b/docs/设计文档/database/学生请假/xg_leave_type_config.sql new file mode 100644 index 00000000..719cccfd --- /dev/null +++ b/docs/设计文档/database/学生请假/xg_leave_type_config.sql @@ -0,0 +1,48 @@ +-- ---------------------------- +-- 学生请假类型配置表 +-- ---------------------------- +DROP TABLE IF EXISTS `xg_leave_type_config`; +CREATE TABLE `xg_leave_type_config` ( + `id` bigint(20) NOT NULL COMMENT '主键ID(雪花ID)', + `tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号', + `create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门', + `create_by` bigint(20) DEFAULT NULL COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` bigint(20) DEFAULT NULL COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `deleted` tinyint(1) DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)', + + -- 业务字段 + `leave_type_name` varchar(50) NOT NULL COMMENT '请假类型名称', + `leave_type_code` varchar(20) NOT NULL COMMENT '请假类型编码', + `leave_type_desc` varchar(500) DEFAULT NULL COMMENT '请假类型描述', + `sort_order` int(4) DEFAULT '0' COMMENT '排序号', + + -- 配置字段(使用char类型) + `need_location_on_apply` char(1) NOT NULL DEFAULT '0' COMMENT '请假是否需要上传地理位置:0-否,1-是', + `need_photo_on_cancel` char(1) NOT NULL DEFAULT '0' COMMENT '销假是否必须上传照片:0-否,1-是', + `need_location_on_cancel` char(1) NOT NULL DEFAULT '0' COMMENT '销假是否需要上传地理位置:0-否,1-是', + `need_cancel_for_non_leave` char(1) NOT NULL DEFAULT '0' COMMENT '非离校请假是否需要销假:0-否,1-是', + `can_apply_in_advance` char(1) NOT NULL DEFAULT '0' COMMENT '是否可以提前请假:0-否,1-是', + `is_enabled` char(1) NOT NULL DEFAULT '1' COMMENT '是否开启:0-关闭,1-开启', + + -- 数值配置字段 + `max_apply_duration` decimal(5,2) DEFAULT NULL COMMENT '请假最大申请时长(天)', + `cancel_overdue_reminder` decimal(5,2) DEFAULT NULL COMMENT '销假逾期多少时长给予提醒(天)', + + PRIMARY KEY (`id`) USING BTREE, + UNIQUE KEY `uk_leave_type_code` (`leave_type_code`, `tenant_id`) USING BTREE COMMENT '请假类型编码唯一索引', + KEY `idx_tenant_id` (`tenant_id`) USING BTREE COMMENT '租户索引', + KEY `idx_is_enabled` (`is_enabled`) USING BTREE COMMENT '启用状态索引', + KEY `idx_sort_order` (`sort_order`) USING BTREE COMMENT '排序索引' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='学生请假类型配置表'; + +-- ---------------------------- +-- 初始化数据 +-- ---------------------------- +INSERT INTO `xg_leave_type_config` VALUES +(1, '000000', 103, 1, NOW(), NULL, NULL, 0, '事假', 'PERSONAL_LEAVE', '因个人事务需要请假', 1, '0', '0', '0', '0', '1', '1', 72, 24), +(2, '000000', 103, 1, NOW(), NULL, NULL, 0, '病假', 'SICK_LEAVE', '因身体不适需要请假', 2, '0', '1', '0', '1', '1', '1', 168, 48), +(3, '000000', 103, 1, NOW(), NULL, NULL, 0, '外出请假', 'OUT_LEAVE', '因外出办事需要请假', 3, '1', '1', '1', '1', '1', '1', 24, 2), +(4, '000000', 103, 1, NOW(), NULL, NULL, 0, '回家请假', 'HOME_LEAVE', '因回家需要请假', 4, '1', '1', '1', '1', '1', '1', 72, 6), +(5, '000000', 103, 1, NOW(), NULL, NULL, 0, '其他请假', 'OTHER_LEAVE', '其他原因请假', 5, '0', '0', '0', '0', '1', '1', 48, 12); \ No newline at end of file diff --git a/docs/设计文档/database/学生请假/xg_student_leave.sql b/docs/设计文档/database/学生请假/xg_student_leave.sql new file mode 100644 index 00000000..b6700027 --- /dev/null +++ b/docs/设计文档/database/学生请假/xg_student_leave.sql @@ -0,0 +1,101 @@ +-- ---------------------------- +-- 学生请假表 +-- ---------------------------- +DROP TABLE IF EXISTS `xg_student_leave`; +CREATE TABLE `xg_student_leave` ( + `id` bigint(20) NOT NULL COMMENT '主键ID(雪花ID)', + `tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号', + `create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门', + `create_by` bigint(20) DEFAULT NULL COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_by` bigint(20) DEFAULT NULL COMMENT '更新者', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `deleted` tinyint(1) DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)', + + -- 业务字段 + `student_id` bigint(20) NOT NULL COMMENT '学生ID', + `student_name` varchar(50) NOT NULL COMMENT '学生姓名', + `student_no` varchar(20) NOT NULL COMMENT '学号', + `class_id` bigint(20) DEFAULT NULL COMMENT '班级ID', + `class_name` varchar(100) DEFAULT NULL COMMENT '班级名称', + `major_id` bigint(20) DEFAULT NULL COMMENT '专业ID', + `major_name` varchar(100) DEFAULT NULL COMMENT '专业名称', + `college_id` bigint(20) DEFAULT NULL COMMENT '学院ID', + `college_name` varchar(100) DEFAULT NULL COMMENT '学院名称', + + -- 请假信息 + `leave_type_code` varchar(20) NOT NULL COMMENT '请假类型编码', + `leave_type_name` varchar(50) NOT NULL COMMENT '请假类型名称', + `start_time` datetime NOT NULL COMMENT '开始时间(年月日时分秒)', + `end_time` datetime NOT NULL COMMENT '结束时间(年月日时分秒)', + `leave_duration` decimal(5,2) NOT NULL COMMENT '请假时长(天)', + `is_leave_school` char(1) NOT NULL DEFAULT '0' COMMENT '是否离校:0-否,1-是', + `need_cancel` char(1) NOT NULL DEFAULT '1' COMMENT '是否需要销假:0-否,1-是', + + -- 紧急联系人信息 + `emergency_contact` varchar(50) DEFAULT NULL COMMENT '紧急联系人', + `emergency_phone` varchar(20) DEFAULT NULL COMMENT '紧急联系电话', + + -- 请假原因和位置 + `leave_reason` text NOT NULL COMMENT '请假原因', + `leave_location` varchar(500) DEFAULT NULL COMMENT '请假时地理位置', + `attachment_oss_ids` text DEFAULT NULL COMMENT '附件OSS文件ID(逗号分隔)', + + -- 审批状态 + `approval_status` char(1) NOT NULL DEFAULT '0' COMMENT '审批状态:0-待审批,1-已通过,2-已拒绝,3-已取消', + `approval_opinion` varchar(500) DEFAULT NULL COMMENT '审批意见', + `approval_time` datetime DEFAULT NULL COMMENT '审批时间', + `approval_by` bigint(20) DEFAULT NULL COMMENT '审批人ID', + `approval_by_name` varchar(50) DEFAULT NULL COMMENT '审批人姓名', + + -- 销假信息 + `cancel_status` char(1) NOT NULL DEFAULT '0' COMMENT '销假状态:0-未销假,1-已销假,2-逾期未销假', + `cancel_time` datetime DEFAULT NULL COMMENT '销假时间', + `cancel_location` varchar(500) DEFAULT NULL COMMENT '销假地理位置', + `cancel_photo_oss_ids` text DEFAULT NULL COMMENT '销假照片OSS文件ID(逗号分隔)', + `cancel_remark` varchar(500) DEFAULT NULL COMMENT '销假备注', + + PRIMARY KEY (`id`) USING BTREE, + KEY `idx_tenant_id` (`tenant_id`) USING BTREE COMMENT '租户索引', + KEY `idx_student_id` (`student_id`) USING BTREE COMMENT '学生索引', + KEY `idx_student_no` (`student_no`) USING BTREE COMMENT '学号索引', + KEY `idx_class_id` (`class_id`) USING BTREE COMMENT '班级索引', + KEY `idx_college_id` (`college_id`) USING BTREE COMMENT '学院索引', + KEY `idx_leave_type_code` (`leave_type_code`) USING BTREE COMMENT '请假类型索引', + KEY `idx_start_time` (`start_time`) USING BTREE COMMENT '开始时间索引', + KEY `idx_end_time` (`end_time`) USING BTREE COMMENT '结束时间索引', + KEY `idx_approval_status` (`approval_status`) USING BTREE COMMENT '审批状态索引', + KEY `idx_cancel_status` (`cancel_status`) USING BTREE COMMENT '销假状态索引', + KEY `idx_create_time` (`create_time`) USING BTREE COMMENT '创建时间索引', + KEY `idx_is_leave_school` (`is_leave_school`) USING BTREE COMMENT '离校状态索引', + KEY `idx_need_cancel` (`need_cancel`) USING BTREE COMMENT '是否需要销假索引' +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='学生请假表'; + +-- ---------------------------- +-- 创建索引 +-- ---------------------------- +-- 复合索引:学生+时间范围查询 +CREATE INDEX `idx_student_time_range` ON `xg_student_leave` (`student_id`, `start_time`, `end_time`); + +-- 复合索引:班级+审批状态查询 +CREATE INDEX `idx_class_approval_status` ON `xg_student_leave` (`class_id`, `approval_status`); + +-- 复合索引:学院+请假类型查询 +CREATE INDEX `idx_college_leave_type` ON `xg_student_leave` (`college_id`, `leave_type_code`); + +-- 复合索引:时间范围+审批状态查询 +CREATE INDEX `idx_time_approval_status` ON `xg_student_leave` (`start_time`, `end_time`, `approval_status`); + +-- 复合索引:是否需要销假+销假状态查询 +CREATE INDEX `idx_need_cancel_status` ON `xg_student_leave` (`need_cancel`, `cancel_status`); + +-- ---------------------------- +-- 添加外键约束(可选,根据实际需要启用) +-- ---------------------------- +-- ALTER TABLE `xg_student_leave` ADD CONSTRAINT `fk_student_leave_type` +-- FOREIGN KEY (`leave_type_code`) REFERENCES `xg_leave_type_config` (`leave_type_code`) ON DELETE RESTRICT ON UPDATE CASCADE; + +-- ---------------------------- +-- 添加注释 +-- ---------------------------- +ALTER TABLE `xg_student_leave` COMMENT = '学生请假表 - 记录学生的请假申请、审批和销假信息'; \ No newline at end of file diff --git a/docs/设计文档/database/学生请假/xg_student_leave_sample_data.sql b/docs/设计文档/database/学生请假/xg_student_leave_sample_data.sql new file mode 100644 index 00000000..202c04d8 --- /dev/null +++ b/docs/设计文档/database/学生请假/xg_student_leave_sample_data.sql @@ -0,0 +1,91 @@ +-- ---------------------------- +-- 学生请假表示例数据 +-- ---------------------------- + +-- 示例数据1:事假申请 +INSERT INTO `xg_student_leave` VALUES ( + 1001, '000000', 103, 1, '2024-01-15 10:30:00', NULL, NULL, 0, + 10001, '张三', '2024001', 101, '计算机科学与技术1班', 1, '计算机科学与技术', 1, '信息工程学院', + 'PERSONAL_LEAVE', '事假', '2024-01-20 08:00:00', '2024-01-21 18:00:00', 2.00, '0', + '李四', '13800138001', + '家中有急事需要处理,特此请假。', '北京市海淀区中关村大街1号', 'oss_file_001,oss_file_002', + '1', '同意请假,请按时返校。', '2024-01-16 14:20:00', 1001, '王老师', + '0', NULL, NULL, NULL, NULL +); + +-- 示例数据2:病假申请 +INSERT INTO `xg_student_leave` VALUES ( + 1002, '000000', 103, 1, '2024-01-16 09:15:00', NULL, NULL, 0, + 10002, '李四', '2024002', 101, '计算机科学与技术1班', 1, '计算机科学与技术', 1, '信息工程学院', + 'SICK_LEAVE', '病假', '2024-01-17 00:00:00', '2024-01-19 23:59:59', 3.00, '0', + '王五', '13800138002', + '感冒发烧,需要休息治疗。', '北京市朝阳区建国路2号', 'oss_file_003', + '1', '同意病假,注意休息。', '2024-01-16 16:30:00', 1001, '王老师', + '1', '2024-01-20 08:30:00', '北京市朝阳区建国路2号', 'oss_file_004', '已康复返校' +); + +-- 示例数据3:外出请假申请 +INSERT INTO `xg_student_leave` VALUES ( + 1003, '000000', 103, 1, '2024-01-17 14:20:00', NULL, NULL, 0, + 10003, '王五', '2024003', 102, '软件工程1班', 2, '软件工程', 1, '信息工程学院', + 'OUT_LEAVE', '外出请假', '2024-01-18 14:00:00', '2024-01-18 18:00:00', 0.17, '1', + '赵六', '13800138003', + '需要外出办理身份证业务。', '北京市西城区西单大街3号', 'oss_file_005', + '0', NULL, NULL, NULL, NULL, + '0', NULL, NULL, NULL, NULL +); + +-- 示例数据4:回家请假申请 +INSERT INTO `xg_student_leave` VALUES ( + 1004, '000000', 103, 1, '2024-01-18 11:00:00', NULL, NULL, 0, + 10004, '赵六', '2024004', 102, '软件工程1班', 2, '软件工程', 1, '信息工程学院', + 'HOME_LEAVE', '回家请假', '2024-01-25 16:00:00', '2024-01-27 20:00:00', 2.17, '1', + '钱七', '13800138004', + '回家参加亲戚婚礼。', '上海市浦东新区陆家嘴4号', 'oss_file_006,oss_file_007', + '2', '请假时间过长,建议缩短。', '2024-01-19 10:15:00', 1001, '王老师', + '0', NULL, NULL, NULL, NULL +); + +-- 示例数据5:其他请假申请 +INSERT INTO `xg_student_leave` VALUES ( + 1005, '000000', 103, 1, '2024-01-19 16:45:00', NULL, NULL, 0, + 10005, '钱七', '2024005', 103, '网络工程1班', 3, '网络工程', 1, '信息工程学院', + 'OTHER_LEAVE', '其他请假', '2024-01-22 09:00:00', '2024-01-22 12:00:00', 0.13, '0', + '孙八', '13800138005', + '参加学校组织的志愿者活动。', '北京市海淀区清华园5号', 'oss_file_008', + '1', '同意参加志愿者活动。', '2024-01-20 09:30:00', 1001, '王老师', + '1', '2024-01-22 12:30:00', '北京市海淀区清华园5号', 'oss_file_009', '活动完成返校' +); + +-- 示例数据6:待审批的请假申请 +INSERT INTO `xg_student_leave` VALUES ( + 1006, '000000', 103, 1, '2024-01-20 08:30:00', NULL, NULL, 0, + 10006, '孙八', '2024006', 103, '网络工程1班', 3, '网络工程', 1, '信息工程学院', + 'PERSONAL_LEAVE', '事假', '2024-01-23 08:00:00', '2024-01-24 18:00:00', 2.00, '0', + '周九', '13800138006', + '需要参加驾照考试。', '北京市丰台区南四环6号', 'oss_file_010', + '0', NULL, NULL, NULL, NULL, + '0', NULL, NULL, NULL, NULL +); + +-- 示例数据7:逾期未销假的请假记录 +INSERT INTO `xg_student_leave` VALUES ( + 1007, '000000', 103, 1, '2024-01-10 10:00:00', NULL, NULL, 0, + 10007, '周九', '2024007', 104, '信息安全1班', 4, '信息安全', 1, '信息工程学院', + 'SICK_LEAVE', '病假', '2024-01-11 00:00:00', '2024-01-13 23:59:59', 3.00, '0', + '吴十', '13800138007', + '肠胃炎,需要住院治疗。', '北京市昌平区回龙观7号', 'oss_file_011', + '1', '同意病假,注意身体。', '2024-01-10 15:00:00', 1001, '王老师', + '2', NULL, NULL, NULL, '逾期未销假' +); + +-- 示例数据8:已取消的请假申请 +INSERT INTO `xg_student_leave` VALUES ( + 1008, '000000', 103, 1, '2024-01-21 13:20:00', 1001, '2024-01-21 15:30:00', 0, + 10008, '吴十', '2024008', 104, '信息安全1班', 4, '信息安全', 1, '信息工程学院', + 'OUT_LEAVE', '外出请假', '2024-01-22 14:00:00', '2024-01-22 17:00:00', 0.13, '1', + '郑十一', '13800138008', + '需要外出办理银行卡业务。', '北京市东城区王府井8号', 'oss_file_012', + '3', '学生主动取消申请。', '2024-01-21 15:30:00', 1001, '王老师', + '0', NULL, NULL, NULL, NULL +); \ No newline at end of file diff --git a/web/src/api/workflow/studentLeave/studentLeave/index.ts b/web/src/api/workflow/studentLeave/studentLeave/index.ts new file mode 100644 index 00000000..0a447c85 --- /dev/null +++ b/web/src/api/workflow/studentLeave/studentLeave/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { StudentLeaveVO, StudentLeaveForm, StudentLeaveQuery } from '@/api/workflow/studentLeave/studentLeave/types'; + +/** + * 查询学生请假 - 记录学生的请假申请、审批和销假信息列表 + * @param query + * @returns {*} + */ + +export const listStudentLeave = (query?: StudentLeaveQuery): AxiosPromise => { + return request({ + url: '/studentLeave/studentLeave/list', + method: 'get', + params: query + }); +}; + +/** + * 查询学生请假 - 记录学生的请假申请、审批和销假信息详细 + * @param id + */ +export const getStudentLeave = (id: string | number): AxiosPromise => { + return request({ + url: '/studentLeave/studentLeave/' + id, + method: 'get' + }); +}; + +/** + * 新增学生请假 - 记录学生的请假申请、审批和销假信息 + * @param data + */ +export const addStudentLeave = (data: StudentLeaveForm) => { + return request({ + url: '/studentLeave/studentLeave', + method: 'post', + data: data + }); +}; + +/** + * 修改学生请假 - 记录学生的请假申请、审批和销假信息 + * @param data + */ +export const updateStudentLeave = (data: StudentLeaveForm) => { + return request({ + url: '/studentLeave/studentLeave', + method: 'put', + data: data + }); +}; + +/** + * 删除学生请假 - 记录学生的请假申请、审批和销假信息 + * @param id + */ +export const delStudentLeave = (id: string | number | Array) => { + return request({ + url: '/studentLeave/studentLeave/' + id, + method: 'delete' + }); +}; diff --git a/web/src/api/workflow/studentLeave/studentLeave/types.ts b/web/src/api/workflow/studentLeave/studentLeave/types.ts new file mode 100644 index 00000000..44545480 --- /dev/null +++ b/web/src/api/workflow/studentLeave/studentLeave/types.ts @@ -0,0 +1,511 @@ +export interface StudentLeaveVO { + /** + * 主键ID(雪花ID) + */ + id: string | number; + + /** + * 删除标志(0代表存在 1代表删除) + */ + deleted: number; + + /** + * 学生ID + */ + studentId: string | number; + + /** + * 学生姓名 + */ + studentName: string; + + /** + * 学号 + */ + studentNo: string; + + /** + * 班级ID + */ + classId: string | number; + + /** + * 班级名称 + */ + className: string; + + /** + * 专业ID + */ + majorId: string | number; + + /** + * 专业名称 + */ + majorName: string; + + /** + * 学院ID + */ + collegeId: string | number; + + /** + * 学院名称 + */ + collegeName: string; + + /** + * 请假类型编码 + */ + leaveTypeCode: string; + + /** + * 请假类型名称 + */ + leaveTypeName: string; + + /** + * 开始时间(年月日时分秒) + */ + startTime: string; + + /** + * 结束时间(年月日时分秒) + */ + endTime: string; + + /** + * 请假时长(天) + */ + leaveDuration: number; + + /** + * 是否离校:0-否,1-是 + */ + isLeaveSchool: string; + + /** + * 是否需要销假:0-否,1-是 + */ + needCancel: string; + + /** + * 紧急联系人 + */ + emergencyContact: string; + + /** + * 紧急联系电话 + */ + emergencyPhone: string; + + /** + * 请假原因 + */ + leaveReason: string; + + /** + * 请假时地理位置 + */ + leaveLocation: string; + + /** + * 附件OSS文件ID(逗号分隔) + */ + attachmentOssIds: string | number; + + /** + * 审批状态:0-待审批,1-已通过,2-已拒绝,3-已取消 + */ + approvalStatus: string; + + /** + * 审批意见 + */ + approvalOpinion: string; + + /** + * 审批时间 + */ + approvalTime: string; + + /** + * 审批人ID + */ + approvalBy: number; + + /** + * 审批人姓名 + */ + approvalByName: string; + + /** + * 销假状态:0-未销假,1-已销假,2-逾期未销假 + */ + cancelStatus: string; + + /** + * 销假时间 + */ + cancelTime: string; + + /** + * 销假地理位置 + */ + cancelLocation: string; + + /** + * 销假照片OSS文件ID(逗号分隔) + */ + cancelPhotoOssIds: string | number; + + /** + * 销假备注 + */ + cancelRemark: string; + +} + +export interface StudentLeaveForm extends BaseEntity { + /** + * 主键ID(雪花ID) + */ + id?: string | number; + + /** + * 删除标志(0代表存在 1代表删除) + */ + deleted?: number; + + /** + * 学生ID + */ + studentId?: string | number; + + /** + * 学生姓名 + */ + studentName?: string; + + /** + * 学号 + */ + studentNo?: string; + + /** + * 班级ID + */ + classId?: string | number; + + /** + * 班级名称 + */ + className?: string; + + /** + * 专业ID + */ + majorId?: string | number; + + /** + * 专业名称 + */ + majorName?: string; + + /** + * 学院ID + */ + collegeId?: string | number; + + /** + * 学院名称 + */ + collegeName?: string; + + /** + * 请假类型编码 + */ + leaveTypeCode?: string; + + /** + * 请假类型名称 + */ + leaveTypeName?: string; + + /** + * 开始时间(年月日时分秒) + */ + startTime?: string; + + /** + * 结束时间(年月日时分秒) + */ + endTime?: string; + + /** + * 请假时长(天) + */ + leaveDuration?: number; + + /** + * 是否离校:0-否,1-是 + */ + isLeaveSchool?: string; + + /** + * 是否需要销假:0-否,1-是 + */ + needCancel?: string; + + /** + * 紧急联系人 + */ + emergencyContact?: string; + + /** + * 紧急联系电话 + */ + emergencyPhone?: string; + + /** + * 请假原因 + */ + leaveReason?: string; + + /** + * 请假时地理位置 + */ + leaveLocation?: string; + + /** + * 附件OSS文件ID(逗号分隔) + */ + attachmentOssIds?: string | number; + + /** + * 审批状态:0-待审批,1-已通过,2-已拒绝,3-已取消 + */ + approvalStatus?: string; + + /** + * 审批意见 + */ + approvalOpinion?: string; + + /** + * 审批时间 + */ + approvalTime?: string; + + /** + * 审批人ID + */ + approvalBy?: number; + + /** + * 审批人姓名 + */ + approvalByName?: string; + + /** + * 销假状态:0-未销假,1-已销假,2-逾期未销假 + */ + cancelStatus?: string; + + /** + * 销假时间 + */ + cancelTime?: string; + + /** + * 销假地理位置 + */ + cancelLocation?: string; + + /** + * 销假照片OSS文件ID(逗号分隔) + */ + cancelPhotoOssIds?: string | number; + + /** + * 销假备注 + */ + cancelRemark?: string; + + /** + * 操作类型:add-新增,update-修改,view-查看 + */ + type?: string; + +} + +export interface StudentLeaveQuery extends PageQuery { + + /** + * 删除标志(0代表存在 1代表删除) + */ + deleted?: number; + + /** + * 学生ID + */ + studentId?: string | number; + + /** + * 学生姓名 + */ + studentName?: string; + + /** + * 学号 + */ + studentNo?: string; + + /** + * 班级ID + */ + classId?: string | number; + + /** + * 班级名称 + */ + className?: string; + + /** + * 专业ID + */ + majorId?: string | number; + + /** + * 专业名称 + */ + majorName?: string; + + /** + * 学院ID + */ + collegeId?: string | number; + + /** + * 学院名称 + */ + collegeName?: string; + + /** + * 请假类型编码 + */ + leaveTypeCode?: string; + + /** + * 请假类型名称 + */ + leaveTypeName?: string; + + /** + * 开始时间(年月日时分秒) + */ + startTime?: string; + + /** + * 结束时间(年月日时分秒) + */ + endTime?: string; + + /** + * 请假时长(天) + */ + leaveDuration?: number; + + /** + * 是否离校:0-否,1-是 + */ + isLeaveSchool?: string; + + /** + * 是否需要销假:0-否,1-是 + */ + needCancel?: string; + + /** + * 紧急联系人 + */ + emergencyContact?: string; + + /** + * 紧急联系电话 + */ + emergencyPhone?: string; + + /** + * 请假原因 + */ + leaveReason?: string; + + /** + * 请假时地理位置 + */ + leaveLocation?: string; + + /** + * 附件OSS文件ID(逗号分隔) + */ + attachmentOssIds?: string | number; + + /** + * 审批状态:0-待审批,1-已通过,2-已拒绝,3-已取消 + */ + approvalStatus?: string; + + /** + * 审批意见 + */ + approvalOpinion?: string; + + /** + * 审批时间 + */ + approvalTime?: string; + + /** + * 审批人ID + */ + approvalBy?: number; + + /** + * 审批人姓名 + */ + approvalByName?: string; + + /** + * 销假状态:0-未销假,1-已销假,2-逾期未销假 + */ + cancelStatus?: string; + + /** + * 销假时间 + */ + cancelTime?: string; + + /** + * 销假地理位置 + */ + cancelLocation?: string; + + /** + * 销假照片OSS文件ID(逗号分隔) + */ + cancelPhotoOssIds?: string | number; + + /** + * 销假备注 + */ + cancelRemark?: string; + + /** + * 日期范围参数 + */ + params?: any; +} + + + diff --git a/web/src/api/xg/xsjcxx/xgLeaveTypeConfig/xgLeaveTypeConfig/index.ts b/web/src/api/xg/xsjcxx/xgLeaveTypeConfig/xgLeaveTypeConfig/index.ts new file mode 100644 index 00000000..85b8d3e8 --- /dev/null +++ b/web/src/api/xg/xsjcxx/xgLeaveTypeConfig/xgLeaveTypeConfig/index.ts @@ -0,0 +1,63 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { XgLeaveTypeConfigVO, XgLeaveTypeConfigForm, XgLeaveTypeConfigQuery } from '@/api/xg/xsjcxx/xgLeaveTypeConfig/xgLeaveTypeConfig/types'; + +/** + * 查询学生请假类型配置列表 + * @param query + * @returns {*} + */ + +export const listXgLeaveTypeConfig = (query?: XgLeaveTypeConfigQuery): AxiosPromise => { + return request({ + url: '/xgLeaveTypeConfig/xgLeaveTypeConfig/list', + method: 'get', + params: query + }); +}; + +/** + * 查询学生请假类型配置详细 + * @param id + */ +export const getXgLeaveTypeConfig = (id: string | number): AxiosPromise => { + return request({ + url: '/xgLeaveTypeConfig/xgLeaveTypeConfig/' + id, + method: 'get' + }); +}; + +/** + * 新增学生请假类型配置 + * @param data + */ +export const addXgLeaveTypeConfig = (data: XgLeaveTypeConfigForm) => { + return request({ + url: '/xgLeaveTypeConfig/xgLeaveTypeConfig', + method: 'post', + data: data + }); +}; + +/** + * 修改学生请假类型配置 + * @param data + */ +export const updateXgLeaveTypeConfig = (data: XgLeaveTypeConfigForm) => { + return request({ + url: '/xgLeaveTypeConfig/xgLeaveTypeConfig', + method: 'put', + data: data + }); +}; + +/** + * 删除学生请假类型配置 + * @param id + */ +export const delXgLeaveTypeConfig = (id: string | number | Array) => { + return request({ + url: '/xgLeaveTypeConfig/xgLeaveTypeConfig/' + id, + method: 'delete' + }); +}; diff --git a/web/src/api/xg/xsjcxx/xgLeaveTypeConfig/xgLeaveTypeConfig/types.ts b/web/src/api/xg/xsjcxx/xgLeaveTypeConfig/xgLeaveTypeConfig/types.ts new file mode 100644 index 00000000..09566afc --- /dev/null +++ b/web/src/api/xg/xsjcxx/xgLeaveTypeConfig/xgLeaveTypeConfig/types.ts @@ -0,0 +1,166 @@ +export interface XgLeaveTypeConfigVO { + /** + * 主键ID(雪花ID) + */ + id: string | number; + + /** + * 请假类型名称 + */ + leaveTypeName: string; + + /** + * 请假类型编码 + */ + leaveTypeCode: string; + + /** + * 请假类型描述 + */ + leaveTypeDesc: string; + + /** + * 排序号 + */ + sortOrder: number; + + /** + * 请假是否需要上传地理位置:0-否,1-是 + */ + needLocationOnApply: string; + + /** + * 销假是否必须上传照片:0-否,1-是 + */ + needPhotoOnCancel: string; + + /** + * 销假是否需要上传地理位置:0-否,1-是 + */ + needLocationOnCancel: string; + + /** + * 非离校请假是否需要销假:0-否,1-是 + */ + needCancelForNonLeave: string; + + /** + * 是否可以提前请假:0-否,1-是 + */ + canApplyInAdvance: string; + + /** + * 是否开启:0-关闭,1-开启 + */ + isEnabled: string; + + /** + * 请假最大申请时长(天) + */ + maxApplyDuration: number; + + /** + * 销假逾期多少时长给予提醒(天) + */ + cancelOverdueReminder: number; + +} + +export interface XgLeaveTypeConfigForm extends BaseEntity { + /** + * 主键ID(雪花ID) + */ + id?: string | number; + + /** + * 请假类型名称 + */ + leaveTypeName?: string; + + /** + * 请假类型编码 + */ + leaveTypeCode?: string; + + /** + * 请假类型描述 + */ + leaveTypeDesc?: string; + + /** + * 排序号 + */ + sortOrder?: number; + + /** + * 请假是否需要上传地理位置:0-否,1-是 + */ + needLocationOnApply?: string; + + /** + * 销假是否必须上传照片:0-否,1-是 + */ + needPhotoOnCancel?: string; + + /** + * 销假是否需要上传地理位置:0-否,1-是 + */ + needLocationOnCancel?: string; + + /** + * 非离校请假是否需要销假:0-否,1-是 + */ + needCancelForNonLeave?: string; + + /** + * 是否可以提前请假:0-否,1-是 + */ + canApplyInAdvance?: string; + + /** + * 是否开启:0-关闭,1-开启 + */ + isEnabled?: string; + + /** + * 请假最大申请时长(天) + */ + maxApplyDuration?: number; + + /** + * 销假逾期多少时长给予提醒(天) + */ + cancelOverdueReminder?: number; + +} + +export interface XgLeaveTypeConfigQuery extends PageQuery { + + /** + * 删除标志(0代表存在 1代表删除) + */ + deleted?: number; + + /** + * 请假类型名称 + */ + leaveTypeName?: string; + + /** + * 请假类型编码 + */ + leaveTypeCode?: string; + + /** + * 是否开启:0-关闭,1-开启 + */ + isEnabled?: string; + + /** + * 日期范围参数 + */ + params?: any; +} + + + diff --git a/web/src/components/Process/approvalButton.vue b/web/src/components/Process/approvalButton.vue index cb4fe8dd..ed92284a 100644 --- a/web/src/components/Process/approvalButton.vue +++ b/web/src/components/Process/approvalButton.vue @@ -7,9 +7,9 @@ 流程进度 -
+
diff --git a/web/src/views/xg/xsjcxx/xsqj/index-bak.vue b/web/src/views/xg/xsjcxx/xsqj/index-bak.vue new file mode 100644 index 00000000..e53b0c7e --- /dev/null +++ b/web/src/views/xg/xsjcxx/xsqj/index-bak.vue @@ -0,0 +1,236 @@ + + + diff --git a/web/src/views/xg/xsjcxx/xsqj/index.vue b/web/src/views/xg/xsjcxx/xsqj/index.vue index e53b0c7e..3daff663 100644 --- a/web/src/views/xg/xsjcxx/xsqj/index.vue +++ b/web/src/views/xg/xsjcxx/xsqj/index.vue @@ -1,20 +1,143 @@ - + + diff --git a/web/src/views/xg/xsjcxx/xsqj/leaveEdit-bak.vue b/web/src/views/xg/xsjcxx/xsqj/leaveEdit-bak.vue new file mode 100644 index 00000000..6471d46f --- /dev/null +++ b/web/src/views/xg/xsjcxx/xsqj/leaveEdit-bak.vue @@ -0,0 +1,314 @@ + + +