“出国申请审批权限修改”

This commit is contained in:
weizhong committed 2025-10-28 14:11:39 +08:00
commit f907b9cd40
97 files changed
+18070 -2812

No files matched your search

@@ -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@
@@ -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:
@@ -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;
/**
* 通知
*/
@@ -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;
/**
* 消息通知
*/
@@ -151,6 +151,11 @@ public class FlowHisTaskVo implements Serializable {
*/
private String message;
/**
* 手写签名(Base64编码的图片数据)
*/
private String signature;
/**
* 业务详情 存业务类的json
*/
@@ -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<FlowHisTaskVo> selectHisTaskListWithSignature(@Param("instanceId") Long instanceId,
@Param("nodeType") Integer nodeType);
}
@@ -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<FlowInstanceBo> buildQueryWrapper(FlowInstanceBo flowInstanceBo) {
QueryWrapper<FlowInstanceBo> 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<Long> categoryIds = flwCategoryMapper.selectCategoryIdsByParentId(Convert.toLong(flowInstanceBo.getCategory()));
List<Long> 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<FlowInstance>().eq(FlowInstance::getBusinessId, businessId));
return flowInstanceMapper
.selectOne(new LambdaQueryWrapper<FlowInstance>().eq(FlowInstance::getBusinessId, businessId));
}
/**
@@ -180,7 +189,8 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
@Override
@Transactional(rollbackFor = Exception.class)
public boolean deleteByBusinessIds(List<Long> businessIds) {
List<FlowInstance> flowInstances = flowInstanceMapper.selectList(new LambdaQueryWrapper<FlowInstance>().in(FlowInstance::getBusinessId, StreamUtils.toList(businessIds, Convert::toStr)));
List<FlowInstance> flowInstances = flowInstanceMapper.selectList(new LambdaQueryWrapper<FlowInstance>()
.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<Long, Definition> 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<FlowHisTaskVo> list = new ArrayList<>();
List<FlowTask> flowTaskList = flwTaskService.selectByInstId(instanceId);
if (CollUtil.isNotEmpty(flowTaskList)) {
@@ -302,16 +312,13 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
}
list.addAll(flowHisTaskVos);
}
//历史任务
LambdaQueryWrapper<FlowHisTask> wrapper = Wrappers.lambdaQuery();
wrapper.eq(FlowHisTask::getInstanceId, instanceId);
wrapper.eq(FlowHisTask::getNodeType, NodeType.BETWEEN.getKey());
wrapper.orderByDesc(FlowHisTask::getCreateTime).orderByDesc(FlowHisTask::getUpdateTime);
List<FlowHisTask> flowHisTasks = flowHisTaskMapper.selectList(wrapper);
if (CollUtil.isNotEmpty(flowHisTasks)) {
list.addAll(BeanUtil.copyToList(flowHisTasks, FlowHisTaskVo.class));
// 历史任务(使用自定义Mapper查询,包含签名字段)
List<FlowHisTaskVo> 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<String, Object> instanceVariable(Long instanceId) {
FlowInstance flowInstance = flowInstanceMapper.selectById(instanceId);
Map<String, Object> variableMap = Optional.ofNullable(flowInstance.getVariableMap()).orElse(Collections.emptyMap());
Map<String, Object> variableMap = Optional.ofNullable(flowInstance.getVariableMap())
.orElse(Collections.emptyMap());
List<Map<String, Object>> 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) {
@@ -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);
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.workflow.mapper.FlwHisTaskExtMapper">
<!-- FlowHisTaskVo结果映射 -->
<resultMap id="FlowHisTaskVoResult" type="org.dromara.workflow.domain.vo.FlowHisTaskVo">
<id property="id" column="id"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
<result property="tenantId" column="tenant_id"/>
<result property="delFlag" column="del_flag"/>
<result property="definitionId" column="definition_id"/>
<result property="instanceId" column="instance_id"/>
<result property="taskId" column="task_id"/>
<result property="cooperateType" column="cooperate_type"/>
<result property="nodeCode" column="node_code"/>
<result property="nodeName" column="node_name"/>
<result property="nodeType" column="node_type"/>
<result property="targetNodeCode" column="target_node_code"/>
<result property="targetNodeName" column="target_node_name"/>
<result property="approver" column="approver"/>
<result property="collaborator" column="collaborator"/>
<result property="skipType" column="skip_type"/>
<result property="flowStatus" column="flow_status"/>
<result property="message" column="message"/>
<result property="signature" column="signature"/>
<result property="ext" column="ext"/>
<result property="formCustom" column="form_custom"/>
<result property="formPath" column="form_path"/>
</resultMap>
<!-- 根据实例ID查询历史任务列表(包含签名字段) -->
<select id="selectHisTaskListWithSignature" resultMap="FlowHisTaskVoResult">
SELECT
id,
create_time,
update_time,
tenant_id,
del_flag,
definition_id,
instance_id,
task_id,
cooperate_type,
node_code,
node_name,
node_type,
target_node_code,
target_node_name,
approver,
collaborator,
skip_type,
flow_status,
message,
signature,
ext,
form_custom,
form_path
FROM flow_his_task
WHERE instance_id = #{instanceId}
AND node_type = #{nodeType}
AND del_flag = '0'
ORDER BY create_time DESC, update_time DESC
</select>
</mapper>
@@ -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,
@@ -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<XgCollegeLeaderVo> list(XgCollegeLeaderBo bo, PageQuery pageQuery) {
return xgCollegeLeaderService.queryPageList(bo, pageQuery);
}
/**
* 根据学院ID查询分管领导列表
*/
@Operation(summary = "根据学院ID查询分管领导列表")
@SaCheckPermission("xg:ejxyfgld:list")
@GetMapping("/listByCollege/{collegeId}")
public R<List<XgCollegeLeaderVo>> listByCollege(@PathVariable Long collegeId) {
List<XgCollegeLeaderVo> 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<XgCollegeLeaderVo> list = xgCollegeLeaderService.queryList(bo);
ExcelUtil.exportExcel(list, "二级学院分管领导配置", XgCollegeLeaderVo.class, response);
}
/**
* 获取二级学院分管领导配置详细信息
*
* @param id 主键
*/
@Operation(summary = "获取二级学院分管领导配置详细信息")
@SaCheckPermission("xg:ejxyfgld:query")
@GetMapping("/{id}")
public R<XgCollegeLeaderVo> 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<Void> 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<Void> 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<Void> remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) {
return toAjax(xgCollegeLeaderService.deleteWithValidByIds(List.of(ids), true));
}
}
@@ -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<XgDormApplicationVo> getDormApplicationList(XgDormApplicationBo bo, PageQuery pageQuery) {
return xgStudentDynamicsService.queryDormApplicationPageList(bo, pageQuery);
}
/**
* 查询宿管员权限内的学生假期留宿信息列表
*/
@SaCheckPermission("studentDynamics:holidayStay:list")
@GetMapping("/holidayStayList")
public TableDataInfo<XgHolidayStayVo> getHolidayStayList(XgHolidayStayBo bo, PageQuery pageQuery) {
return xgStudentDynamicsService.queryHolidayStayPageList(bo, pageQuery);
}
/**
* 查询宿管员权限内的学生请假信息列表
*/
@SaCheckPermission("studentDynamics:studentLeave:list")
@GetMapping("/studentLeaveList")
public TableDataInfo<XgStudentLeaveVo> getStudentLeaveList(XgStudentLeaveBo bo, PageQuery pageQuery) {
return xgStudentDynamicsService.queryStudentLeavePageList(bo, pageQuery);
}
/**
* 获取调宿退宿申请详细信息
*/
@SaCheckPermission("studentDynamics:dormApplication:query")
@GetMapping("/dormApplication/{id}")
public R<XgDormApplicationVo> getDormApplicationInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
return R.ok(xgStudentDynamicsService.queryDormApplicationById(id));
}
/**
* 获取假期留宿详细信息
*/
@SaCheckPermission("studentDynamics:holidayStay:query")
@GetMapping("/holidayStay/{id}")
public R<XgHolidayStayVo> getHolidayStayInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
return R.ok(xgStudentDynamicsService.queryHolidayStayById(id));
}
/**
* 获取学生请假详细信息
*/
@SaCheckPermission("studentDynamics:studentLeave:query")
@GetMapping("/studentLeave/{id}")
public R<XgStudentLeaveVo> getStudentLeaveInfo(@NotNull(message = "主键不能为空") @PathVariable Long id) {
return R.ok(xgStudentDynamicsService.queryStudentLeaveById(id));
}
}
@@ -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<List<Long>> getCollegeLeaders(@NotNull(message = "学生ID不能为空") @PathVariable Long studentId) {
log.info("根据学生ID获取二级学院分管领导ID列表 - 学生ID: {}", studentId);
List<Long> leaderIds = xgStudentMsgService.getCollegeLeadersByStudentId(studentId);
if (leaderIds.isEmpty()) {
return R.fail("未找到该学生所在学院的分管领导");
}
return R.ok(leaderIds);
}
/**
* 导入数据
*
@@ -28,7 +28,7 @@ public class XgSysUserController extends BaseController {
private final IXgSysUserService xgSysUserService;
/**
* 查询有效用户列表
* 查询有效用户列表(教职工account_type=1)
*/
@SaCheckPermission("xg:sysUser:list")
@GetMapping("/activeList")
@@ -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;
}
@@ -27,6 +27,11 @@ public class XgSysUser extends TenantEntity {
@TableId(value = "user_id")
private Long userId;
/**
* 用户账号
*/
private String userName;
/**
* 用户昵称
*/
@@ -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;
}
@@ -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;
}
@@ -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<XgCollegeLeader, XgCollegeLeaderVo> {
}
@@ -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<String> checkUserDormManagerType(@Param("userId") Long userId);
/**
* 获取全校管理员权限的所有楼栋ID列表
*
* @param userId 用户ID
* @return 楼栋ID列表
*/
List<Long> getBuildingIdsBySchoolAdmin(@Param("userId") Long userId);
/**
* 获取校区管理员权限的楼栋ID列表
*
* @param userId 用户ID
* @return 楼栋ID列表
*/
List<Long> getBuildingIdsByCampusAdmin(@Param("userId") Long userId);
/**
* 获取宿舍区管理员权限的楼栋ID列表
*
* @param userId 用户ID
* @return 楼栋ID列表
*/
List<Long> getBuildingIdsByAreaAdmin(@Param("userId") Long userId);
/**
* 获取宿舍楼管理员权限的楼栋ID列表
*
* @param userId 用户ID
* @return 楼栋ID列表
*/
List<Long> getBuildingIdsByBuildingAdmin(@Param("userId") Long userId);
/**
* 获取全校管理员权限的所有学生ID列表
*
* @param userId 用户ID
* @return 学生ID列表
*/
List<Long> getStudentIdsBySchoolAdmin(@Param("userId") Long userId);
/**
* 获取校区管理员权限的学生ID列表
*
* @param userId 用户ID
* @return 学生ID列表
*/
List<Long> getStudentIdsByCampusAdmin(@Param("userId") Long userId);
/**
* 获取宿舍区管理员权限的学生ID列表
*
* @param userId 用户ID
* @return 学生ID列表
*/
List<Long> getStudentIdsByAreaAdmin(@Param("userId") Long userId);
/**
* 获取宿舍楼管理员权限的学生ID列表
*
* @param userId 用户ID
* @return 学生ID列表
*/
List<Long> getStudentIdsByBuildingAdmin(@Param("userId") Long userId);
}
@@ -19,87 +19,95 @@ import java.util.Map;
*/
public interface XgStudentMsgMapper extends BaseMapperPlus<XgStudentMsg, XgStudentMsgVo> {
/**
* 根据组织ID列表分页查询学生信息 用于导出
*
* @param page 分页参数
* @param queryWrapper 查询条件
* @param deptIds 组织ID列表
* @return 学生信息分页结果
*/
List<XgStudentMsgExportVo> queryPageListExportByDeptId(
@Param("ew") LambdaQueryWrapper<XgStudentMsg> queryWrapper,
@Param("deptIds") List<Long> deptIds);
/**
* 根据组织ID列表分页查询学生信息 用于导出
*
* @param page 分页参数
* @param queryWrapper 查询条件
* @param deptIds 组织ID列表
* @return 学生信息分页结果
*/
List<XgStudentMsgExportVo> queryPageListExportByDeptId(
@Param("ew") LambdaQueryWrapper<XgStudentMsg> queryWrapper,
@Param("deptIds") List<Long> deptIds);
/**
* 根据组织ID列表分页查询学生信息
*
* @param page 分页参数
* @param queryWrapper 查询条件
* @param deptIds 组织ID列表
* @return 学生信息分页结果
*/
Page<XgStudentMsgVo> selectPageByDeptIds(@Param("page") Page<XgStudentMsgVo> page,
@Param("ew") LambdaQueryWrapper<XgStudentMsg> queryWrapper,
@Param("deptIds") List<Long> deptIds);
/**
* 根据组织ID列表分页查询学生信息
*
* @param page 分页参数
* @param queryWrapper 查询条件
* @param deptIds 组织ID列表
* @return 学生信息分页结果
*/
Page<XgStudentMsgVo> selectPageByDeptIds(@Param("page") Page<XgStudentMsgVo> page,
@Param("ew") LambdaQueryWrapper<XgStudentMsg> queryWrapper,
@Param("deptIds") List<Long> deptIds);
/**
* 根据班级ID和姓名查询学生信息列表
*
* @param classId 班级ID
* @param name 学生姓名(模糊查询)
* @return 学生信息列表
*/
List<XgStudentMsgVo> selectStudentsByClassId(@Param("classId") String classId, @Param("name") String name);
/**
* 根据班级ID和姓名查询学生信息列表
*
* @param classId 班级ID
* @param name 学生姓名(模糊查询)
* @return 学生信息列表
*/
List<XgStudentMsgVo> 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<Long> selectUserIdsByCollegeIdAndRoleKey(@Param("collegeId") Long collegeId,
@Param("roleKey") String roleKey);
/**
* 根据学院ID和角色Key查询具备该角色的用户列表
*
* @param collegeId 学院ID
* @param roleKey 角色Key
* @return 用户ID列表
*/
List<Long> selectUserIdsByCollegeIdAndRoleKey(@Param("collegeId") Long collegeId,
@Param("roleKey") String roleKey);
/**
* 查询二级学院下的学院、专业、班级学生统计信息
*
* @param secondaryCollegeId 二级学院ID
* @return 学生统计信息列表
*/
List<Map<String, Object>> getCollegeStudentStats(@Param("secondaryCollegeId") Long secondaryCollegeId);
/**
* 根据学院ID查询二级学院分管领导ID列表
*
* @param collegeId 学院ID
* @return 分管领导ID列表
*/
List<Long> selectCollegeLeaderIdsByCollegeId(@Param("collegeId") Long collegeId);
/**
* 查询二级学院下的学院、专业、班级学生统计信息(按床位分配统计)
*
* @param secondaryCollegeId 二级学院ID
* @return 学生统计信息列表
*/
List<Map<String, Object>> getCollegeStudentStatsByClass(@Param("secondaryCollegeId") Long secondaryCollegeId);
/**
* 查询二级学院下的学院、专业、班级学生统计信息
*
* @param secondaryCollegeId 二级学院ID
* @return 学生统计信息列表
*/
List<Map<String, Object>> getCollegeStudentStats(@Param("secondaryCollegeId") Long secondaryCollegeId);
/**
* 查询二级学院下的学院床位分配统计信息(基于college_id统计)
*
* @param secondaryCollegeId 二级学院ID
* @return 学院床位分配统计信息列表
*/
List<Map<String, Object>> getCollegeBedAssignmentStats(@Param("secondaryCollegeId") Long secondaryCollegeId);
/**
* 查询二级学院下的学院、专业、班级学生统计信息(按床位分配统计)
*
* @param secondaryCollegeId 二级学院ID
* @return 学生统计信息列表
*/
List<Map<String, Object>> getCollegeStudentStatsByClass(@Param("secondaryCollegeId") Long secondaryCollegeId);
/**
* 查询二级学院下的学院床位分配统计信息(基于college_id统计)
*
* @param secondaryCollegeId 二级学院ID
* @return 学院床位分配统计信息列表
*/
List<Map<String, Object>> getCollegeBedAssignmentStats(@Param("secondaryCollegeId") Long secondaryCollegeId);
}
@@ -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<XgCollegeLeaderVo> queryPageList(XgCollegeLeaderBo bo, PageQuery pageQuery);
/**
* 查询符合条件的二级学院分管领导配置列表
*
* @param bo 查询条件
* @return 二级学院分管领导配置列表
*/
List<XgCollegeLeaderVo> 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<Long> ids, Boolean isValid);
/**
* 根据学院ID查询分管领导列表
*
* @param collegeId 学院ID
* @return 分管领导列表
*/
List<XgCollegeLeaderVo> queryByCollegeId(Long collegeId);
}
@@ -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<XgDormApplicationVo> queryDormApplicationPageList(XgDormApplicationBo bo, PageQuery pageQuery);
/**
* 查询宿管员权限内的学生假期留宿信息列表
*/
TableDataInfo<XgHolidayStayVo> queryHolidayStayPageList(XgHolidayStayBo bo, PageQuery pageQuery);
/**
* 查询宿管员权限内的学生请假信息列表
*/
TableDataInfo<XgStudentLeaveVo> queryStudentLeavePageList(XgStudentLeaveBo bo, PageQuery pageQuery);
/**
* 根据主键查询调宿退宿申请详情
*/
XgDormApplicationVo queryDormApplicationById(Long id);
/**
* 根据主键查询假期留宿详情
*/
XgHolidayStayVo queryHolidayStayById(Long id);
/**
* 根据主键查询学生请假详情
*/
XgStudentLeaveVo queryStudentLeaveById(Long id);
}
@@ -140,6 +140,14 @@ public interface IXgStudentMsgService {
*/
List<Long> getCollegeLeaveApproversByStudentId(Long studentId);
/**
* 根据学生ID获取二级学院分管领导ID列表
*
* @param studentId 学生ID
* @return 分管领导ID列表
*/
List<Long> getCollegeLeadersByStudentId(Long studentId);
/**
* 批量申请床位
*
@@ -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<XgCollegeLeaderVo> queryPageList(XgCollegeLeaderBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<XgCollegeLeader> lqw = buildQueryWrapper(bo);
Page<XgCollegeLeaderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的二级学院分管领导配置列表
*
* @param bo 查询条件
* @return 二级学院分管领导配置列表
*/
@Override
public List<XgCollegeLeaderVo> queryList(XgCollegeLeaderBo bo) {
LambdaQueryWrapper<XgCollegeLeader> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
/**
* 根据学院ID查询分管领导列表
*
* @param collegeId 学院ID
* @return 分管领导列表
*/
@Override
public List<XgCollegeLeaderVo> queryByCollegeId(Long collegeId) {
LambdaQueryWrapper<XgCollegeLeader> lqw = Wrappers.lambdaQuery();
lqw.eq(XgCollegeLeader::getCollegeId, collegeId);
lqw.orderByDesc(XgCollegeLeader::getCreateTime);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<XgCollegeLeader> buildQueryWrapper(XgCollegeLeaderBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<XgCollegeLeader> 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<XgCollegeLeader> 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<Long> ids, Boolean isValid) {
if (isValid) {
// 可以添加业务校验逻辑
}
return baseMapper.deleteByIds(ids) > 0;
}
}
@@ -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<XgDormApplicationVo> queryDormApplicationPageList(XgDormApplicationBo bo,
PageQuery pageQuery) {
// 获取当前登录用户ID
Long currentUserId = LoginHelper.getUserId();
// 构建查询条件
LambdaQueryWrapper<XgDormApplication> lqw = buildDormApplicationQueryWrapper(bo, currentUserId);
// 分页查询
Page<XgDormApplicationVo> result = dormApplicationMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询宿管员权限内的学生假期留宿信息列表
*/
@Override
public TableDataInfo<XgHolidayStayVo> queryHolidayStayPageList(XgHolidayStayBo bo, PageQuery pageQuery) {
// 获取当前登录用户ID
Long currentUserId = LoginHelper.getUserId();
// 构建查询条件
LambdaQueryWrapper<XgHolidayStay> lqw = buildHolidayStayQueryWrapper(bo, currentUserId);
// 分页查询
Page<XgHolidayStayVo> result = holidayStayMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询宿管员权限内的学生请假信息列表
*/
@Override
public TableDataInfo<XgStudentLeaveVo> queryStudentLeavePageList(XgStudentLeaveBo bo, PageQuery pageQuery) {
// 获取当前登录用户ID
Long currentUserId = LoginHelper.getUserId();
// 构建查询条件
LambdaQueryWrapper<XgStudentLeave> lqw = buildStudentLeaveQueryWrapper(bo, currentUserId);
// 分页查询
Page<XgStudentLeaveVo> 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<XgDormApplication> buildDormApplicationQueryWrapper(XgDormApplicationBo bo,
Long currentUserId) {
LambdaQueryWrapper<XgDormApplication> lqw = new LambdaQueryWrapper<>();
// 获取宿管员管理的楼栋ID列表
List<Long> 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<XgHolidayStay> buildHolidayStayQueryWrapper(XgHolidayStayBo bo, Long currentUserId) {
LambdaQueryWrapper<XgHolidayStay> lqw = new LambdaQueryWrapper<>();
// 获取宿管员管理的楼栋ID列表
List<Long> 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<XgStudentLeave> buildStudentLeaveQueryWrapper(XgStudentLeaveBo bo, Long currentUserId) {
LambdaQueryWrapper<XgStudentLeave> lqw = new LambdaQueryWrapper<>();
// 获取宿管员权限内的学生ID列表
List<Long> 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<Long> getManagedBuildingIds(Long userId) {
// 查询用户管理权限类型
List<String> managerTypes = studentDynamicsMapper.checkUserDormManagerType(userId);
if (managerTypes == null || managerTypes.isEmpty()) {
// 没有宿舍管理权限,返回空列表
return new ArrayList<>();
}
// 存储所有权限的楼栋ID,使用Set去重
Set<Long> buildingIdSet = new HashSet<>();
// 按照权限分别查询并合并结果(支持用户拥有多种角色的情况)
if (managerTypes.contains("1")) {
// 全校管理员,获取所有楼栋
List<Long> allBuildings = studentDynamicsMapper.getBuildingIdsBySchoolAdmin(userId);
if (allBuildings != null) {
buildingIdSet.addAll(allBuildings);
}
// 全校管理员可以查看所有楼栋,直接返回
return new ArrayList<>(buildingIdSet);
}
// 对于非全校管理员,合并多种权限的结果
if (managerTypes.contains("2")) {
// 校区管理员,获取管理的校区下的楼栋
List<Long> campusBuildings = studentDynamicsMapper.getBuildingIdsByCampusAdmin(userId);
if (campusBuildings != null) {
buildingIdSet.addAll(campusBuildings);
}
}
if (managerTypes.contains("3")) {
// 宿舍区管理员,获取管理的宿舍区下的楼栋
List<Long> areaBuildings = studentDynamicsMapper.getBuildingIdsByAreaAdmin(userId);
if (areaBuildings != null) {
buildingIdSet.addAll(areaBuildings);
}
}
if (managerTypes.contains("4")) {
// 宿舍楼管理员,获取管理的楼栋
List<Long> directBuildings = studentDynamicsMapper.getBuildingIdsByBuildingAdmin(userId);
if (directBuildings != null) {
buildingIdSet.addAll(directBuildings);
}
}
return new ArrayList<>(buildingIdSet);
}
/**
* 获取宿管员权限内的学生ID列表(支持多级权限合并)
*/
private List<Long> getManagedStudentIds(Long userId) {
// 查询用户管理权限类型
List<String> managerTypes = studentDynamicsMapper.checkUserDormManagerType(userId);
if (managerTypes == null || managerTypes.isEmpty()) {
// 没有宿舍管理权限,返回空列表
return new ArrayList<>();
}
// 存储所有权限的学生ID,使用Set去重
Set<Long> studentIdSet = new HashSet<>();
// 按照权限分别查询并合并结果(支持用户拥有多种角色的情况)
if (managerTypes.contains("1")) {
// 全校管理员,获取所有学生
List<Long> allStudents = studentDynamicsMapper.getStudentIdsBySchoolAdmin(userId);
if (allStudents != null) {
studentIdSet.addAll(allStudents);
}
// 全校管理员可以查看所有学生,直接返回
return new ArrayList<>(studentIdSet);
}
// 对于非全校管理员,合并多种权限的结果
if (managerTypes.contains("2")) {
// 校区管理员,获取管理的校区下的学生
List<Long> campusStudents = studentDynamicsMapper.getStudentIdsByCampusAdmin(userId);
if (campusStudents != null) {
studentIdSet.addAll(campusStudents);
}
}
if (managerTypes.contains("3")) {
// 宿舍区管理员,获取管理的宿舍区下的学生
List<Long> areaStudents = studentDynamicsMapper.getStudentIdsByAreaAdmin(userId);
if (areaStudents != null) {
studentIdSet.addAll(areaStudents);
}
}
if (managerTypes.contains("4")) {
// 宿舍楼管理员,获取管理的楼栋下的学生
List<Long> buildingStudents = studentDynamicsMapper.getStudentIdsByBuildingAdmin(userId);
if (buildingStudents != null) {
studentIdSet.addAll(buildingStudents);
}
}
return new ArrayList<>(studentIdSet);
}
}
@@ -1095,6 +1095,32 @@ public class XgStudentMsgServiceImpl implements IXgStudentMsgService {
return approverUserIds;
}
/**
* 根据学生ID获取二级学院分管领导ID列表
*
* @param studentId 学生ID
* @return 分管领导ID列表
*/
@Override
public List<Long> 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<Long> leaderIds = baseMapper.selectCollegeLeaderIdsByCollegeId(collegeId);
log.info("找到的二级学院分管领导数量: {}", leaderIds.size());
return leaderIds;
}
/**
* 批量申请床位
*
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.xg.mapper.XgCollegeLeaderMapper">
</mapper>
@@ -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>
<!-- 根据学院ID查询二级学院分管领导ID列表 -->
<select id="selectCollegeLeaderIdsByCollegeId" resultType="java.lang.Long">
SELECT leader_id
FROM xg_college_leader
WHERE college_id = #{collegeId}
AND deleted = 0
</select>
<!-- 查询二级学院下的学院、专业、班级学生统计信息 -->
<select id="getCollegeStudentStats" resultType="java.util.Map">
SELECT
@@ -0,0 +1,213 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.xg.mapper.XgStudentDynamicsMapper">
<!-- 检查用户是否有宿舍管理权限 -->
<select id="checkUserDormManagerType" resultType="String">
SELECT
DISTINCT manager_type
FROM
xg_dorm_manager
WHERE
user_id = #{userId}
AND deleted = '0'
AND status = '0'
</select>
<!-- 获取全校管理员权限的所有楼栋ID列表 -->
<select id="getBuildingIdsBySchoolAdmin" resultType="Long">
SELECT
id
FROM
xg_dorm_building
WHERE
deleted = '0'
AND EXISTS (
SELECT 1 FROM xg_dorm_manager m
WHERE m.user_id = #{userId}
AND m.manager_type = '1'
AND m.deleted = '0'
AND m.status = '0'
)
</select>
<!-- 获取校区管理员权限的楼栋ID列表 -->
<select id="getBuildingIdsByCampusAdmin" resultType="Long">
SELECT
b.id
FROM
xg_dorm_building b
WHERE
b.deleted = '0'
AND b.campus_id IN (
SELECT
s.auth_source
FROM
xg_dorm_manager m
JOIN
xg_dorm_manager_source s ON m.id = s.manager_id
WHERE
m.user_id = #{userId}
AND m.manager_type = '2'
AND m.deleted = '0'
AND m.status = '0'
AND s.deleted = '0'
AND s.status = '0'
)
</select>
<!-- 获取宿舍区管理员权限的楼栋ID列表 -->
<select id="getBuildingIdsByAreaAdmin" resultType="Long">
SELECT
b.id
FROM
xg_dorm_building b
WHERE
b.deleted = '0'
AND b.area_id IN (
SELECT
s.auth_source
FROM
xg_dorm_manager m
JOIN
xg_dorm_manager_source s ON m.id = s.manager_id
WHERE
m.user_id = #{userId}
AND m.manager_type = '3'
AND m.deleted = '0'
AND m.status = '0'
AND s.deleted = '0'
AND s.status = '0'
)
</select>
<!-- 获取宿舍楼管理员权限的楼栋ID列表 -->
<select id="getBuildingIdsByBuildingAdmin" resultType="Long">
SELECT
b.id
FROM
xg_dorm_building b
WHERE
b.deleted = '0'
AND b.id IN (
SELECT
s.auth_source
FROM
xg_dorm_manager m
JOIN
xg_dorm_manager_source s ON m.id = s.manager_id
WHERE
m.user_id = #{userId}
AND m.manager_type = '4'
AND m.deleted = '0'
AND m.status = '0'
AND s.deleted = '0'
AND s.status = '0'
)
</select>
<!-- 获取全校管理员权限的所有学生ID列表 -->
<select id="getStudentIdsBySchoolAdmin" resultType="Long">
SELECT
sm.id
FROM
xg_student_msg sm
WHERE
sm.deleted = 0
AND EXISTS (
SELECT 1 FROM xg_dorm_manager m
WHERE m.user_id = #{userId}
AND m.manager_type = '1'
AND m.deleted = '0'
AND m.status = '0'
)
</select>
<!-- 获取校区管理员权限的学生ID列表 -->
<select id="getStudentIdsByCampusAdmin" resultType="Long">
SELECT
sm.id
FROM
xg_student_msg sm
INNER JOIN
xg_dorm_building db ON sm.dormitory_building = db.id
WHERE
sm.deleted = 0
AND db.deleted = '0'
AND db.campus_id IN (
SELECT
s.auth_source
FROM
xg_dorm_manager m
JOIN
xg_dorm_manager_source s ON m.id = s.manager_id
WHERE
m.user_id = #{userId}
AND m.manager_type = '2'
AND m.deleted = '0'
AND m.status = '0'
AND s.deleted = '0'
AND s.status = '0'
)
</select>
<!-- 获取宿舍区管理员权限的学生ID列表 -->
<select id="getStudentIdsByAreaAdmin" resultType="Long">
SELECT
sm.id
FROM
xg_student_msg sm
INNER JOIN
xg_dorm_building db ON sm.dormitory_building = db.id
WHERE
sm.deleted = 0
AND db.deleted = '0'
AND db.area_id IN (
SELECT
s.auth_source
FROM
xg_dorm_manager m
JOIN
xg_dorm_manager_source s ON m.id = s.manager_id
WHERE
m.user_id = #{userId}
AND m.manager_type = '3'
AND m.deleted = '0'
AND m.status = '0'
AND s.deleted = '0'
AND s.status = '0'
)
</select>
<!-- 获取宿舍楼管理员权限的学生ID列表 -->
<select id="getStudentIdsByBuildingAdmin" resultType="Long">
SELECT
sm.id
FROM
xg_student_msg sm
INNER JOIN
xg_dorm_building db ON sm.dormitory_building = db.id
WHERE
sm.deleted = 0
AND db.deleted = '0'
AND db.id IN (
SELECT
s.auth_source
FROM
xg_dorm_manager m
JOIN
xg_dorm_manager_source s ON m.id = s.manager_id
WHERE
m.user_id = #{userId}
AND m.manager_type = '4'
AND m.deleted = '0'
AND m.status = '0'
AND s.deleted = '0'
AND s.status = '0'
)
</select>
</mapper>
@@ -6,10 +6,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<resultMap type="org.dromara.xg.domain.XgSysUser" id="XgSysUserResult">
<id property="userId" column="user_id"/>
<result property="userName" column="user_name"/>
<result property="nickName" column="nick_name"/>
<result property="phonenumber" column="phonenumber"/>
<result property="status" column="status"/>
<result property="delFlag" column="del_flag"/>
<result property="accountType" column="account_type"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
@@ -18,7 +20,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<!-- 查询有效用户列表 -->
<select id="selectActiveUserList" resultMap="XgSysUserResult">
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'
order by create_time desc
@@ -26,7 +28,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<!-- 根据账户类型查询有效用户列表 -->
<select id="selectActiveUserListByAccountType" parameterType="String" resultMap="XgSysUserResult">
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
@@ -112,6 +112,18 @@ public class XskhDisciplineRecordController extends BaseController {
return R.ok(xskhDisciplineRecordService.getStudentOptions(keyword));
}
/**
* 分页查询学生选项列表(用于移动端)
*/
@SaCheckPermission("disciplineRecord:disciplineRecord:query")
@GetMapping("/studentOptionsPage")
public R<List<XskhStudentOptionVo>> 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<XskhDisciplineRecordVo> getMyCreatedDisciplineRecords(XskhDisciplineRecordBo bo,
PageQuery pageQuery) {
return xskhDisciplineRecordService.queryMyCreatedPageList(bo, pageQuery);
}
}
@@ -22,10 +22,14 @@ public interface XskhDisciplineRecordMapper extends BaseMapperPlus<XskhDisciplin
/**
* 查询学生选项列表(用于下拉框)
*
* @param keyword 搜索关键词(学号或姓名)
* @param keyword 搜索关键词(学号或姓名)
* @param pageNum 页码
* @param pageSize 每页数量
* @return 学生选项列表
*/
List<XskhStudentOptionVo> selectStudentOptions(String keyword);
List<XskhStudentOptionVo> selectStudentOptions(@Param("keyword") String keyword,
@Param("pageNum") Integer pageNum,
@Param("pageSize") Integer pageSize);
/**
* 查询班主任班级的违纪处分记录列表(班主任专用)
@@ -78,7 +82,7 @@ public interface XskhDisciplineRecordMapper extends BaseMapperPlus<XskhDisciplin
* @return 最高总扣分
*/
java.math.BigDecimal selectMaxScoreByTypeAndPeriod(@Param("typeId") Long typeId,
@Param("startTime") String startTime,
@Param("endTime") String endTime);
@Param("startTime") String startTime,
@Param("endTime") String endTime);
}
@@ -50,9 +50,22 @@ public interface IXskhDisciplineRecordService {
/**
* 查询学生选项列表(用于下拉框)
*
* @param keyword 搜索关键词
* @return 学生选项列表
*/
List<XskhStudentOptionVo> getStudentOptions(String keyword);
/**
* 分页查询学生选项列表(用于移动端)
*
* @param keyword 搜索关键词
* @param pageNum 页码
* @param pageSize 每页数量
* @return 学生选项列表
*/
List<XskhStudentOptionVo> 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<XskhDisciplineRecordVo> queryMyCreatedPageList(XskhDisciplineRecordBo bo, PageQuery pageQuery);
}
@@ -165,7 +165,15 @@ public class XskhDisciplineRecordServiceImpl implements IXskhDisciplineRecordSer
*/
@Override
public List<XskhStudentOptionVo> getStudentOptions(String keyword) {
return baseMapper.selectStudentOptions(keyword);
return baseMapper.selectStudentOptions(keyword, null, null);
}
/**
* 分页查询学生选项列表(用于移动端)
*/
@Override
public List<XskhStudentOptionVo> 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<XskhDisciplineRecordVo> queryMyCreatedPageList(XskhDisciplineRecordBo bo,
PageQuery pageQuery) {
// 获取当前登录用户ID
Long currentUserId = LoginHelper.getUserId();
log.info("查询用户 {} 创建的违纪记录列表", currentUserId);
// 构建查询条件,强制只查询当前用户创建的记录
LambdaQueryWrapper<XskhDisciplineRecord> 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<XskhDisciplineRecordVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
log.info("查询到 {} 条记录", result.getTotal());
return TableDataInfo.build(result);
}
}
@@ -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
</sql>
<select id="selectStudentOptions" parameterType="String" resultMap="StudentOptionResult">
<select id="selectStudentOptions" resultMap="StudentOptionResult">
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}, '%'))
</if>
order by student_no
limit 50
<choose>
<when test="pageNum != null and pageSize != null">
limit ${(pageNum - 1) * pageSize}, #{pageSize, jdbcType=INTEGER}
</when>
<otherwise>
limit 50
</otherwise>
</choose>
</select>
<select id="selectClassTeacherVoPage" resultType="XskhDisciplineRecordVo">
+100
View File
@@ -1,4 +1,104 @@
-- ----------------------------
-- 0、warm-flow-all.sql,地址:https://gitee.com/dromara/warm-flow/blob/master/sql/mysql/warm-flow-all.sql
-- ----------------------------
CREATE TABLE `flow_definition`
(
`id` bigint NOT NULL COMMENT '主键id',
`flow_code` varchar(40) NOT NULL COMMENT '流程编码',
`flow_name` varchar(100) NOT NULL COMMENT '流程名称',
`category` varchar(100) DEFAULT NULL COMMENT '流程类别',
`version` varchar(20) NOT NULL COMMENT '流程版本',
`is_publish` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否发布(0未发布 1已发布 9失效)',
`form_custom` char(1) DEFAULT 'N' COMMENT '审批表单是否自定义(Y是 N否)',
`form_path` varchar(100) DEFAULT NULL COMMENT '审批表单路径',
`activity_status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '流程激活状态(0挂起 1激活)',
`listener_type` varchar(100) DEFAULT NULL COMMENT '监听器类型',
`listener_path` varchar(400) DEFAULT NULL COMMENT '监听器路径',
`ext` varchar(500) DEFAULT NULL COMMENT '业务详情 存业务表对象json字符串',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志',
`tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB COMMENT ='流程定义表';
CREATE TABLE `flow_node`
(
`id` bigint NOT NULL COMMENT '主键id',
`node_type` tinyint(1) NOT NULL COMMENT '节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关)',
`definition_id` bigint NOT NULL COMMENT '流程定义id',
`node_code` varchar(100) NOT NULL COMMENT '流程节点编码',
`node_name` varchar(100) DEFAULT NULL COMMENT '流程节点名称',
`permission_flag` varchar(200) DEFAULT NULL COMMENT '权限标识(权限类型:权限标识,可以多个,用逗号隔开)',
`node_ratio` decimal(6, 3) DEFAULT NULL COMMENT '流程签署比例值',
`coordinate` varchar(100) DEFAULT NULL COMMENT '坐标',
`any_node_skip` varchar(100) DEFAULT NULL COMMENT '任意结点跳转',
`listener_type` varchar(100) DEFAULT NULL COMMENT '监听器类型',
`listener_path` varchar(400) DEFAULT NULL COMMENT '监听器路径',
`handler_type` varchar(100) DEFAULT NULL COMMENT '处理器类型',
`handler_path` varchar(400) DEFAULT NULL COMMENT '处理器路径',
`form_custom` char(1) DEFAULT 'N' COMMENT '审批表单是否自定义(Y是 N否)',
`form_path` varchar(100) DEFAULT NULL COMMENT '审批表单路径',
`version` varchar(20) NOT NULL COMMENT '版本',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`ext` text COMMENT '扩展属性',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志',
`tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB COMMENT ='流程节点表';
CREATE TABLE `flow_skip`
(
`id` bigint NOT NULL COMMENT '主键id',
`definition_id` bigint NOT NULL COMMENT '流程定义id',
`now_node_code` varchar(100) NOT NULL COMMENT '当前流程节点的编码',
`now_node_type` tinyint(1) DEFAULT NULL COMMENT '当前节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关)',
`next_node_code` varchar(100) NOT NULL COMMENT '下一个流程节点的编码',
`next_node_type` tinyint(1) DEFAULT NULL COMMENT '下一个节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关)',
`skip_name` varchar(100) DEFAULT NULL COMMENT '跳转名称',
`skip_type` varchar(40) DEFAULT NULL COMMENT '跳转类型(PASS审批通过 REJECT退回)',
`skip_condition` varchar(200) DEFAULT NULL COMMENT '跳转条件',
`coordinate` varchar(100) DEFAULT NULL COMMENT '坐标',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志',
`tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB COMMENT ='节点跳转关联表';
CREATE TABLE `flow_instance`
(
`id` bigint NOT NULL COMMENT '主键id',
`definition_id` bigint NOT NULL COMMENT '对应flow_definition表的id',
`business_id` varchar(40) NOT NULL COMMENT '业务id',
`node_type` tinyint(1) NOT NULL COMMENT '节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关)',
`node_code` varchar(40) NOT NULL COMMENT '流程节点编码',
`node_name` varchar(100) DEFAULT NULL COMMENT '流程节点名称',
`variable` text COMMENT '任务变量',
`flow_status` varchar(20) NOT NULL COMMENT '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)',
`activity_status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '流程激活状态(0挂起 1激活)',
`def_json` text COMMENT '流程定义json',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`ext` varchar(500) DEFAULT NULL COMMENT '扩展字段,预留给业务系统使用',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志',
`tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB COMMENT ='流程实例表';
CREATE TABLE `flow_task`
(
`id` bigint NOT NULL COMMENT '主键id',
`definition_id` bigint NOT NULL COMMENT '对应flow_definition表的id',
`instance_id` bigint NOT NULL COMMENT '对应flow_instance表的id',
`node_code` varchar(100) NOT NULL COMMENT '节点编码',
`node_name` varchar(100) DEFAULT NULL COMMENT '节点名称',
`node_type` tinyint(1) NOT NULL COMMENT '节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关)',
`flow_status` varchar(20) NOT NULL COMMENT '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)',
`form_custom` char(1) DEFAULT 'N' COMMENT '审批表单是否自定义(Y是 N否)',
`form_path` varchar(100) DEFAULT NULL COMMENT '审批表单路径',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志',