zlwu 1 год назад
Родитель
Сommit
7a4881592a

+ 6 - 6
backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgDormBedStudentController.java

@@ -272,16 +272,16 @@ public class XgDormBedStudentController extends BaseController {
 
     /**
      * 班主任床位互换
-     * 将两个有学生的床位进行互换
+     * 将两个学生的床位进行互换
      */
     @SaCheckPermission("dormBedStudent:dormBedStudent:edit")
     @Log(title = "班主任床位互换", businessType = BusinessType.UPDATE)
     @RepeatSubmit()
     @PostMapping("/classTeacherExchangeBeds")
-    public R<Void> classTeacherExchangeBeds(@RequestParam Long sourceBedId,
-            @RequestParam Long targetBedId,
+    public R<Void> classTeacherExchangeBeds(@RequestParam Long sourceStudentId,
+            @RequestParam Long targetStudentId,
             @RequestParam(required = false) Long classId) {
-        return toAjax(xgDormBedStudentService.classTeacherExchangeBeds(sourceBedId, targetBedId, classId));
+        return toAjax(xgDormBedStudentService.classTeacherExchangeBeds(sourceStudentId, targetStudentId, classId));
     }
 
     /**
@@ -292,10 +292,10 @@ public class XgDormBedStudentController extends BaseController {
     @Log(title = "班主任床位移动", businessType = BusinessType.UPDATE)
     @RepeatSubmit()
     @PostMapping("/classTeacherMoveBed")
-    public R<Void> classTeacherMoveBed(@RequestParam Long sourceBedId,
+    public R<Void> classTeacherMoveBed(@RequestParam Long sourceStudentId,
             @RequestParam Long targetBedId,
             @RequestParam(required = false) Long classId) {
-        return toAjax(xgDormBedStudentService.classTeacherMoveBed(sourceBedId, targetBedId, classId));
+        return toAjax(xgDormBedStudentService.classTeacherMoveBed(sourceStudentId, targetBedId, classId));
     }
 
     /**

+ 129 - 0
backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgDormBedStudentMapper.java

@@ -3,6 +3,11 @@ package org.dromara.xg.mapper;
 import org.dromara.xg.domain.XgDormBedStudent;
 import org.dromara.xg.domain.vo.XgDormBedStudentVo;
 import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+import java.util.Map;
 
 /**
  * 床位学生分配关系Mapper接口
@@ -12,4 +17,128 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
  */
 public interface XgDormBedStudentMapper extends BaseMapperPlus<XgDormBedStudent, XgDormBedStudentVo> {
 
+    /**
+     * 查询班级已入住床位详情(通过SQL关联查询,按楼栋、房间、床位排序)
+     *
+     * @param classId 班级ID
+     * @return 班级已入住床位详情列表
+     */
+    @Select("""
+            SELECT
+                bs.bed_id,
+                bs.student_id,
+                bs.class_id,
+                bs.college_id,
+
+                -- 床位信息
+                b.bed_name,
+                b.bed_type,
+                b.bed_code,
+
+                -- 房间信息
+                r.id as room_id,
+                r.room_name,
+                r.room_code,
+
+                -- 楼栋信息
+                building.id as building_id,
+                building.building_name,
+                building.building_code,
+                building.building_type,
+
+                -- 宿舍区信息
+                area.id as area_id,
+                area.area_name,
+
+                -- 校区信息
+                campus.id as campus_id,
+                campus.campus_name,
+
+                -- 学生信息
+                s.student_no,
+                s.name as student_name,
+                s.gender,
+                s.phone,
+                s.id_card
+
+            FROM xg_dorm_bed_student bs
+            INNER JOIN xg_dorm_bed b ON bs.bed_id = b.id AND b.deleted = '0'
+            INNER JOIN xg_dorm_room r ON b.room_id = r.id AND r.deleted = '0'
+            INNER JOIN xg_dorm_building building ON r.building_id = building.id AND building.deleted = '0'
+            INNER JOIN xg_dorm_area area ON building.area_id = area.id AND area.deleted = '0'
+            INNER JOIN xg_dorm_campus campus ON area.campus_id = campus.id AND campus.deleted = '0'
+            INNER JOIN xg_student_msg s ON bs.student_id = s.id AND s.deleted = 0
+
+            WHERE bs.class_id = #{classId}
+            AND bs.student_id IS NOT NULL
+            AND bs.status = '0'
+            AND bs.deleted = '0'
+            AND s.student_status = '1'
+
+            ORDER BY
+                campus.campus_name,
+                area.area_name,
+                building.building_code,
+                r.room_code,
+                b.bed_code
+            """)
+    List<Map<String, Object>> selectClassOccupiedBedDetails(@Param("classId") Long classId);
+
+    /**
+     * 查询班级未分配学生床位详情(通过SQL关联查询,按楼栋、房间、床位排序)
+     *
+     * @param classId 班级ID
+     * @return 班级未分配学生床位详情列表
+     */
+    @Select("""
+            SELECT
+                bs.bed_id,
+                bs.class_id,
+                bs.college_id,
+
+                -- 床位信息
+                b.bed_name,
+                b.bed_type,
+                b.bed_code,
+
+                -- 房间信息
+                r.id as room_id,
+                r.room_name,
+                r.room_code,
+
+                -- 楼栋信息
+                building.id as building_id,
+                building.building_name,
+                building.building_code,
+                building.building_type,
+
+                -- 宿舍区信息
+                area.id as area_id,
+                area.area_name,
+
+                -- 校区信息
+                campus.id as campus_id,
+                campus.campus_name
+
+            FROM xg_dorm_bed_student bs
+            INNER JOIN xg_dorm_bed b ON bs.bed_id = b.id AND b.deleted = '0' AND b.bed_status = '1'
+            INNER JOIN xg_dorm_room r ON b.room_id = r.id AND r.deleted = '0'
+            INNER JOIN xg_dorm_building building ON r.building_id = building.id AND building.deleted = '0'
+            INNER JOIN xg_dorm_area area ON building.area_id = area.id AND area.deleted = '0'
+            INNER JOIN xg_dorm_campus campus ON area.campus_id = campus.id AND campus.deleted = '0'
+
+            WHERE bs.class_id = #{classId}
+            AND bs.student_id IS NULL
+            AND bs.status = '0'
+            AND bs.deleted = '0'
+
+            ORDER BY
+                campus.campus_name,
+                area.area_name,
+                building.building_code,
+                r.room_code,
+                b.bed_code
+            """)
+    List<Map<String, Object>> selectClassUnoccupiedBedDetails(@Param("classId") Long classId);
+
 }

+ 6 - 6
backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgDormBedStudentService.java

@@ -195,14 +195,14 @@ public interface IXgDormBedStudentService {
 
     /**
      * 班主任床位互换
-     * 将两个有学生的床位进行互换
+     * 将两个学生的床位进行互换
      *
-     * @param sourceBedId 源床位ID
-     * @param targetBedId 目标床位ID
-     * @param classId     班级ID
+     * @param sourceStudentId 源学生ID
+     * @param targetStudentId 目标学生ID
+     * @param classId         班级ID
      * @return 是否互换成功
      */
-    Boolean classTeacherExchangeBeds(Long sourceBedId, Long targetBedId, Long classId);
+    Boolean classTeacherExchangeBeds(Long sourceStudentId, Long targetStudentId, Long classId);
 
     /**
      * 班主任床位移动
@@ -213,7 +213,7 @@ public interface IXgDormBedStudentService {
      * @param classId     班级ID
      * @return 是否移动成功
      */
-    Boolean classTeacherMoveBed(Long sourceBedId, Long targetBedId, Long classId);
+    Boolean classTeacherMoveBed(Long sourceStudentId, Long targetBedId, Long classId);
 
     /**
      * 获取班级所有已入住宿舍的学生床位信息

+ 245 - 169
backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormBedStudentServiceImpl.java

@@ -1875,71 +1875,133 @@ public class XgDormBedStudentServiceImpl implements IXgDormBedStudentService {
 
     /**
      * 班主任床位互换
-     * 将两个有学生的床位进行互换
+     * 将两个学生的床位进行互换
      */
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public Boolean classTeacherExchangeBeds(Long sourceBedId, Long targetBedId, Long classId) {
+    public Boolean classTeacherExchangeBeds(Long sourceStudentId, Long targetStudentId, Long classId) {
         try {
-            log.info("班主任床位互换开始,源床位ID: {}, 目标床位ID: {}, 班级ID: {}", sourceBedId, targetBedId, classId);
+            log.info("班主任床位互换开始,源学生ID: {}, 目标学生ID: {}, 班级ID: {}", sourceStudentId, targetStudentId, classId);
 
             // 1. 校验参数
-            if (sourceBedId == null || targetBedId == null) {
-                throw new RuntimeException("床位ID不能为空");
+            if (sourceStudentId == null || targetStudentId == null) {
+                throw new RuntimeException("学生ID不能为空");
             }
-            if (sourceBedId.equals(targetBedId)) {
-                throw new RuntimeException("不能选择相同的床位进行互换");
+            if (sourceStudentId.equals(targetStudentId)) {
+                throw new RuntimeException("不能选择相同的学生进行互换");
             }
 
-            // 2. 获取源床位和目标床位的分配信息
-            LambdaQueryWrapper<XgDormBedStudent> queryWrapper = Wrappers.lambdaQuery();
-            queryWrapper.in(XgDormBedStudent::getBedId, sourceBedId, targetBedId)
-                    .eq(XgDormBedStudent::getDeleted, "0");
-            List<XgDormBedStudent> bedStudents = baseMapper.selectList(queryWrapper);
+            Date now = new Date();
+            Long loginUserId = LoginHelper.getUserId();
 
-            if (bedStudents.size() != 2) {
-                throw new RuntimeException("互换床位必须都已分配学生");
-            }
+            // 2. 查询两个学生当前的床位分配信息
+            LambdaQueryWrapper<XgDormBedStudent> sourceQueryWrapper = Wrappers.lambdaQuery();
+            sourceQueryWrapper.eq(XgDormBedStudent::getStudentId, sourceStudentId)
+                    .eq(XgDormBedStudent::getDeleted, "0")
+                    .eq(XgDormBedStudent::getStatus, "0");
+            XgDormBedStudent sourceBedStudent = baseMapper.selectOne(sourceQueryWrapper);
 
-            // 3. 找到对应的分配记录
-            XgDormBedStudent sourceBedStudent = bedStudents.stream()
-                    .filter(bs -> bs.getBedId().equals(sourceBedId))
-                    .findFirst()
-                    .orElseThrow(() -> new RuntimeException("未找到源床位的分配记录"));
+            LambdaQueryWrapper<XgDormBedStudent> targetQueryWrapper = Wrappers.lambdaQuery();
+            targetQueryWrapper.eq(XgDormBedStudent::getStudentId, targetStudentId)
+                    .eq(XgDormBedStudent::getDeleted, "0")
+                    .eq(XgDormBedStudent::getStatus, "0");
+            XgDormBedStudent targetBedStudent = baseMapper.selectOne(targetQueryWrapper);
 
-            XgDormBedStudent targetBedStudent = bedStudents.stream()
-                    .filter(bs -> bs.getBedId().equals(targetBedId))
-                    .findFirst()
-                    .orElseThrow(() -> new RuntimeException("未找到目标床位的分配记录"));
+            if (sourceBedStudent == null || targetBedStudent == null) {
+                throw new RuntimeException("学生必须都已分配床位才能互换");
+            }
 
-            // 4. 验证班级权限(如果指定了班级ID)
+            // 3. 验证班级权限(如果指定了班级ID)
             if (classId != null) {
-                if (!classId.equals(sourceBedStudent.getClassId()) && !classId.equals(targetBedStudent.getClassId())) {
-                    throw new RuntimeException("没有权限操作这些床位");
+                if (!classId.equals(sourceBedStudent.getClassId()) || !classId.equals(targetBedStudent.getClassId())) {
+                    throw new RuntimeException("没有权限操作这些学生床位");
                 }
             }
 
-            // 5. 执行互换:交换两个记录的床位ID
-            Long tempStudentId = sourceBedStudent.getStudentId();
-            Long tempClassId = sourceBedStudent.getClassId();
+            // 4. 查询两个学生在学生信息表中的宿舍信息
+            XgStudentMsg sourceStudent = xgStudentMsgMapper.selectById(sourceStudentId);
+            XgStudentMsg targetStudent = xgStudentMsgMapper.selectById(targetStudentId);
 
-            // 更新源床位分配记录
-            sourceBedStudent.setStudentId(targetBedStudent.getStudentId());
-            sourceBedStudent.setClassId(targetBedStudent.getClassId());
-            sourceBedStudent.setUpdateTime(new Date());
-            sourceBedStudent.setUpdateBy(LoginHelper.getUserId());
+            if (sourceStudent == null || targetStudent == null) {
+                throw new RuntimeException("未找到学生信息");
+            }
 
-            // 更新目标床位分配记录
-            targetBedStudent.setStudentId(tempStudentId);
-            targetBedStudent.setClassId(tempClassId);
-            targetBedStudent.setUpdateTime(new Date());
-            targetBedStudent.setUpdateBy(LoginHelper.getUserId());
+            // 5. 互换学生信息表中的宿舍信息
+            String tempDormitoryBuilding = sourceStudent.getDormitoryBuilding();
+            String tempDormitoryRoom = sourceStudent.getDormitoryRoom();
+            String tempExtField1 = sourceStudent.getExtField1();
+
+            // 更新源学生的宿舍信息
+            sourceStudent.setDormitoryBuilding(targetStudent.getDormitoryBuilding());
+            sourceStudent.setDormitoryRoom(targetStudent.getDormitoryRoom());
+            sourceStudent.setExtField1(targetStudent.getExtField1());
+            sourceStudent.setUpdateTime(now);
+            sourceStudent.setUpdateBy(loginUserId);
+
+            // 更新目标学生的宿舍信息
+            targetStudent.setDormitoryBuilding(tempDormitoryBuilding);
+            targetStudent.setDormitoryRoom(tempDormitoryRoom);
+            targetStudent.setExtField1(tempExtField1);
+            targetStudent.setUpdateTime(now);
+            targetStudent.setUpdateBy(loginUserId);
+
+            // 6. 更新学生信息表
+            xgStudentMsgMapper.updateById(sourceStudent);
+            xgStudentMsgMapper.updateById(targetStudent);
+
+            // 7. 更新床位分配表中原记录的状态为已退宿
+            sourceBedStudent.setStatus("1");
+            sourceBedStudent.setCheckoutTime(now);
+            sourceBedStudent.setUpdateTime(now);
+            sourceBedStudent.setUpdateBy(loginUserId);
+
+            targetBedStudent.setStatus("1");
+            targetBedStudent.setCheckoutTime(now);
+            targetBedStudent.setUpdateTime(now);
+            targetBedStudent.setUpdateBy(loginUserId);
 
-            // 6. 更新数据库
             baseMapper.updateById(sourceBedStudent);
             baseMapper.updateById(targetBedStudent);
 
-            log.info("班主任床位互换成功");
+            // 8. 插入两条新的床位分配记录
+            XgDormBedStudent newSourceBedStudent = new XgDormBedStudent();
+            newSourceBedStudent.setCollegeId(targetBedStudent.getCollegeId());
+            newSourceBedStudent.setMajorId(targetBedStudent.getMajorId());
+            newSourceBedStudent.setClassId(targetBedStudent.getClassId());
+            newSourceBedStudent.setStudentId(sourceStudentId);
+            newSourceBedStudent.setBedId(targetBedStudent.getBedId());
+            newSourceBedStudent.setRoomId(targetBedStudent.getRoomId());
+            newSourceBedStudent.setBuildingId(targetBedStudent.getBuildingId());
+            newSourceBedStudent.setAreaId(targetBedStudent.getAreaId());
+            newSourceBedStudent.setCampusId(targetBedStudent.getCampusId());
+            newSourceBedStudent.setStatus("0");
+            newSourceBedStudent.setAssignTime(now);
+            newSourceBedStudent.setDeleted("0");
+            newSourceBedStudent.setCreateTime(now);
+            newSourceBedStudent.setCreateBy(loginUserId);
+
+            XgDormBedStudent newTargetBedStudent = new XgDormBedStudent();
+            newTargetBedStudent.setCollegeId(sourceBedStudent.getCollegeId());
+            newTargetBedStudent.setMajorId(sourceBedStudent.getMajorId());
+            newTargetBedStudent.setClassId(sourceBedStudent.getClassId());
+            newTargetBedStudent.setStudentId(targetStudentId);
+            newTargetBedStudent.setBedId(sourceBedStudent.getBedId());
+            newTargetBedStudent.setRoomId(sourceBedStudent.getRoomId());
+            newTargetBedStudent.setBuildingId(sourceBedStudent.getBuildingId());
+            newTargetBedStudent.setAreaId(sourceBedStudent.getAreaId());
+            newTargetBedStudent.setCampusId(sourceBedStudent.getCampusId());
+            newTargetBedStudent.setStatus("0");
+            newTargetBedStudent.setAssignTime(now);
+            newTargetBedStudent.setDeleted("0");
+            newTargetBedStudent.setCreateTime(now);
+            newTargetBedStudent.setCreateBy(loginUserId);
+
+            baseMapper.insert(newSourceBedStudent);
+            baseMapper.insert(newTargetBedStudent);
+
+            log.info("班主任床位互换成功,源学生{}分配到床位{},目标学生{}分配到床位{}",
+                    sourceStudentId, targetBedStudent.getBedId(),
+                    targetStudentId, sourceBedStudent.getBedId());
             return true;
 
         } catch (Exception e) {
@@ -1954,37 +2016,40 @@ public class XgDormBedStudentServiceImpl implements IXgDormBedStudentService {
      */
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public Boolean classTeacherMoveBed(Long sourceBedId, Long targetBedId, Long classId) {
+    public Boolean classTeacherMoveBed(Long sourceStudentId, Long targetBedId, Long classId) {
         try {
-            log.info("班主任床位移动开始,源床位ID: {}, 目标床位ID: {}, 班级ID: {}", sourceBedId, targetBedId, classId);
+            log.info("班主任床位移动开始,源学生ID: {}, 目标床位ID: {}, 班级ID: {}", sourceStudentId, targetBedId, classId);
 
             // 1. 校验参数
-            if (sourceBedId == null || targetBedId == null) {
-                throw new RuntimeException("床位ID不能为空");
-            }
-            if (sourceBedId.equals(targetBedId)) {
-                throw new RuntimeException("不能选择相同的床位进行移动");
+            if (sourceStudentId == null || targetBedId == null) {
+                throw new RuntimeException("学生ID和目标床位ID不能为空");
             }
 
-            // 2. 检查源床位是否有学生分配
+            Date now = new Date();
+            Long loginUserId = LoginHelper.getUserId();
+
+            // 2. 查询学生当前的床位分配信息
             LambdaQueryWrapper<XgDormBedStudent> sourceQueryWrapper = Wrappers.lambdaQuery();
-            sourceQueryWrapper.eq(XgDormBedStudent::getBedId, sourceBedId)
-                    .eq(XgDormBedStudent::getDeleted, "0");
+            sourceQueryWrapper.eq(XgDormBedStudent::getStudentId, sourceStudentId)
+                    .eq(XgDormBedStudent::getDeleted, "0")
+                    .eq(XgDormBedStudent::getStatus, "0");
             XgDormBedStudent sourceBedStudent = baseMapper.selectOne(sourceQueryWrapper);
 
             if (sourceBedStudent == null) {
-                throw new RuntimeException("源床位未分配学生");
+                throw new RuntimeException("学生未分配床位");
             }
 
             // 3. 验证班级权限(如果指定了班级ID)
             if (classId != null && !classId.equals(sourceBedStudent.getClassId())) {
-                throw new RuntimeException("没有权限操作此床位");
+                throw new RuntimeException("没有权限操作此学生床位");
             }
 
             // 4. 检查目标床位是否空闲
             LambdaQueryWrapper<XgDormBedStudent> targetQueryWrapper = Wrappers.lambdaQuery();
             targetQueryWrapper.eq(XgDormBedStudent::getBedId, targetBedId)
-                    .eq(XgDormBedStudent::getDeleted, "0");
+                    .eq(XgDormBedStudent::getDeleted, "0")
+                    .eq(XgDormBedStudent::getStatus, "0")
+                    .isNotNull(XgDormBedStudent::getStudentId);
             XgDormBedStudent targetBedStudent = baseMapper.selectOne(targetQueryWrapper);
 
             if (targetBedStudent != null) {
@@ -1996,30 +2061,112 @@ public class XgDormBedStudentServiceImpl implements IXgDormBedStudentService {
             if (targetBed == null || !"0".equals(targetBed.getDeleted())) {
                 throw new RuntimeException("目标床位不存在");
             }
-            if (!"0".equals(targetBed.getBedStatus())) {
+            if (!"1".equals(targetBed.getBedStatus())) {
                 throw new RuntimeException("目标床位不可用(维修中或其他状态)");
             }
 
-            // 6. 创建目标床位的新分配记录
-            XgDormBedStudent newBedStudent = new XgDormBedStudent();
-            newBedStudent.setBedId(targetBedId);
-            newBedStudent.setStudentId(sourceBedStudent.getStudentId());
-            newBedStudent.setClassId(sourceBedStudent.getClassId());
-            newBedStudent.setCollegeId(sourceBedStudent.getCollegeId());
-            newBedStudent.setCreateTime(new Date());
-            newBedStudent.setCreateBy(LoginHelper.getUserId());
-            newBedStudent.setDeleted("0");
+            // 6. 检查是否是移动到相同床位
+            if (sourceBedStudent.getBedId().equals(targetBedId)) {
+                throw new RuntimeException("学生已在目标床位,无需移动");
+            }
+
+            // 7. 查询学生信息,准备更新宿舍信息
+            XgStudentMsg student = xgStudentMsgMapper.selectById(sourceStudentId);
+            if (student == null) {
+                throw new RuntimeException("未找到学生信息");
+            }
 
-            // 7. 插入新记录
-            baseMapper.insert(newBedStudent);
+            // 8. 查询目标床位的详细信息以更新学生宿舍信息
+            XgDormRoom targetRoom = xgDormRoomMapper.selectById(targetBed.getRoomId());
+            if (targetRoom == null) {
+                throw new RuntimeException("目标床位房间信息不存在");
+            }
 
-            // 8. 删除源床位的分配记录
-            sourceBedStudent.setDeleted("1");
-            sourceBedStudent.setUpdateTime(new Date());
-            sourceBedStudent.setUpdateBy(LoginHelper.getUserId());
+            // 获取目标床位的楼栋ID、宿舍区ID、校区ID
+            Long targetBuildingId = getBuildingIdByBedId(targetBedId);
+            Long targetAreaId = getAreaIdByBedId(targetBedId);
+            Long targetCampusId = getCampusIdByBedId(targetBedId);
+
+            if (targetBuildingId == null || targetAreaId == null || targetCampusId == null) {
+                throw new RuntimeException("目标床位层级信息不完整");
+            }
+
+            // 9. 更新学生信息表中的宿舍信息
+            student.setDormitoryBuilding(String.valueOf(targetBuildingId));
+            student.setDormitoryRoom(String.valueOf(targetBed.getRoomId()));
+            student.setExtField1(String.valueOf(targetBedId));
+            student.setUpdateTime(now);
+            student.setUpdateBy(loginUserId);
+            xgStudentMsgMapper.updateById(student);
+
+            // 10. 更新原床位分配记录状态为已退宿
+            sourceBedStudent.setStatus("1");
+            sourceBedStudent.setCheckoutTime(now);
+            sourceBedStudent.setUpdateTime(now);
+            sourceBedStudent.setUpdateBy(loginUserId);
             baseMapper.updateById(sourceBedStudent);
 
-            log.info("班主任床位移动成功");
+            // 11. 为原床位创建一个新的空闲分配记录(保持分配给班级但没有学生)
+            XgDormBedStudent newSourceBedRecord = new XgDormBedStudent();
+            newSourceBedRecord.setCollegeId(sourceBedStudent.getCollegeId());
+            newSourceBedRecord.setMajorId(sourceBedStudent.getMajorId());
+            newSourceBedRecord.setClassId(sourceBedStudent.getClassId());
+            newSourceBedRecord.setStudentId(null); // 空闲状态,没有学生
+            newSourceBedRecord.setBedId(sourceBedStudent.getBedId());
+            newSourceBedRecord.setRoomId(sourceBedStudent.getRoomId());
+            newSourceBedRecord.setBuildingId(sourceBedStudent.getBuildingId());
+            newSourceBedRecord.setAreaId(sourceBedStudent.getAreaId());
+            newSourceBedRecord.setCampusId(sourceBedStudent.getCampusId());
+            newSourceBedRecord.setStatus("0"); // 正常状态
+            newSourceBedRecord.setAssignTime(sourceBedStudent.getAssignTime()); // 没有分配给具体学生
+            newSourceBedRecord.setDeleted("0");
+            newSourceBedRecord.setCreateTime(now);
+            newSourceBedRecord.setCreateBy(loginUserId);
+            newSourceBedRecord.setUpdateTime(now);
+            newSourceBedRecord.setUpdateBy(loginUserId);
+            baseMapper.insert(newSourceBedRecord);
+
+            // 12. 查找目标床位的现有分配记录并更新student_id
+            LambdaQueryWrapper<XgDormBedStudent> targetBedQuery = Wrappers.lambdaQuery();
+            targetBedQuery.eq(XgDormBedStudent::getBedId, targetBedId)
+                    .eq(XgDormBedStudent::getDeleted, "0")
+                    .eq(XgDormBedStudent::getStatus, "0")
+                    .isNull(XgDormBedStudent::getStudentId); // 已分配给班级但没有学生的记录
+            XgDormBedStudent targetBedRecord = baseMapper.selectOne(targetBedQuery);
+
+            if (targetBedRecord != null) {
+                // 更新现有记录,添加学生信息
+                LambdaUpdateWrapper<XgDormBedStudent> updateTargetWrapper = Wrappers.lambdaUpdate();
+                updateTargetWrapper.eq(XgDormBedStudent::getId, targetBedRecord.getId())
+                        .set(XgDormBedStudent::getStudentId, sourceStudentId)
+                        .set(XgDormBedStudent::getAssignTime, now)
+                        .set(XgDormBedStudent::getUpdateBy, loginUserId)
+                        .set(XgDormBedStudent::getUpdateTime, now);
+                baseMapper.update(null, updateTargetWrapper);
+            } else {
+                // 如果目标床位没有现有的分配记录,创建新的分配记录
+                XgDormBedStudent newTargetBedRecord = new XgDormBedStudent();
+                newTargetBedRecord.setCollegeId(sourceBedStudent.getCollegeId());
+                newTargetBedRecord.setMajorId(sourceBedStudent.getMajorId());
+                newTargetBedRecord.setClassId(sourceBedStudent.getClassId());
+                newTargetBedRecord.setStudentId(sourceStudentId);
+                newTargetBedRecord.setBedId(targetBedId);
+                newTargetBedRecord.setRoomId(targetBed.getRoomId());
+                newTargetBedRecord.setBuildingId(targetBuildingId);
+                newTargetBedRecord.setAreaId(targetAreaId);
+                newTargetBedRecord.setCampusId(targetCampusId);
+                newTargetBedRecord.setStatus("0"); // 正常状态
+                newTargetBedRecord.setAssignTime(now);
+                newTargetBedRecord.setDeleted("0");
+                newTargetBedRecord.setCreateTime(now);
+                newTargetBedRecord.setCreateBy(loginUserId);
+                newTargetBedRecord.setUpdateTime(now);
+                newTargetBedRecord.setUpdateBy(loginUserId);
+                baseMapper.insert(newTargetBedRecord);
+            }
+
+            log.info("班主任床位移动成功,学生{}从床位{}移动到床位{}",
+                    sourceStudentId, sourceBedStudent.getBedId(), targetBedId);
             return true;
 
         } catch (Exception e) {
@@ -2038,69 +2185,33 @@ public class XgDormBedStudentServiceImpl implements IXgDormBedStudentService {
         try {
             log.info("开始获取班级已入住床位详情,班级ID: {}", classId);
 
-            // 查询已分配学生的床位信息
-            List<Map<String, Object>> bedDetails = baseMapper.selectMaps(
-                    Wrappers.lambdaQuery(XgDormBedStudent.class)
-                            .select(XgDormBedStudent::getBedId, XgDormBedStudent::getStudentId,
-                                    XgDormBedStudent::getClassId, XgDormBedStudent::getCollegeId)
-                            .eq(XgDormBedStudent::getClassId, classId)
-                            .isNotNull(XgDormBedStudent::getStudentId)
-                            .eq(XgDormBedStudent::getStatus, "0")
-                            .eq(XgDormBedStudent::getDeleted, "0"));
+            // 使用SQL关联查询,一次性获取所有信息并按楼栋、房间、床位排序
+            List<Map<String, Object>> bedDetails = baseMapper.selectClassOccupiedBedDetails(classId);
 
             List<Object> result = new ArrayList<>();
 
-            for (Map<String, Object> bedStudent : bedDetails) {
-                Long bedId = (Long) bedStudent.get("bed_id");
-                Long studentId = (Long) bedStudent.get("student_id");
-
-                // 查询床位详细信息
-                XgDormBed bed = xgDormBedMapper.selectById(bedId);
-                if (bed == null)
-                    continue;
-
-                XgDormRoom room = xgDormRoomMapper.selectById(bed.getRoomId());
-                if (room == null)
-                    continue;
-
-                XgDormBuilding building = xgDormBuildingMapper.selectById(room.getBuildingId());
-                if (building == null)
-                    continue;
-
-                XgDormArea area = xgDormAreaMapper.selectById(building.getAreaId());
-                if (area == null)
-                    continue;
-
-                XgDormCampus campus = xgDormCampusMapper.selectById(area.getCampusId());
-                if (campus == null)
-                    continue;
-
-                // 查询学生信息
-                XgStudentMsg student = xgStudentMsgMapper.selectById(studentId);
-                if (student == null)
-                    continue;
-
+            for (Map<String, Object> detailMap : bedDetails) {
                 // 组装结果数据
                 Map<String, Object> detailInfo = new LinkedHashMap<>();
 
                 // 床位信息
-                detailInfo.put("bedId", bedId);
-                detailInfo.put("campusName", campus.getCampusName());
-                detailInfo.put("areaName", area.getAreaName());
-                detailInfo.put("buildingName", building.getBuildingName());
-                detailInfo.put("roomName", room.getRoomName());
-                detailInfo.put("bedName", bed.getBedName());
-                detailInfo.put("bedType", bed.getBedType());
+                detailInfo.put("bedId", detailMap.get("bed_id"));
+                detailInfo.put("campusName", detailMap.get("campus_name"));
+                detailInfo.put("areaName", detailMap.get("area_name"));
+                detailInfo.put("buildingName", detailMap.get("building_name"));
+                detailInfo.put("roomName", detailMap.get("room_name"));
+                detailInfo.put("bedName", detailMap.get("bed_name"));
+                detailInfo.put("bedType", detailMap.get("bed_type"));
 
                 // 床位性别类型(基于楼栋类型)
-                String bedGenderType = building.getBuildingType(); // 1男生楼 2女生楼 3混合楼
+                String bedGenderType = (String) detailMap.get("building_type"); // 1男生楼 2女生楼 3混合楼
                 detailInfo.put("bedGenderType", bedGenderType);
 
                 // 学生信息
-                detailInfo.put("studentId", studentId);
-                detailInfo.put("studentName", student.getName());
-                detailInfo.put("studentNo", student.getStudentNo());
-                detailInfo.put("gender", student.getGender());
+                detailInfo.put("studentId", detailMap.get("student_id"));
+                detailInfo.put("studentName", detailMap.get("student_name"));
+                detailInfo.put("studentNo", detailMap.get("student_no"));
+                detailInfo.put("gender", detailMap.get("gender"));
 
                 result.add(detailInfo);
             }
@@ -2123,61 +2234,26 @@ public class XgDormBedStudentServiceImpl implements IXgDormBedStudentService {
         try {
             log.info("开始获取班级未分配学生床位详情,班级ID: {}", classId);
 
-            // 查询分配给班级但未分配学生的床位信息
-            List<Map<String, Object>> bedDetails = baseMapper.selectMaps(
-                    Wrappers.lambdaQuery(XgDormBedStudent.class)
-                            .select(XgDormBedStudent::getBedId, XgDormBedStudent::getClassId,
-                                    XgDormBedStudent::getCollegeId)
-                            .eq(XgDormBedStudent::getClassId, classId)
-                            .isNull(XgDormBedStudent::getStudentId)
-                            .eq(XgDormBedStudent::getStatus, "0")
-                            .eq(XgDormBedStudent::getDeleted, "0"));
+            // 使用SQL关联查询,一次性获取所有信息并按楼栋、房间、床位排序
+            List<Map<String, Object>> bedDetails = baseMapper.selectClassUnoccupiedBedDetails(classId);
 
             List<Object> result = new ArrayList<>();
 
-            for (Map<String, Object> bedStudent : bedDetails) {
-                Long bedId = (Long) bedStudent.get("bed_id");
-
-                // 查询床位详细信息
-                XgDormBed bed = xgDormBedMapper.selectById(bedId);
-                if (bed == null)
-                    continue;
-
-                // 确保床位可用
-                if (!"1".equals(bed.getBedStatus()) || !"0".equals(bed.getDeleted())) {
-                    continue;
-                }
-
-                XgDormRoom room = xgDormRoomMapper.selectById(bed.getRoomId());
-                if (room == null)
-                    continue;
-
-                XgDormBuilding building = xgDormBuildingMapper.selectById(room.getBuildingId());
-                if (building == null)
-                    continue;
-
-                XgDormArea area = xgDormAreaMapper.selectById(building.getAreaId());
-                if (area == null)
-                    continue;
-
-                XgDormCampus campus = xgDormCampusMapper.selectById(area.getCampusId());
-                if (campus == null)
-                    continue;
-
+            for (Map<String, Object> detailMap : bedDetails) {
                 // 组装结果数据
                 Map<String, Object> detailInfo = new LinkedHashMap<>();
 
                 // 床位信息
-                detailInfo.put("bedId", bedId);
-                detailInfo.put("campusName", campus.getCampusName());
-                detailInfo.put("areaName", area.getAreaName());
-                detailInfo.put("buildingName", building.getBuildingName());
-                detailInfo.put("roomName", room.getRoomName());
-                detailInfo.put("bedName", bed.getBedName());
-                detailInfo.put("bedType", bed.getBedType());
+                detailInfo.put("bedId", detailMap.get("bed_id"));
+                detailInfo.put("campusName", detailMap.get("campus_name"));
+                detailInfo.put("areaName", detailMap.get("area_name"));
+                detailInfo.put("buildingName", detailMap.get("building_name"));
+                detailInfo.put("roomName", detailMap.get("room_name"));
+                detailInfo.put("bedName", detailMap.get("bed_name"));
+                detailInfo.put("bedType", detailMap.get("bed_type"));
 
                 // 床位性别类型(基于楼栋类型)
-                String bedGenderType = building.getBuildingType(); // 1男生楼 2女生楼 3混合楼
+                String bedGenderType = (String) detailMap.get("building_type"); // 1男生楼 2女生楼 3混合楼
                 detailInfo.put("bedGenderType", bedGenderType);
 
                 result.add(detailInfo);

+ 7 - 7
web/src/api/xg/xgss/dormBedStudent/dormBedStudent/index.ts

@@ -219,30 +219,30 @@ export const classTeacherStayawaySelectedBeds = (bedIds: number[], classId?: str
 /**
  * 班主任床位互换
  * 将两个有学生的床位进行互换
- * @param sourceBedId 源床位ID
- * @param targetBedId 目标床位ID
+ * @param sourceStudentId 源学生ID
+ * @param targetStudentId 目标学生ID
  * @param classId 班级ID,可为空
  */
-export const classTeacherExchangeBeds = (sourceBedId: number, targetBedId: number, classId?: string | number) => {
+export const classTeacherExchangeBeds = (sourceStudentId: string | number, targetStudentId: string | number, classId?: string | number) => {
   return request({
     url: '/dormBedStudent/dormBedStudent/classTeacherExchangeBeds',
     method: 'post',
-    params: { sourceBedId, targetBedId, classId }
+    params: { sourceStudentId, targetStudentId, classId }
   });
 };
 
 /**
  * 班主任床位移动
  * 将学生从当前床位移动到指定的空闲床位
- * @param sourceBedId 源床位ID
+ * @param sourceStudentId 源学生ID
  * @param targetBedId 目标床位ID
  * @param classId 班级ID,可为空
  */
-export const classTeacherMoveBed = (sourceBedId: number, targetBedId: number, classId?: string | number) => {
+export const classTeacherMoveBed = (sourceStudentId: string | number, targetBedId?: string | number, classId?: string | number) => {
   return request({
     url: '/dormBedStudent/dormBedStudent/classTeacherMoveBed',
     method: 'post',
-    params: { sourceBedId, targetBedId, classId }
+    params: { sourceStudentId, targetBedId, classId }
   });
 };
 

+ 4 - 2
web/src/views/xg/xgss/bzrfp/components/BedTransferDialog.vue

@@ -528,9 +528,11 @@ const handleConfirm = async () => {
 
     // 调用API
     if (transferMode.value === 'exchange') {
-      await classTeacherExchangeBeds(props.selectedBed.id, selectedTargetBed.value.id, props.classId);
+      // 互换模式:传入两个学生ID
+      await classTeacherExchangeBeds(props.selectedBed.studentId, selectedTargetBed.value.studentId, props.classId);
     } else {
-      await classTeacherMoveBed(props.selectedBed.id, selectedTargetBed.value.id, props.classId);
+      // 移动模式:传入学生ID和目标床位ID
+      await classTeacherMoveBed(props.selectedBed.studentId, selectedTargetBed.value.id, props.classId);
     }
 
     ElMessage.success(`${transferMode.value === 'exchange' ? '互换' : '移动'}成功`);