From bf25ceba6622122977ce2a08cb2bc54102f71772 Mon Sep 17 00:00:00 2001 From: zlwu <704541015@qq.com> Date: Mon, 8 Sep 2025 00:26:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/XgHolidayStayServiceImpl.java | 63 ++++++++-- .../xgss/holidayStay/holidayStay/index-sg.ts | 2 +- .../xgss/holidayStay/holidayStay/index-sg.vue | 118 ++++++++++++++++-- .../xgss/xsssgly/components/AdminDialog.vue | 90 +++++++++---- 4 files changed, 227 insertions(+), 46 deletions(-) diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgHolidayStayServiceImpl.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgHolidayStayServiceImpl.java index 0da95e78..c53f9fef 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgHolidayStayServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgHolidayStayServiceImpl.java @@ -21,6 +21,7 @@ import org.dromara.xg.service.IXgHolidayStayService; import java.util.List; import java.util.Map; import java.util.Collection; +import java.util.ArrayList; /** * 假期留宿管理Service业务层处理 @@ -90,15 +91,42 @@ public class XgHolidayStayServiceImpl implements IXgHolidayStayService { lqw.like(StringUtils.isNotBlank(bo.getCampusName()), XgHolidayStay::getCampusName, bo.getCampusName()); lqw.eq(bo.getAreaId() != null, XgHolidayStay::getAreaId, bo.getAreaId()); lqw.like(StringUtils.isNotBlank(bo.getAreaName()), XgHolidayStay::getAreaName, bo.getAreaName()); - lqw.eq(bo.getBuildingId() != null, XgHolidayStay::getBuildingId, bo.getBuildingId()); + + // 楼栋ID过滤逻辑:支持单个楼栋ID和多个楼栋ID的查询 + if (bo.getBuildingId() != null) { + // 单个楼栋ID查询 + lqw.eq(XgHolidayStay::getBuildingId, bo.getBuildingId()); + } else if (params != null && params.containsKey("buildingIds")) { + // 多个楼栋ID查询,从params中获取buildingIds(逗号分隔的字符串) + String buildingIdsStr = (String) params.get("buildingIds"); + if (StringUtils.isNotBlank(buildingIdsStr)) { + String[] buildingIdArray = buildingIdsStr.split(","); + if (buildingIdArray.length > 0) { + List buildingIds = new ArrayList<>(); + for (String buildingIdStr : buildingIdArray) { + try { + Long buildingId = Long.parseLong(buildingIdStr.trim()); + buildingIds.add(buildingId); + } catch (NumberFormatException e) { + log.warn("无效的楼栋ID: {}", buildingIdStr); + } + } + if (!buildingIds.isEmpty()) { + lqw.in(XgHolidayStay::getBuildingId, buildingIds); + log.debug("添加多楼栋ID过滤条件: {}", buildingIds); + } + } + } + } + lqw.like(StringUtils.isNotBlank(bo.getBuildingName()), XgHolidayStay::getBuildingName, bo.getBuildingName()); lqw.eq(bo.getRoomId() != null, XgHolidayStay::getRoomId, bo.getRoomId()); lqw.like(StringUtils.isNotBlank(bo.getRoomName()), XgHolidayStay::getRoomName, bo.getRoomName()); lqw.eq(bo.getBedId() != null, XgHolidayStay::getBedId, bo.getBedId()); lqw.like(StringUtils.isNotBlank(bo.getBedName()), XgHolidayStay::getBedName, bo.getBedName()); lqw.eq(StringUtils.isNotBlank(bo.getHolidayType()), XgHolidayStay::getHolidayType, bo.getHolidayType()); - lqw.ge(bo.getApplyStartDate() != null, XgHolidayStay::getApplyStartDate, bo.getApplyStartDate()); - lqw.le(bo.getApplyEndDate() != null, XgHolidayStay::getApplyEndDate, bo.getApplyEndDate()); + lqw.eq(bo.getApplyStartDate() != null, XgHolidayStay::getApplyStartDate, bo.getApplyStartDate()); + lqw.eq(bo.getApplyEndDate() != null, XgHolidayStay::getApplyEndDate, bo.getApplyEndDate()); lqw.like(StringUtils.isNotBlank(bo.getStayReason()), XgHolidayStay::getStayReason, bo.getStayReason()); lqw.eq(StringUtils.isNotBlank(bo.getStayReasonType()), XgHolidayStay::getStayReasonType, bo.getStayReasonType()); @@ -110,9 +138,9 @@ public class XgHolidayStayServiceImpl implements IXgHolidayStayService { lqw.eq(StringUtils.isNotBlank(bo.getParentConsent()), XgHolidayStay::getParentConsent, bo.getParentConsent()); lqw.like(StringUtils.isNotBlank(bo.getAttachmentOssIds()), XgHolidayStay::getAttachmentOssIds, bo.getAttachmentOssIds()); - lqw.eq(StringUtils.isNotBlank(bo.getExtField1()), XgHolidayStay::getExtField1, bo.getExtField1()); - lqw.eq(StringUtils.isNotBlank(bo.getExtField2()), XgHolidayStay::getExtField2, bo.getExtField2()); - lqw.eq(StringUtils.isNotBlank(bo.getExtField3()), XgHolidayStay::getExtField3, bo.getExtField3()); + lqw.like(StringUtils.isNotBlank(bo.getExtField1()), XgHolidayStay::getExtField1, bo.getExtField1()); + lqw.like(StringUtils.isNotBlank(bo.getExtField2()), XgHolidayStay::getExtField2, bo.getExtField2()); + lqw.like(StringUtils.isNotBlank(bo.getExtField3()), XgHolidayStay::getExtField3, bo.getExtField3()); // 添加创建人过滤条件 - 实现班主任权限控制,只能查看自己创建的数据 lqw.eq(bo.getCreateBy() != null, XgHolidayStay::getCreateBy, bo.getCreateBy()); @@ -137,17 +165,30 @@ public class XgHolidayStayServiceImpl implements IXgHolidayStayService { if (StringUtils.isNotBlank(statusType) && StringUtils.isNotBlank(currentTime)) { if ("valid".equals(statusType)) { - // 有效状态:结束时间 >= 当前时间 AND 结束时间不为空 - lqw.ge(XgHolidayStay::getApplyEndDate, currentTime) + // 有效状态:当前时间在留宿开始时间和结束时间之间(包含边界) + // 条件:applyStartDate <= currentTime AND applyEndDate >= currentTime + // AND applyStartDate IS NOT NULL AND applyEndDate IS NOT NULL + lqw.le(XgHolidayStay::getApplyStartDate, currentTime) + .ge(XgHolidayStay::getApplyEndDate, currentTime) + .isNotNull(XgHolidayStay::getApplyStartDate) .isNotNull(XgHolidayStay::getApplyEndDate); - log.debug("添加有效状态过滤条件: apply_end_date >= {} AND apply_end_date IS NOT NULL", currentTime); + log.debug( + "添加有效状态过滤条件: apply_start_date <= {} AND apply_end_date >= {} AND start/end dates are not null", + currentTime, currentTime); } else if ("invalid".equals(statusType)) { - // 失效状态:结束时间 < 当前时间 OR 结束时间为空 + // 失效状态:当前时间不在留宿时间范围内 + // 条件:applyStartDate > currentTime OR applyEndDate < currentTime + // OR applyStartDate IS NULL OR applyEndDate IS NULL lqw.and(wrapper -> wrapper + .gt(XgHolidayStay::getApplyStartDate, currentTime) + .or() .lt(XgHolidayStay::getApplyEndDate, currentTime) .or() + .isNull(XgHolidayStay::getApplyStartDate) + .or() .isNull(XgHolidayStay::getApplyEndDate)); - log.debug("添加失效状态过滤条件: apply_end_date < {} OR apply_end_date IS NULL", currentTime); + log.debug("添加失效状态过滤条件: apply_start_date > {} OR apply_end_date < {} OR start/end dates are null", + currentTime, currentTime); } } } diff --git a/web/src/api/xg/xgss/holidayStay/holidayStay/index-sg.ts b/web/src/api/xg/xgss/holidayStay/holidayStay/index-sg.ts index 20b855b7..b34a65a5 100644 --- a/web/src/api/xg/xgss/holidayStay/holidayStay/index-sg.ts +++ b/web/src/api/xg/xgss/holidayStay/holidayStay/index-sg.ts @@ -1,6 +1,6 @@ import request from '@/utils/request'; import { AxiosPromise } from 'axios'; -import { HolidayStayVO, HolidayStayForm, HolidayStayQuery, StudentOptionVO, StudentOptionQuery } from '@/api/xg/xgss/holidayStay/holidayStay/types'; +import { HolidayStayVO, HolidayStayForm, HolidayStayQuery, StudentOptionVO, StudentOptionQuery } from '@/api/xg/xgss/holidayStay/holidayStay/types-sg'; /** * 查询假期留宿管理列表 diff --git a/web/src/views/xg/xgss/holidayStay/holidayStay/index-sg.vue b/web/src/views/xg/xgss/holidayStay/holidayStay/index-sg.vue index 4fdd1c00..0ae1b8bc 100644 --- a/web/src/views/xg/xgss/holidayStay/holidayStay/index-sg.vue +++ b/web/src/views/xg/xgss/holidayStay/holidayStay/index-sg.vue @@ -723,7 +723,7 @@ const data = reactive>({ extField1: undefined, extField2: undefined, extField3: undefined, - status: undefined, + status: 'valid', // 默认展示有效状态的数据 params: {} }, rules: { @@ -756,6 +756,56 @@ const uploadData = computed(() => { }; }); +// 宿管员权限相关状态 +const dormManagerBuildingIds = ref<(string | number)[]>([]); +const hasDormManagerPermission = ref(false); + +/** 获取宿管员权限范围内的楼栋ID列表 */ +const getDormManagerBuildingIds = async () => { + try { + // 调用宿舍楼树接口,该接口会根据当前用户权限自动过滤 + const response = await request({ + url: '/xgss/dormBuildingTree/list', + method: 'get' + }); + + if (response.code === 200 && response.data) { + const buildingIds: (string | number)[] = []; + + // 提取所有楼栋ID(递归遍历树形结构) + const extractBuildingIds = (nodes: any[]) => { + nodes.forEach((node: any) => { + // 如果是楼栋节点(type为building或者有buildingId) + if (node.type === 'building' || (node.id && !node.children)) { + buildingIds.push(node.id); + } + // 递归处理子节点 + if (node.children && node.children.length > 0) { + extractBuildingIds(node.children); + } + }); + }; + + extractBuildingIds(response.data); + dormManagerBuildingIds.value = buildingIds; + hasDormManagerPermission.value = buildingIds.length > 0; + + console.log('宿管员权限楼栋ID列表:', buildingIds); + return buildingIds; + } else { + console.warn('获取宿管员权限楼栋失败:', response.msg); + dormManagerBuildingIds.value = []; + hasDormManagerPermission.value = false; + return []; + } + } catch (error) { + console.error('获取宿管员权限楼栋失败:', error); + dormManagerBuildingIds.value = []; + hasDormManagerPermission.value = false; + return []; + } +}; + /** 查询假期留宿管理列表 */ const getList = async () => { loading.value = true; @@ -765,25 +815,48 @@ const getList = async () => { await userStore.getInfo(); } + // 获取宿管员权限楼栋列表 + const buildingIds = await getDormManagerBuildingIds(); + + // 如果没有宿管员权限,直接返回空列表 + if (!hasDormManagerPermission.value || buildingIds.length === 0) { + holidayStayList.value = []; + total.value = 0; + loading.value = false; + console.log('当前用户没有宿管员权限或没有分配管理楼栋'); + return; + } + // 处理状态过滤逻辑 const requestParams = { ...queryParams.value }; - // 添加创建人过滤条件 - 班主任只能看到自己创建的数据 - requestParams.createBy = userStore.userId; + // 宿管员权限过滤:添加楼栋ID过滤条件 + if (buildingIds.length === 1) { + // 单个楼栋直接设置buildingId + requestParams.buildingId = buildingIds[0]; + } else { + // 多个楼栋使用in查询,通过params传递 + requestParams.params = { + ...requestParams.params, + buildingIds: buildingIds.join(',') + }; + } // 根据状态设置时间过滤条件 if (requestParams.status) { const currentTime = new Date().toISOString().slice(0, 19).replace('T', ' '); if (requestParams.status === 'valid') { - // 查询有效状态:结束时间大于等于当前时间 + // 查询有效状态:当前时间在留宿开始时间和结束时间之间 + // 条件:currentTime >= applyStartDate AND currentTime <= applyEndDate requestParams.params = { ...requestParams.params, statusType: 'valid', currentTime: currentTime }; } else if (requestParams.status === 'invalid') { - // 查询失效状态:结束时间小于当前时间 + // 查询失效状态:当前时间不在留宿时间范围内 + // 条件:currentTime < applyStartDate OR currentTime > applyEndDate requestParams.params = { ...requestParams.params, statusType: 'invalid', @@ -795,10 +868,17 @@ const getList = async () => { delete requestParams.status; } - const res = await listHolidayStay(requestParams); - holidayStayList.value = res.rows; - total.value = res.total; - loading.value = false; + try { + const res = await listHolidayStay(requestParams); + holidayStayList.value = res.rows; + total.value = res.total; + } catch (error) { + console.error('查询假期留宿列表失败:', error); + holidayStayList.value = []; + total.value = 0; + } finally { + loading.value = false; + } }; /** 取消按钮 */ @@ -1315,26 +1395,38 @@ const loadCascadeOptionsForUpdate = async (formData: HolidayStayForm) => { /** 获取状态文本 */ const getStatusText = (row: HolidayStayVO) => { - if (!row.applyEndDate) { + if (!row.applyStartDate || !row.applyEndDate) { return '未知'; } const currentTime = new Date(); + const startTime = new Date(row.applyStartDate); const endTime = new Date(row.applyEndDate); - return currentTime > endTime ? '失效' : '有效'; + // 有效条件:当前时间在留宿开始时间和结束时间之间(包含边界) + if (currentTime >= startTime && currentTime <= endTime) { + return '有效'; + } else { + return '失效'; + } }; /** 获取状态标签类型 */ const getStatusType = (row: HolidayStayVO) => { - if (!row.applyEndDate) { + if (!row.applyStartDate || !row.applyEndDate) { return 'info'; } const currentTime = new Date(); + const startTime = new Date(row.applyStartDate); const endTime = new Date(row.applyEndDate); - return currentTime > endTime ? 'danger' : 'success'; + // 有效条件:当前时间在留宿开始时间和结束时间之间(包含边界) + if (currentTime >= startTime && currentTime <= endTime) { + return 'success'; // 有效 - 绿色 + } else { + return 'danger'; // 失效 - 红色 + } }; // 文件类型判断 diff --git a/web/src/views/xg/xgss/xsssgly/components/AdminDialog.vue b/web/src/views/xg/xgss/xsssgly/components/AdminDialog.vue index 4e505516..67de5a08 100644 --- a/web/src/views/xg/xgss/xsssgly/components/AdminDialog.vue +++ b/web/src/views/xg/xgss/xsssgly/components/AdminDialog.vue @@ -47,7 +47,7 @@