From bd5d4e57fcb76771fe10d288d2cbf865d9ba5b6b Mon Sep 17 00:00:00 2001 From: zlwu <704541015@qq.com> Date: Thu, 14 Aug 2025 20:11:57 +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 --- .../XgDormBedStudentController.java | 13 ++++ .../xg/service/IXgDormBedStudentService.java | 9 +++ .../impl/XgDormBedStudentServiceImpl.java | 67 +++++++++++++++++++ .../dormBedStudent/dormBedStudent/index.ts | 14 ++++ web/src/views/xg/xgss/bzrfp/bzrfp.vue | 40 ++++++++++- web/src/views/xg/xgss/ejxyfp/ejxyfp.vue | 38 ++++++++++- web/src/views/xg/xgss/xsssfpejxy/index.vue | 38 ++++++++++- 7 files changed, 214 insertions(+), 5 deletions(-) diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgDormBedStudentController.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgDormBedStudentController.java index 51dc01cd..d36ae8e8 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgDormBedStudentController.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgDormBedStudentController.java @@ -257,4 +257,17 @@ public class XgDormBedStudentController extends BaseController { @RequestParam(required = false) Long classId) { return toAjax(xgDormBedStudentService.classTeacherRecallSelectedBeds(bedIds, classId)); } + + /** + * 班主任批量退宿 + */ + @SaCheckPermission("dormBedStudent:dormBedStudent:edit") + @Log(title = "班主任批量退宿", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PostMapping("/classTeacherStayawaySelectedBeds") + public R classTeacherStayawaySelectedBeds(@RequestBody List bedIds, + @RequestParam(required = false) Long classId) { + return toAjax(xgDormBedStudentService.classTeacherStayawaySelectedBeds(bedIds, classId)); + } + } diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgDormBedStudentService.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgDormBedStudentService.java index b3383aee..679fdf14 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgDormBedStudentService.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgDormBedStudentService.java @@ -183,4 +183,13 @@ public interface IXgDormBedStudentService { * @return 是否收回成功 */ Boolean classTeacherRecallSelectedBeds(List bedIds, Long classId); + + /** + * 班主任批量退宿 + * + * @param bedIds 床位ID列表 + * @param classId 班级ID + * @return 是否退宿成功 + */ + Boolean classTeacherStayawaySelectedBeds(List bedIds, Long classId); } diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormBedStudentServiceImpl.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormBedStudentServiceImpl.java index 41583f81..d43faa6e 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormBedStudentServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormBedStudentServiceImpl.java @@ -1806,4 +1806,71 @@ public class XgDormBedStudentServiceImpl implements IXgDormBedStudentService { throw new RuntimeException("收回选中床位失败:" + e.getMessage()); } } + + /** + * 班主任退宿床位 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean classTeacherStayawaySelectedBeds(List bedIds, Long classId) { + if (bedIds == null || bedIds.isEmpty()) { + throw new IllegalArgumentException("床位ID列表不能为空"); + } + + try { + Long targetClassId = classId != null ? classId : getCurrentUserClassId(); + Date now = new Date(); + Long loginUserId = LoginHelper.getUserId(); + + log.info("班主任退宿选中床位,床位IDs: {},classId:{}", bedIds, targetClassId); + + // 1. 更新 xg_student_msg 表:根据 ext_field1 = 床位id,deleted = 0,student_status = 1 + // 的数据 + // 将 dormitory_building、dormitory_room、ext_field1 置空 + if (!bedIds.isEmpty()) { + LambdaUpdateWrapper updateStudentWrapper = Wrappers.lambdaUpdate(); + updateStudentWrapper + .in(XgStudentMsg::getExtField1, + bedIds.stream().map(String::valueOf).collect(java.util.stream.Collectors.toList())) + .eq(XgStudentMsg::getDeleted, 0L) + .eq(XgStudentMsg::getStudentStatus, "1") + .set(XgStudentMsg::getDormitoryBuilding, null) + .set(XgStudentMsg::getDormitoryRoom, null) + .set(XgStudentMsg::getExtField1, null) + .set(XgStudentMsg::getUpdateTime, now) + .set(XgStudentMsg::getUpdateBy, loginUserId); + + int studentUpdateCount = xgStudentMsgMapper.update(null, updateStudentWrapper); + log.info("更新学生信息表记录数: {}", studentUpdateCount); + } + + // 2. 更新 xg_dorm_bed_student 表:根据 bed_id = 床位id,deleted = 0,status = 0 + // 将 status = 1 , checkout_time = 当前时间 + LambdaUpdateWrapper updateBedStudentWrapper = Wrappers.lambdaUpdate(); + updateBedStudentWrapper.in(XgDormBedStudent::getBedId, bedIds) + .eq(XgDormBedStudent::getDeleted, "0") + .eq(XgDormBedStudent::getStatus, "0") + .set(XgDormBedStudent::getStatus, "1") + // .set(XgDormBedStudent::getAssignTime, null) + .set(XgDormBedStudent::getCheckoutTime, now) + .set(XgDormBedStudent::getUpdateTime, now) + .set(XgDormBedStudent::getUpdateBy, loginUserId); + + int bedStudentUpdateCount = baseMapper.update(null, updateBedStudentWrapper); + log.info("更新床位学生分配表记录数: {}", bedStudentUpdateCount); + + // 根据id跟床位id更新床位状态为空闲 + LambdaUpdateWrapper updateBedWrapper = Wrappers.lambdaUpdate(); + updateBedWrapper.in(XgDormBed::getId, bedIds) + .eq(XgDormBed::getDeleted, "0") + .set(XgDormBed::getBedStatus, "0"); + xgDormBedMapper.update(null, updateBedWrapper); + + return true; + } catch (Exception e) { + log.error("班主任退宿选中床位失败", e); + throw new RuntimeException("退宿选中床位失败:" + e.getMessage()); + } + } + } diff --git a/web/src/api/xg/xgss/dormBedStudent/dormBedStudent/index.ts b/web/src/api/xg/xgss/dormBedStudent/dormBedStudent/index.ts index 1e96e2d1..0604f9ea 100644 --- a/web/src/api/xg/xgss/dormBedStudent/dormBedStudent/index.ts +++ b/web/src/api/xg/xgss/dormBedStudent/dormBedStudent/index.ts @@ -201,3 +201,17 @@ export const classTeacherRecallSelectedBeds = (bedIds: number[], classId?: strin params: { classId } }); }; + +/** + * 班主任退宿选中床位 + * @param bedIds 床位ID数组 + * @param classId 班级ID,可为空 + */ +export const classTeacherStayawaySelectedBeds = (bedIds: number[], classId?: string | number) => { + return request({ + url: '/dormBedStudent/dormBedStudent/classTeacherStayawaySelectedBeds', + method: 'post', + data: bedIds, + params: { classId } + }); +}; diff --git a/web/src/views/xg/xgss/bzrfp/bzrfp.vue b/web/src/views/xg/xgss/bzrfp/bzrfp.vue index 37e1e522..4e8d0acf 100644 --- a/web/src/views/xg/xgss/bzrfp/bzrfp.vue +++ b/web/src/views/xg/xgss/bzrfp/bzrfp.vue @@ -99,6 +99,7 @@ 收回选中床位 + 退宿选中床位 { } }; +/** 退宿床位 */ +const handleStayawayBeds = async () => { + if (!selectedBuilding.value) { + ElMessage.warning('请先选择宿舍楼'); + return; + } + + // 获取选中的床位ID数组 + const selectedBedIds = selectedRows.value + .filter((row) => row.isBed && row.studentId) // 只退宿已分配的床位 + .map((bed) => bed.id); + + if (selectedBedIds.length === 0) { + ElMessage.warning('请先勾选要退宿的床位!'); + return; + } + + try { + const confirmMessage = `确认退宿选中的 ${selectedBedIds.length} 个床位吗?\n\n退宿后,这些床位上学生的床位信息将被清空,同时该床位归还学校。`; + + await ElMessageBox.confirm(confirmMessage, '确认退宿选中床位', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }); + + await classTeacherStayawaySelectedBeds(selectedBedIds, activeClassId.value); + ElMessage.success('退宿选中床位成功'); + handleAllocationSuccess(); + } catch (error: any) { + if (error !== 'cancel') { + ElMessage.error('退宿床位失败'); + } + } +}; + /** 分配成功回调 */ const handleAllocationSuccess = () => { // 清除缓存,确保数据刷新 diff --git a/web/src/views/xg/xgss/ejxyfp/ejxyfp.vue b/web/src/views/xg/xgss/ejxyfp/ejxyfp.vue index d731ab02..961b79ef 100644 --- a/web/src/views/xg/xgss/ejxyfp/ejxyfp.vue +++ b/web/src/views/xg/xgss/ejxyfp/ejxyfp.vue @@ -134,6 +134,7 @@ 分配给班级 批量收回宿舍 + 批量退宿床位 import { ref, computed, reactive, onMounted, nextTick, watch, getCurrentInstance } from 'vue'; -import { InfoFilled, House, Avatar } from '@element-plus/icons-vue'; +import { InfoFilled, House, Avatar, UserFilled } from '@element-plus/icons-vue'; import type { DormBuildingTreeVO } from '@/api/xg/xgss/dormBedStudent/dormBedStudent/types'; import type { DormTreeNode, BedInfo } from '@/api/xg/xgss/xsssfjgl/types'; import type { DormRoomVO } from '@/api/xg/xgss/dormRoom/types'; @@ -375,7 +376,7 @@ import ElMessageBox from 'element-plus/es/components/message-box/index'; import RoomDialog from './components/RoomDialog.vue'; import BedDialog from './components/BedDialog.vue'; import ClassAllocationDialog from './components/ClassAllocationDialog.vue'; -import { batchRecallDormBeds, batchRecallClassAllocation } from '@/api/xg/xgss/dormBedStudent/dormBedStudent'; +import { batchRecallDormBeds, batchRecallClassAllocation, classTeacherStayawaySelectedBeds } from '@/api/xg/xgss/dormBedStudent/dormBedStudent'; // const { proxy } = getCurrentInstance(); @@ -712,6 +713,39 @@ const handleBatchRecall = async () => { } }; +/** 批量退宿床位 */ +const handleBatchStayaway = async () => { + if (!selectedBuilding.value) { + ElMessage.warning('请先选择宿舍楼'); + return; + } + const selectedBeds = selectedRows.value.filter((row) => row.isBed).map((row) => row.id); + if (selectedBeds.length === 0) { + ElMessage.warning('请先选择要退宿的床位'); + return; + } + try { + const content = `确认退宿选中的 ${selectedBeds.length} 个床位吗?\n\n重要提示:退宿后,这些床位上学生的床位信息将被清空,同时该床位归还学校。`; + await ElMessageBox.confirm(content, '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }); + } catch { + return; + } + try { + await classTeacherStayawaySelectedBeds(selectedBeds); + ElMessage.success('批量退宿成功'); + // 刷新数据 + selectableRowsCache.value = []; + loadRoomData(); + } catch (e) { + ElMessage.error('批量退宿失败'); + console.error(e); + } +}; + /** 全部展开 */ const expandAll = async () => { if (expandAllLoading.value || selectionLoading.value || !roomList.value?.length) return; diff --git a/web/src/views/xg/xgss/xsssfpejxy/index.vue b/web/src/views/xg/xgss/xsssfpejxy/index.vue index 9f50a0b4..202cfaa9 100644 --- a/web/src/views/xg/xgss/xsssfpejxy/index.vue +++ b/web/src/views/xg/xgss/xsssfpejxy/index.vue @@ -134,6 +134,7 @@ 分配给二级学院 批量收回宿舍 + 批量退宿床位 import { ref, computed, reactive, onMounted, nextTick, watch, getCurrentInstance } from 'vue'; -import { InfoFilled, House, Avatar } from '@element-plus/icons-vue'; +import { InfoFilled, House, Avatar, UserFilled } from '@element-plus/icons-vue'; import type { DormTreeNode, BedInfo } from '@/api/xg/xgss/xsssfjgl/types'; import type { DormRoomVO } from '@/api/xg/xgss/dormRoom/types'; import type { DormBedDetailVO } from '@/api/xg/xgss/dormBed/types'; @@ -372,7 +373,7 @@ import ElMessageBox from 'element-plus/es/components/message-box/index'; import RoomDialog from './components/RoomDialog.vue'; import BedDialog from './components/BedDialog.vue'; import CollegeAllocationDialog from './components/CollegeAllocationDialog.vue'; -import { batchRecallDormBeds } from '@/api/xg/xgss/dormBedStudent/dormBedStudent'; +import { batchRecallDormBeds, classTeacherStayawaySelectedBeds } from '@/api/xg/xgss/dormBedStudent/dormBedStudent'; // const { proxy } = getCurrentInstance(); @@ -713,6 +714,39 @@ const handleBatchRecall = async () => { } }; +/** 批量退宿床位 */ +const handleBatchStayaway = async () => { + if (!selectedBuilding.value) { + ElMessage.warning('请先选择宿舍楼'); + return; + } + const selectedBeds = selectedRows.value.filter((row) => row.isBed).map((row) => row.id); + if (selectedBeds.length === 0) { + ElMessage.warning('请先选择要退宿的床位'); + return; + } + try { + const content = `确认退宿选中的 ${selectedBeds.length} 个床位吗?\n\n重要提示:退宿后,这些床位上学生的床位信息将被清空,同时该床位归还学校。`; + await ElMessageBox.confirm(content, '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }); + } catch { + return; + } + try { + await classTeacherStayawaySelectedBeds(selectedBeds); + ElMessage.success('批量退宿成功'); + // 刷新数据 + selectableRowsCache.value = []; + loadRoomData(); + } catch (e) { + ElMessage.error('批量退宿失败'); + console.error(e); + } +}; + /** 全部展开 */ const expandAll = async () => { if (expandAllLoading.value || selectionLoading.value || !roomList.value?.length) return;