提交代码
This commit is contained in:
1 parent
652285005a
commit
bf25ceba66
4 files changed
+223
-42
No files matched your search
+52
-11
@@ -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<Long> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
/**
|
||||
* 查询假期留宿管理列表
|
||||
|
||||
@@ -723,7 +723,7 @@ const data = reactive<PageData<HolidayStayForm, HolidayStayQuery>>({
|
||||
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;
|
||||
}
|
||||
|
||||
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'; // 失效 - 红色
|
||||
}
|
||||
};
|
||||
|
||||
// 文件类型判断
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, reactive, computed, watch, onMounted } from 'vue';
|
||||
import { searchTeacherByName } from '@/api/system/teacher';
|
||||
import { getTeacherList } from '@/api/xg/xgss/xsssgly/dormManager';
|
||||
import { addDormManager, updateDormManager } from '@/api/xg/xgss/ssglyxx/dormManager/index';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
@@ -121,17 +121,33 @@ export default defineComponent({
|
||||
const queryTeachers = async (query: string) => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await searchTeacherByName(query, 20);
|
||||
const res = await getTeacherList(
|
||||
query,
|
||||
(() => {
|
||||
switch (props.type) {
|
||||
case 'school':
|
||||
return '1';
|
||||
case 'campus':
|
||||
return '2';
|
||||
case 'area':
|
||||
return '3';
|
||||
case 'building':
|
||||
return '4';
|
||||
default:
|
||||
return '1';
|
||||
}
|
||||
})()
|
||||
);
|
||||
if (res.code === 200 && res.data) {
|
||||
teacherOptions.value = res.data.map((item: any) => {
|
||||
return {
|
||||
value: item.userId,
|
||||
label: item.nickName,
|
||||
username: item.userName,
|
||||
nickName: item.nickName,
|
||||
userId: item.userId,
|
||||
phonenumber: item.phonenumber,
|
||||
sex: item.sex
|
||||
value: item.value,
|
||||
label: item.label,
|
||||
username: item.username,
|
||||
nickName: item.label,
|
||||
userId: item.value, // 直接使用API返回的value作为userId
|
||||
phonenumber: item.phonenumber, // 保存手机号码
|
||||
sex: item.sex // 保存性别
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -181,15 +197,31 @@ export default defineComponent({
|
||||
const handleFocus = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await searchTeacherByName('', 100);
|
||||
const res = await getTeacherList(
|
||||
'',
|
||||
(() => {
|
||||
switch (props.type) {
|
||||
case 'school':
|
||||
return '1';
|
||||
case 'campus':
|
||||
return '2';
|
||||
case 'area':
|
||||
return '3';
|
||||
case 'building':
|
||||
return '4';
|
||||
default:
|
||||
return '1';
|
||||
}
|
||||
})()
|
||||
);
|
||||
if (res.code === 200 && res.data) {
|
||||
teacherOptions.value = res.data.map((item: any) => {
|
||||
return {
|
||||
value: item.userId,
|
||||
label: item.nickName,
|
||||
username: item.userName,
|
||||
userId: item.userId,
|
||||
nickName: item.nickName,
|
||||
value: item.value,
|
||||
label: item.label,
|
||||
username: item.username,
|
||||
userId: item.value,
|
||||
nickName: item.label,
|
||||
phonenumber: item.phonenumber, // 保存手机号码
|
||||
sex: item.sex // 保存性别
|
||||
};
|
||||
@@ -205,15 +237,31 @@ export default defineComponent({
|
||||
// 页面加载时预加载一些教师数据
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const res = await searchTeacherByName('', 100);
|
||||
const res = await getTeacherList(
|
||||
'',
|
||||
(() => {
|
||||
switch (props.type) {
|
||||
case 'school':
|
||||
return '1';
|
||||
case 'campus':
|
||||
return '2';
|
||||
case 'area':
|
||||
return '3';
|
||||
case 'building':
|
||||
return '4';
|
||||
default:
|
||||
return '1';
|
||||
}
|
||||
})()
|
||||
);
|
||||
if (res.code === 200 && res.data) {
|
||||
teacherOptions.value = res.data.map((item: any) => {
|
||||
return {
|
||||
value: item.userId,
|
||||
label: item.nickName,
|
||||
username: item.userName,
|
||||
userId: item.userId,
|
||||
nickName: item.nickName,
|
||||
value: item.value,
|
||||
label: item.label,
|
||||
username: item.username,
|
||||
userId: item.value,
|
||||
nickName: item.label,
|
||||
phonenumber: item.phonenumber, // 保存手机号码
|
||||
sex: item.sex // 保存性别
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user