diff --git a/backend/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application-prod.yml b/backend/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application-prod.yml new file mode 100644 index 00000000..108a203e --- /dev/null +++ b/backend/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application-prod.yml @@ -0,0 +1,48 @@ +server: + port: 9090 +spring: + application: + name: ruoyi-monitor-admin + profiles: + active: @profiles.active@ + +logging: + config: classpath:logback-plus.xml + +--- # 监控中心服务端配置 +spring: + security: + user: + name: @monitor.username@ + password: @monitor.password@ + boot: + admin: + ui: + title: RuoYi-Vue-Plus服务监控中心 + context-path: /admin + +--- # Actuator 监控端点的配置项 +management: + endpoints: + web: + exposure: + include: '*' + endpoint: + health: + show-details: ALWAYS + logfile: + external-file: ./logs/ruoyi-monitor-admin.log + +--- # 监控配置 +spring.boot.admin.client: + # 增加客户端开关 + enabled: true + # 设置 Spring Boot Admin Server 地址 + url: http://172.16.0.67:9090/admin + instance: + service-host-type: IP + metadata: + username: ${spring.boot.admin.client.username} + userpassword: ${spring.boot.admin.client.password} + username: @monitor.username@ + password: @monitor.password@ diff --git a/backend/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml b/backend/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml index 108a203e..86766d7a 100644 --- a/backend/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml +++ b/backend/ruoyi-extend/ruoyi-monitor-admin/src/main/resources/application.yml @@ -38,7 +38,7 @@ spring.boot.admin.client: # 增加客户端开关 enabled: true # 设置 Spring Boot Admin Server 地址 - url: http://172.16.0.67:9090/admin + url: http://127.0.0.1:9090/admin instance: service-host-type: IP metadata: diff --git a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/BackProcessBo.java b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/BackProcessBo.java index 654bf080..9317c487 100644 --- a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/BackProcessBo.java +++ b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/BackProcessBo.java @@ -1,6 +1,5 @@ package org.dromara.workflow.domain.bo; -import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.Data; import org.dromara.common.core.validate.AddGroup; @@ -12,7 +11,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; - /** * 驳回参数请求 * @@ -50,6 +48,11 @@ public class BackProcessBo implements Serializable { */ private String message; + /** + * 手写签名(Base64编码的图片数据) + */ + private String signature; + /** * 通知 */ diff --git a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/CompleteTaskBo.java b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/CompleteTaskBo.java index e5befff7..7af84053 100644 --- a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/CompleteTaskBo.java +++ b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/bo/CompleteTaskBo.java @@ -25,7 +25,7 @@ public class CompleteTaskBo implements Serializable { /** * 任务id */ - @NotNull(message = "任务id不能为空", groups = {AddGroup.class}) + @NotNull(message = "任务id不能为空", groups = { AddGroup.class }) private Long taskId; /** @@ -48,6 +48,11 @@ public class CompleteTaskBo implements Serializable { */ private String message; + /** + * 手写签名(Base64编码的图片数据) + */ + private String signature; + /** * 消息通知 */ diff --git a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowHisTaskVo.java b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowHisTaskVo.java index 8776a76b..026405ca 100644 --- a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowHisTaskVo.java +++ b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/domain/vo/FlowHisTaskVo.java @@ -151,6 +151,11 @@ public class FlowHisTaskVo implements Serializable { */ private String message; + /** + * 手写签名(Base64编码的图片数据) + */ + private String signature; + /** * 业务详情 存业务类的json */ diff --git a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/FlwHisTaskExtMapper.java b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/FlwHisTaskExtMapper.java new file mode 100644 index 00000000..36bbcee0 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/mapper/FlwHisTaskExtMapper.java @@ -0,0 +1,48 @@ +package org.dromara.workflow.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Update; +import org.dromara.workflow.domain.vo.FlowHisTaskVo; + +import java.util.List; + +/** + * 历史任务扩展Mapper + * 用于处理Warm-Flow框架不支持的自定义字段 + * + * @author System + */ +@Mapper +public interface FlwHisTaskExtMapper { + + /** + * 更新历史任务的签名字段 + * + * @param taskId 任务ID + * @param signature 签名数据(Base64) + * @return 影响行数 + */ + @Update("UPDATE flow_his_task SET signature = #{signature} WHERE task_id = #{taskId}") + int updateSignatureByTaskId(@Param("taskId") Long taskId, @Param("signature") String signature); + + /** + * 根据实例ID更新签名字段(批量更新场景) + * + * @param instanceId 流程实例ID + * @param signature 签名数据(Base64) + * @return 影响行数 + */ + @Update("UPDATE flow_his_task SET signature = #{signature} WHERE instance_id = #{instanceId}") + int updateSignatureByInstanceId(@Param("instanceId") Long instanceId, @Param("signature") String signature); + + /** + * 根据实例ID查询历史任务列表(包含签名字段) + * + * @param instanceId 流程实例ID + * @param nodeType 节点类型 + * @return 历史任务列表 + */ + List selectHisTaskListWithSignature(@Param("instanceId") Long instanceId, + @Param("nodeType") Integer nodeType); +} diff --git a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwInstanceServiceImpl.java b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwInstanceServiceImpl.java index 848bec4e..590f8f4c 100644 --- a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwInstanceServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwInstanceServiceImpl.java @@ -42,6 +42,7 @@ import org.dromara.workflow.domain.vo.FlowHisTaskVo; import org.dromara.workflow.domain.vo.FlowInstanceVo; import org.dromara.workflow.handler.FlowProcessEventHandler; import org.dromara.workflow.mapper.FlwCategoryMapper; +import org.dromara.workflow.mapper.FlwHisTaskExtMapper; import org.dromara.workflow.mapper.FlwInstanceMapper; import org.dromara.workflow.service.IFlwInstanceService; import org.dromara.workflow.service.IFlwTaskService; @@ -71,6 +72,7 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { private final IFlwTaskService flwTaskService; private final FlwInstanceMapper flwInstanceMapper; private final FlwCategoryMapper flwCategoryMapper; + private final FlwHisTaskExtMapper flwHisTaskExtMapper; /** * 分页查询正在运行的流程实例 @@ -128,15 +130,21 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { */ private QueryWrapper buildQueryWrapper(FlowInstanceBo flowInstanceBo) { QueryWrapper queryWrapper = Wrappers.query(); - queryWrapper.like(StringUtils.isNotBlank(flowInstanceBo.getNodeName()), "fi.node_name", flowInstanceBo.getNodeName()); - queryWrapper.like(StringUtils.isNotBlank(flowInstanceBo.getFlowName()), "fd.flow_name", flowInstanceBo.getFlowName()); - queryWrapper.like(StringUtils.isNotBlank(flowInstanceBo.getFlowCode()), "fd.flow_code", flowInstanceBo.getFlowCode()); + queryWrapper.like(StringUtils.isNotBlank(flowInstanceBo.getNodeName()), "fi.node_name", + flowInstanceBo.getNodeName()); + queryWrapper.like(StringUtils.isNotBlank(flowInstanceBo.getFlowName()), "fd.flow_name", + flowInstanceBo.getFlowName()); + queryWrapper.like(StringUtils.isNotBlank(flowInstanceBo.getFlowCode()), "fd.flow_code", + flowInstanceBo.getFlowCode()); if (StringUtils.isNotBlank(flowInstanceBo.getCategory())) { - List categoryIds = flwCategoryMapper.selectCategoryIdsByParentId(Convert.toLong(flowInstanceBo.getCategory())); + List categoryIds = flwCategoryMapper + .selectCategoryIdsByParentId(Convert.toLong(flowInstanceBo.getCategory())); queryWrapper.in("fd.category", StreamUtils.toList(categoryIds, Convert::toStr)); } - queryWrapper.eq(StringUtils.isNotBlank(flowInstanceBo.getBusinessId()), "fi.business_id", flowInstanceBo.getBusinessId()); - queryWrapper.in(CollUtil.isNotEmpty(flowInstanceBo.getCreateByIds()), "fi.create_by", flowInstanceBo.getCreateByIds()); + queryWrapper.eq(StringUtils.isNotBlank(flowInstanceBo.getBusinessId()), "fi.business_id", + flowInstanceBo.getBusinessId()); + queryWrapper.in(CollUtil.isNotEmpty(flowInstanceBo.getCreateByIds()), "fi.create_by", + flowInstanceBo.getCreateByIds()); queryWrapper.eq("fi.del_flag", "0"); queryWrapper.orderByDesc("fi.create_time"); return queryWrapper; @@ -149,7 +157,8 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { */ @Override public FlowInstance selectInstByBusinessId(String businessId) { - return flowInstanceMapper.selectOne(new LambdaQueryWrapper().eq(FlowInstance::getBusinessId, businessId)); + return flowInstanceMapper + .selectOne(new LambdaQueryWrapper().eq(FlowInstance::getBusinessId, businessId)); } /** @@ -180,7 +189,8 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { @Override @Transactional(rollbackFor = Exception.class) public boolean deleteByBusinessIds(List businessIds) { - List flowInstances = flowInstanceMapper.selectList(new LambdaQueryWrapper().in(FlowInstance::getBusinessId, StreamUtils.toList(businessIds, Convert::toStr))); + List flowInstances = flowInstanceMapper.selectList(new LambdaQueryWrapper() + .in(FlowInstance::getBusinessId, StreamUtils.toList(businessIds, Convert::toStr))); if (CollUtil.isEmpty(flowInstances)) { log.warn("未找到对应的流程实例信息,无法执行删除操作。"); return false; @@ -204,8 +214,8 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { } // 获取定义信息 Map definitionMap = defService.getByIds( - StreamUtils.toList(instances, Instance::getDefinitionId) - ).stream().collect(Collectors.toMap(Definition::getId, definition -> definition)); + StreamUtils.toList(instances, Instance::getDefinitionId)).stream() + .collect(Collectors.toMap(Definition::getId, definition -> definition)); // 逐一触发删除事件 instances.forEach(instance -> { @@ -242,11 +252,11 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { String userIdStr = LoginHelper.getUserIdStr(); BusinessStatusEnum.checkCancelStatus(instance.getFlowStatus()); FlowParams flowParams = FlowParams.build() - .message(message) - .flowStatus(BusinessStatusEnum.CANCEL.getStatus()) - .hisStatus(BusinessStatusEnum.CANCEL.getStatus()) - .handler(userIdStr) - .ignore(true); + .message(message) + .flowStatus(BusinessStatusEnum.CANCEL.getStatus()) + .hisStatus(BusinessStatusEnum.CANCEL.getStatus()) + .handler(userIdStr) + .ignore(true); taskService.revoke(instance.getId(), flowParams); } catch (Exception e) { log.error("撤销失败: {}", e.getMessage(), e); @@ -281,7 +291,7 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { throw new ServiceException(ExceptionCons.NOT_FOUNT_INSTANCE); } Long instanceId = flowInstance.getId(); - //运行中的任务 + // 运行中的任务 List list = new ArrayList<>(); List flowTaskList = flwTaskService.selectByInstId(instanceId); if (CollUtil.isNotEmpty(flowTaskList)) { @@ -302,16 +312,13 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { } list.addAll(flowHisTaskVos); } - //历史任务 - LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); - wrapper.eq(FlowHisTask::getInstanceId, instanceId); - wrapper.eq(FlowHisTask::getNodeType, NodeType.BETWEEN.getKey()); - wrapper.orderByDesc(FlowHisTask::getCreateTime).orderByDesc(FlowHisTask::getUpdateTime); - List flowHisTasks = flowHisTaskMapper.selectList(wrapper); - if (CollUtil.isNotEmpty(flowHisTasks)) { - list.addAll(BeanUtil.copyToList(flowHisTasks, FlowHisTaskVo.class)); + // 历史任务(使用自定义Mapper查询,包含签名字段) + List flowHisTaskVos = flwHisTaskExtMapper.selectHisTaskListWithSignature(instanceId, + NodeType.BETWEEN.getKey()); + if (CollUtil.isNotEmpty(flowHisTaskVos)) { + list.addAll(flowHisTaskVos); } - return Map.of("list", list,"instanceId",instanceId); + return Map.of("list", list, "instanceId", instanceId); } /** @@ -336,10 +343,11 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { @Override public Map instanceVariable(Long instanceId) { FlowInstance flowInstance = flowInstanceMapper.selectById(instanceId); - Map variableMap = Optional.ofNullable(flowInstance.getVariableMap()).orElse(Collections.emptyMap()); + Map variableMap = Optional.ofNullable(flowInstance.getVariableMap()) + .orElse(Collections.emptyMap()); List> variableList = variableMap.entrySet().stream() - .map(entry -> Map.of("key", entry.getKey(), "value", entry.getValue())) - .toList(); + .map(entry -> Map.of("key", entry.getKey(), "value", entry.getValue())) + .toList(); return Map.of("variableList", variableList, "variable", flowInstance.getVariable()); } @@ -416,10 +424,10 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { BusinessStatusEnum.checkInvalidStatus(instance.getFlowStatus()); } FlowParams flowParams = FlowParams.build() - .message(bo.getComment()) - .flowStatus(BusinessStatusEnum.INVALID.getStatus()) - .hisStatus(TaskStatusEnum.INVALID.getStatus()) - .ignore(true); + .message(bo.getComment()) + .flowStatus(BusinessStatusEnum.INVALID.getStatus()) + .hisStatus(TaskStatusEnum.INVALID.getStatus()) + .ignore(true); taskService.terminationByInsId(bo.getId(), flowParams); return true; } catch (Exception e) { diff --git a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java index 8fc0340e..c6c90803 100644 --- a/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java @@ -38,6 +38,7 @@ import org.dromara.warm.flow.orm.mapper.FlowInstanceMapper; import org.dromara.warm.flow.orm.mapper.FlowNodeMapper; import org.dromara.warm.flow.orm.mapper.FlowTaskMapper; import org.dromara.workflow.common.ConditionalOnEnable; +import org.dromara.workflow.mapper.FlwHisTaskExtMapper; import org.dromara.workflow.common.constant.FlowConstant; import org.dromara.workflow.common.enums.TaskAssigneeType; import org.dromara.workflow.common.enums.TaskStatusEnum; @@ -86,6 +87,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService { private final IFlwTaskAssigneeService flwTaskAssigneeService; private final IFlwCommonService flwCommonService; private final IFlwNodeExtService flwNodeExtService; + private final FlwHisTaskExtMapper flwHisTaskExtMapper; /** * 启动任务 @@ -185,6 +187,12 @@ public class FlwTaskServiceImpl implements IFlwTaskService { .hisTaskExt(completeTaskBo.getFileId()); // 执行任务跳转,并根据返回的处理人设置下一步处理人 taskService.skip(taskId, flowParams); + + // 保存手写签名到历史任务表 + if (StringUtils.isNotBlank(completeTaskBo.getSignature())) { + flwHisTaskExtMapper.updateSignatureByTaskId(taskId, completeTaskBo.getSignature()); + } + return true; } catch (Exception e) { log.error(e.getMessage(), e); @@ -409,6 +417,12 @@ public class FlwTaskServiceImpl implements IFlwTaskService { .hisStatus(TaskStatusEnum.BACK.getStatus()) .hisTaskExt(bo.getFileId()); taskService.skip(task.getId(), flowParams); + + // 保存手写签名到历史任务表(驳回场景) + if (StringUtils.isNotBlank(bo.getSignature())) { + flwHisTaskExtMapper.updateSignatureByTaskId(taskId, bo.getSignature()); + } + return true; } catch (Exception e) { log.error(e.getMessage(), e); diff --git a/backend/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/FlwHisTaskExtMapper.xml b/backend/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/FlwHisTaskExtMapper.xml new file mode 100644 index 00000000..e55dd78d --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/FlwHisTaskExtMapper.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/FlwTaskMapper.xml b/backend/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/FlwTaskMapper.xml index f539030b..6d4aeeac 100644 --- a/backend/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/FlwTaskMapper.xml +++ b/backend/ruoyi-modules/ruoyi-workflow/src/main/resources/mapper/workflow/FlwTaskMapper.xml @@ -59,6 +59,7 @@ a.instance_id, a.flow_status flow_task_status, a.message, + a.signature, a.ext, a.create_time, a.update_time, diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgCollegeLeaderController.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgCollegeLeaderController.java new file mode 100644 index 00000000..a233ae10 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgCollegeLeaderController.java @@ -0,0 +1,123 @@ +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.XgCollegeLeaderVo; +import org.dromara.xg.domain.bo.XgCollegeLeaderBo; +import org.dromara.xg.service.IXgCollegeLeaderService; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; + +/** + * 二级学院分管领导配置 + * + * @author Cursor AI + * @date 2025-01-24 + */ +@Tag(name = "二级学院分管领导配置") +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/xg/ejxyfgld") +public class XgCollegeLeaderController extends BaseController { + + private final IXgCollegeLeaderService xgCollegeLeaderService; + + /** + * 查询二级学院分管领导配置列表 + */ + @Operation(summary = "查询二级学院分管领导配置列表") + @SaCheckPermission("xg:ejxyfgld:list") + @GetMapping("/list") + public TableDataInfo list(XgCollegeLeaderBo bo, PageQuery pageQuery) { + return xgCollegeLeaderService.queryPageList(bo, pageQuery); + } + + /** + * 根据学院ID查询分管领导列表 + */ + @Operation(summary = "根据学院ID查询分管领导列表") + @SaCheckPermission("xg:ejxyfgld:list") + @GetMapping("/listByCollege/{collegeId}") + public R> listByCollege(@PathVariable Long collegeId) { + List list = xgCollegeLeaderService.queryByCollegeId(collegeId); + return R.ok(list); + } + + /** + * 导出二级学院分管领导配置列表 + */ + @Operation(summary = "导出二级学院分管领导配置列表") + @SaCheckPermission("xg:ejxyfgld:export") + @Log(title = "二级学院分管领导配置", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(XgCollegeLeaderBo bo, HttpServletResponse response) { + List list = xgCollegeLeaderService.queryList(bo); + ExcelUtil.exportExcel(list, "二级学院分管领导配置", XgCollegeLeaderVo.class, response); + } + + /** + * 获取二级学院分管领导配置详细信息 + * + * @param id 主键 + */ + @Operation(summary = "获取二级学院分管领导配置详细信息") + @SaCheckPermission("xg:ejxyfgld:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) { + return R.ok(xgCollegeLeaderService.queryById(id)); + } + + /** + * 新增二级学院分管领导配置 + */ + @Operation(summary = "新增二级学院分管领导配置") + @SaCheckPermission("xg:ejxyfgld:add") + @Log(title = "二级学院分管领导配置", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody XgCollegeLeaderBo bo) { + return toAjax(xgCollegeLeaderService.insertByBo(bo)); + } + + /** + * 修改二级学院分管领导配置 + */ + @Operation(summary = "修改二级学院分管领导配置") + @SaCheckPermission("xg:ejxyfgld:edit") + @Log(title = "二级学院分管领导配置", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody XgCollegeLeaderBo bo) { + return toAjax(xgCollegeLeaderService.updateByBo(bo)); + } + + /** + * 删除二级学院分管领导配置 + * + * @param ids 主键串 + */ + @Operation(summary = "删除二级学院分管领导配置") + @SaCheckPermission("xg:ejxyfgld:remove") + @Log(title = "二级学院分管领导配置", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) { + return toAjax(xgCollegeLeaderService.deleteWithValidByIds(List.of(ids), true)); + } +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentDynamicsController.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentDynamicsController.java new file mode 100644 index 00000000..15d88804 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentDynamicsController.java @@ -0,0 +1,87 @@ +package org.dromara.xg.controller; + +import lombok.RequiredArgsConstructor; +import jakarta.validation.constraints.NotNull; +import cn.dev33.satoken.annotation.SaCheckPermission; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +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.mybatis.core.page.TableDataInfo; +import org.dromara.xg.domain.vo.XgDormApplicationVo; +import org.dromara.xg.domain.vo.XgHolidayStayVo; +import org.dromara.xg.domain.vo.XgStudentLeaveVo; +import org.dromara.xg.domain.bo.XgDormApplicationBo; +import org.dromara.xg.domain.bo.XgHolidayStayBo; +import org.dromara.xg.domain.bo.XgStudentLeaveBo; +import org.dromara.xg.service.IXgStudentDynamicsService; + +/** + * 学生动向信息管理(宿管员) + * + * @author zlwu + * @date 2025-01-15 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/studentDynamics") +public class XgStudentDynamicsController extends BaseController { + + private final IXgStudentDynamicsService xgStudentDynamicsService; + + /** + * 查询宿管员权限内的学生调宿退宿申请列表 + */ + @SaCheckPermission("studentDynamics:dormApplication:list") + @GetMapping("/dormApplicationList") + public TableDataInfo getDormApplicationList(XgDormApplicationBo bo, PageQuery pageQuery) { + return xgStudentDynamicsService.queryDormApplicationPageList(bo, pageQuery); + } + + /** + * 查询宿管员权限内的学生假期留宿信息列表 + */ + @SaCheckPermission("studentDynamics:holidayStay:list") + @GetMapping("/holidayStayList") + public TableDataInfo getHolidayStayList(XgHolidayStayBo bo, PageQuery pageQuery) { + return xgStudentDynamicsService.queryHolidayStayPageList(bo, pageQuery); + } + + /** + * 查询宿管员权限内的学生请假信息列表 + */ + @SaCheckPermission("studentDynamics:studentLeave:list") + @GetMapping("/studentLeaveList") + public TableDataInfo getStudentLeaveList(XgStudentLeaveBo bo, PageQuery pageQuery) { + return xgStudentDynamicsService.queryStudentLeavePageList(bo, pageQuery); + } + + /** + * 获取调宿退宿申请详细信息 + */ + @SaCheckPermission("studentDynamics:dormApplication:query") + @GetMapping("/dormApplication/{id}") + public R getDormApplicationInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) { + return R.ok(xgStudentDynamicsService.queryDormApplicationById(id)); + } + + /** + * 获取假期留宿详细信息 + */ + @SaCheckPermission("studentDynamics:holidayStay:query") + @GetMapping("/holidayStay/{id}") + public R getHolidayStayInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) { + return R.ok(xgStudentDynamicsService.queryHolidayStayById(id)); + } + + /** + * 获取学生请假详细信息 + */ + @SaCheckPermission("studentDynamics:studentLeave:query") + @GetMapping("/studentLeave/{id}") + public R getStudentLeaveInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) { + return R.ok(xgStudentDynamicsService.queryStudentLeaveById(id)); + } +} 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 a41a700e..186c7943 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 @@ -823,6 +823,23 @@ public class XgStudentMsgController extends BaseController { return R.ok(approverUserIds); } + /** + * 根据学生ID获取二级学院分管领导ID列表 + * + * @param studentId 学生ID + * @return 分管领导ID列表 + */ + @SaCheckPermission("studentMsg:studentMsg:query") + @GetMapping("/getCollegeLeaders/{studentId}") + public R> getCollegeLeaders(@NotNull(message = "学生ID不能为空") @PathVariable Long studentId) { + log.info("根据学生ID获取二级学院分管领导ID列表 - 学生ID: {}", studentId); + List leaderIds = xgStudentMsgService.getCollegeLeadersByStudentId(studentId); + if (leaderIds.isEmpty()) { + return R.fail("未找到该学生所在学院的分管领导"); + } + return R.ok(leaderIds); + } + /** * 导入数据 * diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgSysUserController.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgSysUserController.java index ed10eac0..9997dd5f 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgSysUserController.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgSysUserController.java @@ -28,7 +28,7 @@ public class XgSysUserController extends BaseController { private final IXgSysUserService xgSysUserService; /** - * 查询有效用户列表 + * 查询有效用户列表(教职工account_type=1) */ @SaCheckPermission("xg:sysUser:list") @GetMapping("/activeList") diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgCollegeLeader.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgCollegeLeader.java new file mode 100644 index 00000000..08549ec2 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgCollegeLeader.java @@ -0,0 +1,61 @@ +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_college_leader + * + * @author Cursor AI + * @date 2025-01-24 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("xg_college_leader") +public class XgCollegeLeader 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,关联sys_dept.dept_id + */ + private Long collegeId; + + /** + * 二级学院名称 + */ + private String collegeName; + + /** + * 分管领导ID,关联sys_user.user_id + */ + private Long leaderId; + + /** + * 分管领导姓名 + */ + private String leaderName; + + /** + * 备注信息 + */ + private String remark; + +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgSysUser.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgSysUser.java index cd893516..d6528aff 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgSysUser.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgSysUser.java @@ -27,6 +27,11 @@ public class XgSysUser extends TenantEntity { @TableId(value = "user_id") private Long userId; + /** + * 用户账号 + */ + private String userName; + /** * 用户昵称 */ diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/bo/XgCollegeLeaderBo.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/bo/XgCollegeLeaderBo.java new file mode 100644 index 00000000..e94dcaf6 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/bo/XgCollegeLeaderBo.java @@ -0,0 +1,61 @@ +package org.dromara.xg.domain.bo; + +import org.dromara.xg.domain.XgCollegeLeader; +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_college_leader + * + * @author Cursor AI + * @date 2025-01-24 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = XgCollegeLeader.class, reverseConvertGenerate = false) +public class XgCollegeLeaderBo extends BaseEntity { + + /** + * 主键ID(雪花ID) + */ + @NotNull(message = "主键ID不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 删除标志(0代表存在 1代表删除) + */ + private Long deleted; + + /** + * 二级学院ID,关联sys_dept.dept_id + */ + @NotNull(message = "二级学院不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long collegeId; + + /** + * 二级学院名称 + */ + private String collegeName; + + /** + * 分管领导ID,关联sys_user.user_id + */ + @NotNull(message = "分管领导不能为空", groups = { AddGroup.class, EditGroup.class }) + private Long leaderId; + + /** + * 分管领导姓名 + */ + private String leaderName; + + /** + * 备注信息 + */ + private String remark; + +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgCollegeLeaderVo.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgCollegeLeaderVo.java new file mode 100644 index 00000000..71ad5900 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgCollegeLeaderVo.java @@ -0,0 +1,88 @@ +package org.dromara.xg.domain.vo; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.dromara.xg.domain.XgCollegeLeader; +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; + +/** + * 二级学院分管领导配置视图对象 xg_college_leader + * + * @author Cursor AI + * @date 2025-01-24 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = XgCollegeLeader.class) +public class XgCollegeLeaderVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID(雪花ID) + */ + @ExcelProperty(value = "主键ID") + private Long id; + + /** + * 二级学院ID,关联sys_dept.dept_id + */ + @ExcelProperty(value = "二级学院ID") + private Long collegeId; + + /** + * 二级学院名称 + */ + @ExcelProperty(value = "二级学院名称") + private String collegeName; + + /** + * 分管领导ID,关联sys_user.user_id + */ + @ExcelProperty(value = "分管领导ID") + private Long leaderId; + + /** + * 分管领导姓名 + */ + @ExcelProperty(value = "分管领导姓名") + private String leaderName; + + /** + * 备注信息 + */ + @ExcelProperty(value = "备注") + private String remark; + + /** + * 创建者 + */ + private Long createBy; + + /** + * 创建时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** + * 更新者 + */ + private Long updateBy; + + /** + * 更新时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgCollegeLeaderMapper.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgCollegeLeaderMapper.java new file mode 100644 index 00000000..b2ce068a --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgCollegeLeaderMapper.java @@ -0,0 +1,15 @@ +package org.dromara.xg.mapper; + +import org.dromara.xg.domain.XgCollegeLeader; +import org.dromara.xg.domain.vo.XgCollegeLeaderVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 二级学院分管领导配置Mapper接口 + * + * @author Cursor AI + * @date 2025-01-24 + */ +public interface XgCollegeLeaderMapper extends BaseMapperPlus { + +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentDynamicsMapper.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentDynamicsMapper.java new file mode 100644 index 00000000..a2601038 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentDynamicsMapper.java @@ -0,0 +1,85 @@ +package org.dromara.xg.mapper; + +import org.apache.ibatis.annotations.Param; +import java.util.List; + +/** + * 学生动向信息管理(宿管员)Mapper接口 + * + * @author zlwu + * @date 2025-01-15 + */ +public interface XgStudentDynamicsMapper { + + /** + * 检查用户是否有宿舍管理权限 + * + * @param userId 用户ID + * @return 管理员类型列表 (1全校管理员 2校区管理员 3宿舍区管理员 4宿舍楼管理员) + */ + List checkUserDormManagerType(@Param("userId") Long userId); + + /** + * 获取全校管理员权限的所有楼栋ID列表 + * + * @param userId 用户ID + * @return 楼栋ID列表 + */ + List getBuildingIdsBySchoolAdmin(@Param("userId") Long userId); + + /** + * 获取校区管理员权限的楼栋ID列表 + * + * @param userId 用户ID + * @return 楼栋ID列表 + */ + List getBuildingIdsByCampusAdmin(@Param("userId") Long userId); + + /** + * 获取宿舍区管理员权限的楼栋ID列表 + * + * @param userId 用户ID + * @return 楼栋ID列表 + */ + List getBuildingIdsByAreaAdmin(@Param("userId") Long userId); + + /** + * 获取宿舍楼管理员权限的楼栋ID列表 + * + * @param userId 用户ID + * @return 楼栋ID列表 + */ + List getBuildingIdsByBuildingAdmin(@Param("userId") Long userId); + + /** + * 获取全校管理员权限的所有学生ID列表 + * + * @param userId 用户ID + * @return 学生ID列表 + */ + List getStudentIdsBySchoolAdmin(@Param("userId") Long userId); + + /** + * 获取校区管理员权限的学生ID列表 + * + * @param userId 用户ID + * @return 学生ID列表 + */ + List getStudentIdsByCampusAdmin(@Param("userId") Long userId); + + /** + * 获取宿舍区管理员权限的学生ID列表 + * + * @param userId 用户ID + * @return 学生ID列表 + */ + List getStudentIdsByAreaAdmin(@Param("userId") Long userId); + + /** + * 获取宿舍楼管理员权限的学生ID列表 + * + * @param userId 用户ID + * @return 学生ID列表 + */ + List getStudentIdsByBuildingAdmin(@Param("userId") Long userId); +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentMsgMapper.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentMsgMapper.java index 5e3bfc8f..155ef255 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentMsgMapper.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgStudentMsgMapper.java @@ -19,87 +19,95 @@ import java.util.Map; */ public interface XgStudentMsgMapper extends BaseMapperPlus { - /** - * 根据组织ID列表分页查询学生信息 用于导出 - * - * @param page 分页参数 - * @param queryWrapper 查询条件 - * @param deptIds 组织ID列表 - * @return 学生信息分页结果 - */ - List queryPageListExportByDeptId( - @Param("ew") LambdaQueryWrapper queryWrapper, - @Param("deptIds") List deptIds); + /** + * 根据组织ID列表分页查询学生信息 用于导出 + * + * @param page 分页参数 + * @param queryWrapper 查询条件 + * @param deptIds 组织ID列表 + * @return 学生信息分页结果 + */ + List queryPageListExportByDeptId( + @Param("ew") LambdaQueryWrapper queryWrapper, + @Param("deptIds") List deptIds); - /** - * 根据组织ID列表分页查询学生信息 - * - * @param page 分页参数 - * @param queryWrapper 查询条件 - * @param deptIds 组织ID列表 - * @return 学生信息分页结果 - */ - Page selectPageByDeptIds(@Param("page") Page page, - @Param("ew") LambdaQueryWrapper queryWrapper, - @Param("deptIds") List deptIds); + /** + * 根据组织ID列表分页查询学生信息 + * + * @param page 分页参数 + * @param queryWrapper 查询条件 + * @param deptIds 组织ID列表 + * @return 学生信息分页结果 + */ + Page selectPageByDeptIds(@Param("page") Page page, + @Param("ew") LambdaQueryWrapper queryWrapper, + @Param("deptIds") List deptIds); - /** - * 根据班级ID和姓名查询学生信息列表 - * - * @param classId 班级ID - * @param name 学生姓名(模糊查询) - * @return 学生信息列表 - */ - List selectStudentsByClassId(@Param("classId") String classId, @Param("name") String name); + /** + * 根据班级ID和姓名查询学生信息列表 + * + * @param classId 班级ID + * @param name 学生姓名(模糊查询) + * @return 学生信息列表 + */ + List selectStudentsByClassId(@Param("classId") String classId, @Param("name") String name); - /** - * 根据学生ID查询班主任ID - * - * @param studentId 学生ID - * @return 班主任ID - */ - Long selectClassTeacherIdByStudentId(@Param("studentId") Long studentId); + /** + * 根据学生ID查询班主任ID + * + * @param studentId 学生ID + * @return 班主任ID + */ + Long selectClassTeacherIdByStudentId(@Param("studentId") Long studentId); - /** - * 根据学生ID查询学院ID - * - * @param studentId 学生ID - * @return 学院ID - */ - Long selectCollegeIdByStudentId(@Param("studentId") Long studentId); + /** + * 根据学生ID查询学院ID + * + * @param studentId 学生ID + * @return 学院ID + */ + Long selectCollegeIdByStudentId(@Param("studentId") Long studentId); - /** - * 根据学院ID和角色Key查询具备该角色的用户列表 - * - * @param collegeId 学院ID - * @param roleKey 角色Key - * @return 用户ID列表 - */ - List selectUserIdsByCollegeIdAndRoleKey(@Param("collegeId") Long collegeId, - @Param("roleKey") String roleKey); + /** + * 根据学院ID和角色Key查询具备该角色的用户列表 + * + * @param collegeId 学院ID + * @param roleKey 角色Key + * @return 用户ID列表 + */ + List selectUserIdsByCollegeIdAndRoleKey(@Param("collegeId") Long collegeId, + @Param("roleKey") String roleKey); - /** - * 查询二级学院下的学院、专业、班级学生统计信息 - * - * @param secondaryCollegeId 二级学院ID - * @return 学生统计信息列表 - */ - List> getCollegeStudentStats(@Param("secondaryCollegeId") Long secondaryCollegeId); + /** + * 根据学院ID查询二级学院分管领导ID列表 + * + * @param collegeId 学院ID + * @return 分管领导ID列表 + */ + List selectCollegeLeaderIdsByCollegeId(@Param("collegeId") Long collegeId); - /** - * 查询二级学院下的学院、专业、班级学生统计信息(按床位分配统计) - * - * @param secondaryCollegeId 二级学院ID - * @return 学生统计信息列表 - */ - List> getCollegeStudentStatsByClass(@Param("secondaryCollegeId") Long secondaryCollegeId); + /** + * 查询二级学院下的学院、专业、班级学生统计信息 + * + * @param secondaryCollegeId 二级学院ID + * @return 学生统计信息列表 + */ + List> getCollegeStudentStats(@Param("secondaryCollegeId") Long secondaryCollegeId); - /** - * 查询二级学院下的学院床位分配统计信息(基于college_id统计) - * - * @param secondaryCollegeId 二级学院ID - * @return 学院床位分配统计信息列表 - */ - List> getCollegeBedAssignmentStats(@Param("secondaryCollegeId") Long secondaryCollegeId); + /** + * 查询二级学院下的学院、专业、班级学生统计信息(按床位分配统计) + * + * @param secondaryCollegeId 二级学院ID + * @return 学生统计信息列表 + */ + List> getCollegeStudentStatsByClass(@Param("secondaryCollegeId") Long secondaryCollegeId); + + /** + * 查询二级学院下的学院床位分配统计信息(基于college_id统计) + * + * @param secondaryCollegeId 二级学院ID + * @return 学院床位分配统计信息列表 + */ + List> getCollegeBedAssignmentStats(@Param("secondaryCollegeId") Long secondaryCollegeId); } diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgCollegeLeaderService.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgCollegeLeaderService.java new file mode 100644 index 00000000..915752ea --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgCollegeLeaderService.java @@ -0,0 +1,76 @@ +package org.dromara.xg.service; + +import org.dromara.xg.domain.vo.XgCollegeLeaderVo; +import org.dromara.xg.domain.bo.XgCollegeLeaderBo; +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 Cursor AI + * @date 2025-01-24 + */ +public interface IXgCollegeLeaderService { + + /** + * 查询二级学院分管领导配置 + * + * @param id 主键 + * @return 二级学院分管领导配置 + */ + XgCollegeLeaderVo queryById(Long id); + + /** + * 分页查询二级学院分管领导配置列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 二级学院分管领导配置分页列表 + */ + TableDataInfo queryPageList(XgCollegeLeaderBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的二级学院分管领导配置列表 + * + * @param bo 查询条件 + * @return 二级学院分管领导配置列表 + */ + List queryList(XgCollegeLeaderBo bo); + + /** + * 新增二级学院分管领导配置 + * + * @param bo 二级学院分管领导配置 + * @return 是否新增成功 + */ + Boolean insertByBo(XgCollegeLeaderBo bo); + + /** + * 修改二级学院分管领导配置 + * + * @param bo 二级学院分管领导配置 + * @return 是否修改成功 + */ + Boolean updateByBo(XgCollegeLeaderBo bo); + + /** + * 校验并批量删除二级学院分管领导配置信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 根据学院ID查询分管领导列表 + * + * @param collegeId 学院ID + * @return 分管领导列表 + */ + List queryByCollegeId(Long collegeId); +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentDynamicsService.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentDynamicsService.java new file mode 100644 index 00000000..397dc1c5 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentDynamicsService.java @@ -0,0 +1,49 @@ +package org.dromara.xg.service; + +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.xg.domain.vo.XgDormApplicationVo; +import org.dromara.xg.domain.vo.XgHolidayStayVo; +import org.dromara.xg.domain.vo.XgStudentLeaveVo; +import org.dromara.xg.domain.bo.XgDormApplicationBo; +import org.dromara.xg.domain.bo.XgHolidayStayBo; +import org.dromara.xg.domain.bo.XgStudentLeaveBo; + +/** + * 学生动向信息管理(宿管员)Service接口 + * + * @author zlwu + * @date 2025-01-15 + */ +public interface IXgStudentDynamicsService { + + /** + * 查询宿管员权限内的学生调宿退宿申请列表 + */ + TableDataInfo queryDormApplicationPageList(XgDormApplicationBo bo, PageQuery pageQuery); + + /** + * 查询宿管员权限内的学生假期留宿信息列表 + */ + TableDataInfo queryHolidayStayPageList(XgHolidayStayBo bo, PageQuery pageQuery); + + /** + * 查询宿管员权限内的学生请假信息列表 + */ + TableDataInfo queryStudentLeavePageList(XgStudentLeaveBo bo, PageQuery pageQuery); + + /** + * 根据主键查询调宿退宿申请详情 + */ + XgDormApplicationVo queryDormApplicationById(Long id); + + /** + * 根据主键查询假期留宿详情 + */ + XgHolidayStayVo queryHolidayStayById(Long id); + + /** + * 根据主键查询学生请假详情 + */ + XgStudentLeaveVo queryStudentLeaveById(Long id); +} 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 fe89c09c..030c9bd8 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 @@ -140,6 +140,14 @@ public interface IXgStudentMsgService { */ List getCollegeLeaveApproversByStudentId(Long studentId); + /** + * 根据学生ID获取二级学院分管领导ID列表 + * + * @param studentId 学生ID + * @return 分管领导ID列表 + */ + List getCollegeLeadersByStudentId(Long studentId); + /** * 批量申请床位 * diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgCollegeLeaderServiceImpl.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgCollegeLeaderServiceImpl.java new file mode 100644 index 00000000..dac2b934 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgCollegeLeaderServiceImpl.java @@ -0,0 +1,163 @@ +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.springframework.transaction.annotation.Transactional; +import org.dromara.xg.domain.bo.XgCollegeLeaderBo; +import org.dromara.xg.domain.vo.XgCollegeLeaderVo; +import org.dromara.xg.domain.XgCollegeLeader; +import org.dromara.xg.mapper.XgCollegeLeaderMapper; +import org.dromara.xg.service.IXgCollegeLeaderService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 二级学院分管领导配置Service业务层处理 + * + * @author Cursor AI + * @date 2025-01-24 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class XgCollegeLeaderServiceImpl implements IXgCollegeLeaderService { + + private final XgCollegeLeaderMapper baseMapper; + + /** + * 查询二级学院分管领导配置 + * + * @param id 主键 + * @return 二级学院分管领导配置 + */ + @Override + public XgCollegeLeaderVo queryById(Long id) { + return baseMapper.selectVoById(id); + } + + /** + * 分页查询二级学院分管领导配置列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 二级学院分管领导配置分页列表 + */ + @Override + public TableDataInfo queryPageList(XgCollegeLeaderBo 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(XgCollegeLeaderBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + /** + * 根据学院ID查询分管领导列表 + * + * @param collegeId 学院ID + * @return 分管领导列表 + */ + @Override + public List queryByCollegeId(Long collegeId) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(XgCollegeLeader::getCollegeId, collegeId); + lqw.orderByDesc(XgCollegeLeader::getCreateTime); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(XgCollegeLeaderBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(bo.getCollegeId() != null, XgCollegeLeader::getCollegeId, bo.getCollegeId()); + lqw.like(StringUtils.isNotBlank(bo.getCollegeName()), XgCollegeLeader::getCollegeName, bo.getCollegeName()); + lqw.eq(bo.getLeaderId() != null, XgCollegeLeader::getLeaderId, bo.getLeaderId()); + lqw.like(StringUtils.isNotBlank(bo.getLeaderName()), XgCollegeLeader::getLeaderName, bo.getLeaderName()); + lqw.orderByDesc(XgCollegeLeader::getCreateTime); + return lqw; + } + + /** + * 新增二级学院分管领导配置 + * + * @param bo 二级学院分管领导配置 + * @return 是否新增成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean insertByBo(XgCollegeLeaderBo bo) { + XgCollegeLeader add = MapstructUtils.convert(bo, XgCollegeLeader.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改二级学院分管领导配置 + * + * @param bo 二级学院分管领导配置 + * @return 是否修改成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean updateByBo(XgCollegeLeaderBo bo) { + XgCollegeLeader update = MapstructUtils.convert(bo, XgCollegeLeader.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(XgCollegeLeader entity) { + // 校验是否已存在相同的配置 + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(XgCollegeLeader::getCollegeId, entity.getCollegeId()); + lqw.eq(XgCollegeLeader::getLeaderId, entity.getLeaderId()); + if (entity.getId() != null) { + lqw.ne(XgCollegeLeader::getId, entity.getId()); + } + long count = baseMapper.selectCount(lqw); + if (count > 0) { + throw new RuntimeException("该学院已配置此分管领导,不能重复配置!"); + } + } + + /** + * 校验并批量删除二级学院分管领导配置信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if (isValid) { + // 可以添加业务校验逻辑 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentDynamicsServiceImpl.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentDynamicsServiceImpl.java new file mode 100644 index 00000000..8690fe53 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentDynamicsServiceImpl.java @@ -0,0 +1,353 @@ +package org.dromara.xg.service.impl; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.xg.domain.vo.XgDormApplicationVo; +import org.dromara.xg.domain.vo.XgHolidayStayVo; +import org.dromara.xg.domain.vo.XgStudentLeaveVo; +import org.dromara.xg.domain.bo.XgDormApplicationBo; +import org.dromara.xg.domain.bo.XgHolidayStayBo; +import org.dromara.xg.domain.bo.XgStudentLeaveBo; +import org.dromara.xg.domain.XgDormApplication; +import org.dromara.xg.domain.XgHolidayStay; +import org.dromara.xg.domain.XgStudentLeave; +import org.dromara.xg.mapper.XgDormApplicationMapper; +import org.dromara.xg.mapper.XgHolidayStayMapper; +import org.dromara.xg.mapper.XgStudentLeaveMapper; +import org.dromara.xg.mapper.XgStudentDynamicsMapper; +import org.dromara.xg.service.IXgStudentDynamicsService; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * 学生动向信息管理(宿管员)Service实现 + * + * @author zlwu + * @date 2025-01-15 + */ +@RequiredArgsConstructor +@Service +public class XgStudentDynamicsServiceImpl implements IXgStudentDynamicsService { + + private final XgDormApplicationMapper dormApplicationMapper; + private final XgHolidayStayMapper holidayStayMapper; + private final XgStudentLeaveMapper studentLeaveMapper; + private final XgStudentDynamicsMapper studentDynamicsMapper; + + /** + * 查询宿管员权限内的学生调宿退宿申请列表 + */ + @Override + public TableDataInfo queryDormApplicationPageList(XgDormApplicationBo bo, + PageQuery pageQuery) { + // 获取当前登录用户ID + Long currentUserId = LoginHelper.getUserId(); + + // 构建查询条件 + LambdaQueryWrapper lqw = buildDormApplicationQueryWrapper(bo, currentUserId); + + // 分页查询 + Page result = dormApplicationMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询宿管员权限内的学生假期留宿信息列表 + */ + @Override + public TableDataInfo queryHolidayStayPageList(XgHolidayStayBo bo, PageQuery pageQuery) { + // 获取当前登录用户ID + Long currentUserId = LoginHelper.getUserId(); + + // 构建查询条件 + LambdaQueryWrapper lqw = buildHolidayStayQueryWrapper(bo, currentUserId); + + // 分页查询 + Page result = holidayStayMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询宿管员权限内的学生请假信息列表 + */ + @Override + public TableDataInfo queryStudentLeavePageList(XgStudentLeaveBo bo, PageQuery pageQuery) { + // 获取当前登录用户ID + Long currentUserId = LoginHelper.getUserId(); + + // 构建查询条件 + LambdaQueryWrapper lqw = buildStudentLeaveQueryWrapper(bo, currentUserId); + + // 分页查询 + Page result = studentLeaveMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 根据主键查询调宿退宿申请详情 + */ + @Override + public XgDormApplicationVo queryDormApplicationById(Long id) { + return dormApplicationMapper.selectVoById(id); + } + + /** + * 根据主键查询假期留宿详情 + */ + @Override + public XgHolidayStayVo queryHolidayStayById(Long id) { + return holidayStayMapper.selectVoById(id); + } + + /** + * 根据主键查询学生请假详情 + */ + @Override + public XgStudentLeaveVo queryStudentLeaveById(Long id) { + return studentLeaveMapper.selectVoById(id); + } + + /** + * 构建调宿退宿申请查询条件(带宿管员权限) + */ + private LambdaQueryWrapper buildDormApplicationQueryWrapper(XgDormApplicationBo bo, + Long currentUserId) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + + // 获取宿管员管理的楼栋ID列表 + List managedBuildingIds = getManagedBuildingIds(currentUserId); + + if (managedBuildingIds.isEmpty()) { + // 如果没有管理权限,返回空结果 + lqw.eq(XgDormApplication::getId, -1); + return lqw; + } + + // 只查询宿管员权限内楼栋的学生申请 + lqw.in(XgDormApplication::getCurrentBuildingId, managedBuildingIds); + + // 添加其他查询条件 + // 姓名或学号检索(OR关系) + if (bo.getStudentName() != null && bo.getStudentNo() != null) { + lqw.and(wrapper -> wrapper + .like(XgDormApplication::getStudentName, bo.getStudentName()) + .or() + .like(XgDormApplication::getStudentNo, bo.getStudentNo())); + } else { + lqw.like(bo.getStudentName() != null, XgDormApplication::getStudentName, bo.getStudentName()); + lqw.like(bo.getStudentNo() != null, XgDormApplication::getStudentNo, bo.getStudentNo()); + } + lqw.like(bo.getCollegeName() != null, XgDormApplication::getCollegeName, bo.getCollegeName()); + lqw.like(bo.getMajorName() != null, XgDormApplication::getMajorName, bo.getMajorName()); + lqw.like(bo.getClassName() != null, XgDormApplication::getClassName, bo.getClassName()); + lqw.eq(bo.getApplicationType() != null, XgDormApplication::getApplicationType, bo.getApplicationType()); + lqw.eq(bo.getApplicationStatus() != null, XgDormApplication::getApplicationStatus, bo.getApplicationStatus()); + lqw.ge(bo.getApplyTime() != null, XgDormApplication::getApplyTime, bo.getApplyTime()); + + // 默认按创建时间倒序 + lqw.orderByDesc(XgDormApplication::getCreateTime); + + return lqw; + } + + /** + * 构建假期留宿查询条件(带宿管员权限) + */ + private LambdaQueryWrapper buildHolidayStayQueryWrapper(XgHolidayStayBo bo, Long currentUserId) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + + // 获取宿管员管理的楼栋ID列表 + List managedBuildingIds = getManagedBuildingIds(currentUserId); + + if (managedBuildingIds.isEmpty()) { + // 如果没有管理权限,返回空结果 + lqw.eq(XgHolidayStay::getId, -1); + return lqw; + } + + // 只查询宿管员权限内楼栋的学生留宿 + lqw.in(XgHolidayStay::getBuildingId, managedBuildingIds); + + // 添加其他查询条件 + // 姓名或学号检索(OR关系) + if (bo.getStudentName() != null && bo.getStudentNo() != null) { + lqw.and(wrapper -> wrapper + .like(XgHolidayStay::getStudentName, bo.getStudentName()) + .or() + .like(XgHolidayStay::getStudentNo, bo.getStudentNo())); + } else { + lqw.like(bo.getStudentName() != null, XgHolidayStay::getStudentName, bo.getStudentName()); + lqw.like(bo.getStudentNo() != null, XgHolidayStay::getStudentNo, bo.getStudentNo()); + } + lqw.like(bo.getCollegeName() != null, XgHolidayStay::getCollegeName, bo.getCollegeName()); + lqw.like(bo.getMajorName() != null, XgHolidayStay::getMajorName, bo.getMajorName()); + lqw.like(bo.getClassName() != null, XgHolidayStay::getClassName, bo.getClassName()); + lqw.eq(bo.getHolidayType() != null, XgHolidayStay::getHolidayType, bo.getHolidayType()); + lqw.ge(bo.getApplyStartDate() != null, XgHolidayStay::getApplyStartDate, bo.getApplyStartDate()); + lqw.le(bo.getApplyEndDate() != null, XgHolidayStay::getApplyEndDate, bo.getApplyEndDate()); + + // 默认按创建时间倒序 + lqw.orderByDesc(XgHolidayStay::getCreateTime); + + return lqw; + } + + /** + * 构建学生请假查询条件(带宿管员权限) + */ + private LambdaQueryWrapper buildStudentLeaveQueryWrapper(XgStudentLeaveBo bo, Long currentUserId) { + LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); + + // 获取宿管员权限内的学生ID列表 + List managedStudentIds = getManagedStudentIds(currentUserId); + + if (managedStudentIds.isEmpty()) { + // 如果没有管理权限,返回空结果 + lqw.eq(XgStudentLeave::getId, -1); + return lqw; + } + + // 只查询宿管员权限内的学生请假 + lqw.in(XgStudentLeave::getStudentId, managedStudentIds); + + // 添加其他查询条件 + // 姓名或学号检索(OR关系) + if (bo.getStudentName() != null && bo.getStudentNo() != null) { + lqw.and(wrapper -> wrapper + .like(XgStudentLeave::getStudentName, bo.getStudentName()) + .or() + .like(XgStudentLeave::getStudentNo, bo.getStudentNo())); + } else { + lqw.like(bo.getStudentName() != null, XgStudentLeave::getStudentName, bo.getStudentName()); + lqw.like(bo.getStudentNo() != null, XgStudentLeave::getStudentNo, bo.getStudentNo()); + } + lqw.like(bo.getCollegeName() != null, XgStudentLeave::getCollegeName, bo.getCollegeName()); + lqw.like(bo.getMajorName() != null, XgStudentLeave::getMajorName, bo.getMajorName()); + lqw.like(bo.getClassName() != null, XgStudentLeave::getClassName, bo.getClassName()); + lqw.like(bo.getLeaveTypeName() != null, XgStudentLeave::getLeaveTypeName, bo.getLeaveTypeName()); + lqw.eq(bo.getApprovalStatus() != null, XgStudentLeave::getApprovalStatus, bo.getApprovalStatus()); + lqw.ge(bo.getStartTime() != null, XgStudentLeave::getStartTime, bo.getStartTime()); + lqw.le(bo.getEndTime() != null, XgStudentLeave::getEndTime, bo.getEndTime()); + + // 默认按创建时间倒序 + lqw.orderByDesc(XgStudentLeave::getCreateTime); + + return lqw; + } + + /** + * 获取宿管员管理的楼栋ID列表(支持多级权限合并) + */ + private List getManagedBuildingIds(Long userId) { + // 查询用户管理权限类型 + List managerTypes = studentDynamicsMapper.checkUserDormManagerType(userId); + + if (managerTypes == null || managerTypes.isEmpty()) { + // 没有宿舍管理权限,返回空列表 + return new ArrayList<>(); + } + + // 存储所有权限的楼栋ID,使用Set去重 + Set buildingIdSet = new HashSet<>(); + + // 按照权限分别查询并合并结果(支持用户拥有多种角色的情况) + if (managerTypes.contains("1")) { + // 全校管理员,获取所有楼栋 + List allBuildings = studentDynamicsMapper.getBuildingIdsBySchoolAdmin(userId); + if (allBuildings != null) { + buildingIdSet.addAll(allBuildings); + } + // 全校管理员可以查看所有楼栋,直接返回 + return new ArrayList<>(buildingIdSet); + } + + // 对于非全校管理员,合并多种权限的结果 + if (managerTypes.contains("2")) { + // 校区管理员,获取管理的校区下的楼栋 + List campusBuildings = studentDynamicsMapper.getBuildingIdsByCampusAdmin(userId); + if (campusBuildings != null) { + buildingIdSet.addAll(campusBuildings); + } + } + + if (managerTypes.contains("3")) { + // 宿舍区管理员,获取管理的宿舍区下的楼栋 + List areaBuildings = studentDynamicsMapper.getBuildingIdsByAreaAdmin(userId); + if (areaBuildings != null) { + buildingIdSet.addAll(areaBuildings); + } + } + + if (managerTypes.contains("4")) { + // 宿舍楼管理员,获取管理的楼栋 + List directBuildings = studentDynamicsMapper.getBuildingIdsByBuildingAdmin(userId); + if (directBuildings != null) { + buildingIdSet.addAll(directBuildings); + } + } + + return new ArrayList<>(buildingIdSet); + } + + /** + * 获取宿管员权限内的学生ID列表(支持多级权限合并) + */ + private List getManagedStudentIds(Long userId) { + // 查询用户管理权限类型 + List managerTypes = studentDynamicsMapper.checkUserDormManagerType(userId); + + if (managerTypes == null || managerTypes.isEmpty()) { + // 没有宿舍管理权限,返回空列表 + return new ArrayList<>(); + } + + // 存储所有权限的学生ID,使用Set去重 + Set studentIdSet = new HashSet<>(); + + // 按照权限分别查询并合并结果(支持用户拥有多种角色的情况) + if (managerTypes.contains("1")) { + // 全校管理员,获取所有学生 + List allStudents = studentDynamicsMapper.getStudentIdsBySchoolAdmin(userId); + if (allStudents != null) { + studentIdSet.addAll(allStudents); + } + // 全校管理员可以查看所有学生,直接返回 + return new ArrayList<>(studentIdSet); + } + + // 对于非全校管理员,合并多种权限的结果 + if (managerTypes.contains("2")) { + // 校区管理员,获取管理的校区下的学生 + List campusStudents = studentDynamicsMapper.getStudentIdsByCampusAdmin(userId); + if (campusStudents != null) { + studentIdSet.addAll(campusStudents); + } + } + + if (managerTypes.contains("3")) { + // 宿舍区管理员,获取管理的宿舍区下的学生 + List areaStudents = studentDynamicsMapper.getStudentIdsByAreaAdmin(userId); + if (areaStudents != null) { + studentIdSet.addAll(areaStudents); + } + } + + if (managerTypes.contains("4")) { + // 宿舍楼管理员,获取管理的楼栋下的学生 + List buildingStudents = studentDynamicsMapper.getStudentIdsByBuildingAdmin(userId); + if (buildingStudents != null) { + studentIdSet.addAll(buildingStudents); + } + } + + return new ArrayList<>(studentIdSet); + } +} 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 654d757e..af3095f1 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 @@ -1095,6 +1095,32 @@ public class XgStudentMsgServiceImpl implements IXgStudentMsgService { return approverUserIds; } + /** + * 根据学生ID获取二级学院分管领导ID列表 + * + * @param studentId 学生ID + * @return 分管领导ID列表 + */ + @Override + public List getCollegeLeadersByStudentId(Long studentId) { + log.info("根据学生ID获取二级学院分管领导ID列表 - 学生ID: {}", studentId); + + // 1. 根据学生ID查询学院ID + Long collegeId = baseMapper.selectCollegeIdByStudentId(studentId); + if (collegeId == null) { + log.warn("未找到学生对应的学院信息 - 学生ID: {}", studentId); + return new ArrayList<>(); + } + + log.info("学生所在学院ID: {}", collegeId); + + // 2. 根据学院ID查询二级学院分管领导ID列表 + List leaderIds = baseMapper.selectCollegeLeaderIdsByCollegeId(collegeId); + + log.info("找到的二级学院分管领导数量: {}", leaderIds.size()); + return leaderIds; + } + /** * 批量申请床位 * diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/ejxyfgld/XgCollegeLeaderMapper.xml b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/ejxyfgld/XgCollegeLeaderMapper.xml new file mode 100644 index 00000000..91d2a198 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/ejxyfgld/XgCollegeLeaderMapper.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/studentMsg/XgStudentMsgMapper.xml b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/studentMsg/XgStudentMsgMapper.xml index 1c7de23c..64ddfac8 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/studentMsg/XgStudentMsgMapper.xml +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/studentMsg/XgStudentMsgMapper.xml @@ -171,6 +171,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND (d.dept_id = #{collegeId} OR FIND_IN_SET(#{collegeId}, d.ancestors)) + + + + SELECT + DISTINCT manager_type + FROM + xg_dorm_manager + WHERE + user_id = #{userId} + AND deleted = '0' + AND status = '0' + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xg/XgSysUserMapper.xml b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xg/XgSysUserMapper.xml index bd36d7d1..bbd8553a 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xg/XgSysUserMapper.xml +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/xg/XgSysUserMapper.xml @@ -6,10 +6,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + @@ -18,7 +20,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select user_id, nick_name, phonenumber + select user_id, user_name, nick_name, phonenumber, account_type from sys_user where status = '0' and del_flag = '0' and account_type = #{accountType} order by create_time desc diff --git a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/controller/XskhDisciplineRecordController.java b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/controller/XskhDisciplineRecordController.java index be7e95fc..a692de04 100644 --- a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/controller/XskhDisciplineRecordController.java +++ b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/controller/XskhDisciplineRecordController.java @@ -112,6 +112,18 @@ public class XskhDisciplineRecordController extends BaseController { return R.ok(xskhDisciplineRecordService.getStudentOptions(keyword)); } + /** + * 分页查询学生选项列表(用于移动端) + */ + @SaCheckPermission("disciplineRecord:disciplineRecord:query") + @GetMapping("/studentOptionsPage") + public R> getStudentOptionsPage( + @RequestParam(required = false) String keyword, + @RequestParam(required = false, defaultValue = "1") Integer pageNum, + @RequestParam(required = false, defaultValue = "20") Integer pageSize) { + return R.ok(xskhDisciplineRecordService.getStudentOptionsPage(keyword, pageNum, pageSize)); + } + /** * 查询当前登录学生的违纪处分记录列表 */ @@ -166,4 +178,14 @@ public class XskhDisciplineRecordController extends BaseController { @RequestParam String endTime) { return R.ok(xskhDisciplineRecordService.getMaxScoreByTypeAndPeriod(typeId, startTime, endTime)); } + + /** + * 查询当前用户创建的违纪记录列表(支持按学生姓名或学号搜索) + */ + @SaCheckPermission("disciplineRecord:disciplineRecord:query") + @GetMapping("/myCreated") + public TableDataInfo getMyCreatedDisciplineRecords(XskhDisciplineRecordBo bo, + PageQuery pageQuery) { + return xskhDisciplineRecordService.queryMyCreatedPageList(bo, pageQuery); + } } diff --git a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/mapper/XskhDisciplineRecordMapper.java b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/mapper/XskhDisciplineRecordMapper.java index 75db4990..c93965ff 100644 --- a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/mapper/XskhDisciplineRecordMapper.java +++ b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/mapper/XskhDisciplineRecordMapper.java @@ -22,10 +22,14 @@ public interface XskhDisciplineRecordMapper extends BaseMapperPlus selectStudentOptions(String keyword); + List selectStudentOptions(@Param("keyword") String keyword, + @Param("pageNum") Integer pageNum, + @Param("pageSize") Integer pageSize); /** * 查询班主任班级的违纪处分记录列表(班主任专用) @@ -78,7 +82,7 @@ public interface XskhDisciplineRecordMapper extends BaseMapperPlus getStudentOptions(String keyword); + /** + * 分页查询学生选项列表(用于移动端) + * + * @param keyword 搜索关键词 + * @param pageNum 页码 + * @param pageSize 每页数量 + * @return 学生选项列表 + */ + List getStudentOptionsPage(String keyword, Integer pageNum, Integer pageSize); + /** * 查询当前登录学生的违纪处分记录列表 */ @@ -101,4 +114,13 @@ public interface IXskhDisciplineRecordService { * @return 最高总扣分 */ java.math.BigDecimal getMaxScoreByTypeAndPeriod(Long typeId, String startTime, String endTime); + + /** + * 查询当前用户创建的违纪记录列表(支持按学生姓名或学号搜索) + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 违纪记录分页列表 + */ + TableDataInfo queryMyCreatedPageList(XskhDisciplineRecordBo bo, PageQuery pageQuery); } diff --git a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/impl/XskhDisciplineRecordServiceImpl.java b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/impl/XskhDisciplineRecordServiceImpl.java index 97a73cbf..69798c8e 100644 --- a/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/impl/XskhDisciplineRecordServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-xskh/src/main/java/org/dromara/xskh/service/impl/XskhDisciplineRecordServiceImpl.java @@ -165,7 +165,15 @@ public class XskhDisciplineRecordServiceImpl implements IXskhDisciplineRecordSer */ @Override public List getStudentOptions(String keyword) { - return baseMapper.selectStudentOptions(keyword); + return baseMapper.selectStudentOptions(keyword, null, null); + } + + /** + * 分页查询学生选项列表(用于移动端) + */ + @Override + public List getStudentOptionsPage(String keyword, Integer pageNum, Integer pageSize) { + return baseMapper.selectStudentOptions(keyword, pageNum, pageSize); } /** @@ -286,4 +294,46 @@ public class XskhDisciplineRecordServiceImpl implements IXskhDisciplineRecordSer log.info("违纪类型 {} 的最高总扣分为: {}", typeId, maxScore); return maxScore; } + + /** + * 查询当前用户创建的违纪记录列表(支持按学生姓名或学号搜索) + */ + @Override + public TableDataInfo queryMyCreatedPageList(XskhDisciplineRecordBo bo, + PageQuery pageQuery) { + // 获取当前登录用户ID + Long currentUserId = LoginHelper.getUserId(); + log.info("查询用户 {} 创建的违纪记录列表", currentUserId); + + // 构建查询条件,强制只查询当前用户创建的记录 + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + + // 核心条件:只查询当前用户创建的记录 + lqw.eq(XskhDisciplineRecord::getCreateBy, currentUserId); + + // 支持按学生姓名或学号模糊搜索(使用OR连接) + if (StringUtils.isNotBlank(bo.getStudentName()) || StringUtils.isNotBlank(bo.getStudentNo())) { + String keyword = StringUtils.isNotBlank(bo.getStudentName()) ? bo.getStudentName() : bo.getStudentNo(); + lqw.and(wrapper -> wrapper + .like(XskhDisciplineRecord::getStudentName, keyword) + .or() + .like(XskhDisciplineRecord::getStudentNo, keyword)); + } + + // 其他可选查询条件 + lqw.eq(bo.getStudentId() != null, XskhDisciplineRecord::getStudentId, bo.getStudentId()); + lqw.eq(bo.getCollegeId() != null, XskhDisciplineRecord::getCollegeId, bo.getCollegeId()); + lqw.eq(bo.getMajorId() != null, XskhDisciplineRecord::getMajorId, bo.getMajorId()); + lqw.eq(bo.getClassId() != null, XskhDisciplineRecord::getClassId, bo.getClassId()); + lqw.eq(bo.getDisciplineTypeId() != null, XskhDisciplineRecord::getDisciplineTypeId, bo.getDisciplineTypeId()); + lqw.eq(StringUtils.isNotBlank(bo.getStatus()), XskhDisciplineRecord::getStatus, bo.getStatus()); + + // 按创建时间倒序排列 + lqw.orderByDesc(XskhDisciplineRecord::getCreateTime); + + // 执行分页查询 + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + log.info("查询到 {} 条记录", result.getTotal()); + return TableDataInfo.build(result); + } } diff --git a/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/XskhDisciplineRecordMapper.xml b/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/XskhDisciplineRecordMapper.xml index ac51253f..18e6125c 100644 --- a/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/XskhDisciplineRecordMapper.xml +++ b/backend/ruoyi-modules/ruoyi-xskh/src/main/resources/mapper/XskhDisciplineRecordMapper.xml @@ -49,7 +49,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select id, student_id, student_no, student_name, college_id, college_name, major_id, major_name, class_id, class_name, discipline_type_id, discipline_type_name, discipline_date, discipline_reason, discipline_content, score_deduction, status, violation_source, attachment_oss_ids, create_by, create_time, create_dept, update_by, update_time, deleted, tenant_id from xskh_discipline_record - select id, student_no, name, college_id, college_name, major_id, major_name, class_id, class_name @@ -61,7 +61,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" or name like concat('%', #{keyword}, '%')) order by student_no - limit 50 + + + limit ${(pageNum - 1) * pageSize}, #{pageSize, jdbcType=INTEGER} + + + limit 50 + +