zlwu пре 1 година
родитељ
комит
d9ea1caae8
15 измењених фајлова са 1233 додато и 68 уклоњено
  1. 105 0
      backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgDormBedStudentController.java
  2. 34 0
      backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentMsgController.java
  3. 103 0
      backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgDormBedStudent.java
  4. 112 0
      backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/bo/XgDormBedStudentBo.java
  5. 125 0
      backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgDormBedStudentVo.java
  6. 15 0
      backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/mapper/XgDormBedStudentMapper.java
  7. 68 0
      backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgDormBedStudentService.java
  8. 14 0
      backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentMsgService.java
  9. 144 0
      backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormBedStudentServiceImpl.java
  10. 69 0
      backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentMsgServiceImpl.java
  11. 7 0
      backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/dormBedStudent/XgDormBedStudentMapper.xml
  12. 70 68
      docs/设计文档/database/学工管理-宿舍管理/宿舍管理数据库建表脚本.sql
  13. 63 0
      web/src/api/xg/xgss/dormBedStudent/dormBedStudent/index.ts
  14. 231 0
      web/src/api/xg/xgss/dormBedStudent/dormBedStudent/types.ts
  15. 73 0
      web/src/views/xg/xsjcxx/studentMsg/studentMsg/index.vue

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

@@ -0,0 +1,105 @@
+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.XgDormBedStudentVo;
+import org.dromara.xg.domain.bo.XgDormBedStudentBo;
+import org.dromara.xg.service.IXgDormBedStudentService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 床位学生分配关系
+ *
+ * @author zlwu
+ * @date 2025-08-12
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/dormBedStudent/dormBedStudent")
+public class XgDormBedStudentController extends BaseController {
+
+    private final IXgDormBedStudentService xgDormBedStudentService;
+
+    /**
+     * 查询床位学生分配关系列表
+     */
+    @SaCheckPermission("dormBedStudent:dormBedStudent:list")
+    @GetMapping("/list")
+    public TableDataInfo<XgDormBedStudentVo> list(XgDormBedStudentBo bo, PageQuery pageQuery) {
+        return xgDormBedStudentService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出床位学生分配关系列表
+     */
+    @SaCheckPermission("dormBedStudent:dormBedStudent:export")
+    @Log(title = "床位学生分配关系", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(XgDormBedStudentBo bo, HttpServletResponse response) {
+        List<XgDormBedStudentVo> list = xgDormBedStudentService.queryList(bo);
+        ExcelUtil.exportExcel(list, "床位学生分配关系", XgDormBedStudentVo.class, response);
+    }
+
+    /**
+     * 获取床位学生分配关系详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("dormBedStudent:dormBedStudent:query")
+    @GetMapping("/{id}")
+    public R<XgDormBedStudentVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable Long id) {
+        return R.ok(xgDormBedStudentService.queryById(id));
+    }
+
+    /**
+     * 新增床位学生分配关系
+     */
+    @SaCheckPermission("dormBedStudent:dormBedStudent:add")
+    @Log(title = "床位学生分配关系", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody XgDormBedStudentBo bo) {
+        return toAjax(xgDormBedStudentService.insertByBo(bo));
+    }
+
+    /**
+     * 修改床位学生分配关系
+     */
+    @SaCheckPermission("dormBedStudent:dormBedStudent:edit")
+    @Log(title = "床位学生分配关系", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody XgDormBedStudentBo bo) {
+        return toAjax(xgDormBedStudentService.updateByBo(bo));
+    }
+
+    /**
+     * 删除床位学生分配关系
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("dormBedStudent:dormBedStudent:remove")
+    @Log(title = "床位学生分配关系", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable Long[] ids) {
+        return toAjax(xgDormBedStudentService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 34 - 0
backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgStudentMsgController.java

@@ -1240,4 +1240,38 @@ public class XgStudentMsgController extends BaseController {
 
         return exportVo;
     }
+
+    /**
+     * 批量申请床位
+     */
+    @SaCheckPermission("studentMsg:studentMsg:edit")
+    @Log(title = "学生信息", businessType = BusinessType.UPDATE)
+    @PostMapping("/batchApplyBed")
+    public R<Void> batchApplyBed(@RequestBody Map<String, Object> requestBody) {
+        List<Long> studentIds = parseLongList(requestBody.get("studentIds"));
+        if (studentIds == null || studentIds.isEmpty()) {
+            return R.fail("学生ID列表不能为空");
+        }
+
+        log.info("批量申请床位,学生ID列表: {}", studentIds);
+        xgStudentMsgService.batchApplyBed(studentIds);
+        return R.ok();
+    }
+
+    /**
+     * 批量取消床位
+     */
+    @SaCheckPermission("studentMsg:studentMsg:edit")
+    @Log(title = "学生信息", businessType = BusinessType.UPDATE)
+    @PostMapping("/batchCancelBed")
+    public R<Void> batchCancelBed(@RequestBody Map<String, Object> requestBody) {
+        List<Long> studentIds = parseLongList(requestBody.get("studentIds"));
+        if (studentIds == null || studentIds.isEmpty()) {
+            return R.fail("学生ID列表不能为空");
+        }
+
+        log.info("批量取消床位,学生ID列表: {}", studentIds);
+        xgStudentMsgService.batchCancelBed(studentIds);
+        return R.ok();
+    }
 }

+ 103 - 0
backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgDormBedStudent.java

@@ -0,0 +1,103 @@
+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.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.io.Serial;
+
+/**
+ * 床位学生分配关系对象 xg_dorm_bed_student
+ *
+ * @author zlwu
+ * @date 2025-08-12
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("xg_dorm_bed_student")
+public class XgDormBedStudent extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 分配学院ID
+     */
+    private Long collegeId;
+
+    /**
+     * 分配专业ID
+     */
+    private Long majorId;
+
+    /**
+     * 分配班级ID
+     */
+    private Long classId;
+
+    /**
+     * 分配学生ID
+     */
+    private Long studentId;
+
+    /**
+     * 床位ID
+     */
+    private Long bedId;
+
+    /**
+     * 房间ID
+     */
+    private Long roomId;
+
+    /**
+     * 宿舍楼ID
+     */
+    private Long buildingId;
+
+    /**
+     * 宿舍区ID
+     */
+    private Long areaId;
+
+    /**
+     * 校区ID
+     */
+    private Long campusId;
+
+    /**
+     * 状态(0正常 1已退宿)
+     */
+    private String status;
+
+    /**
+     * 分配时间
+     */
+    private Date assignTime;
+
+    /**
+     * 退宿时间
+     */
+    private Date checkoutTime;
+
+    /**
+     * 删除标志(0代表存在 1代表删除)
+     */
+    private String deleted;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 112 - 0
backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/bo/XgDormBedStudentBo.java

@@ -0,0 +1,112 @@
+package org.dromara.xg.domain.bo;
+
+import org.dromara.xg.domain.XgDormBedStudent;
+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.*;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 床位学生分配关系业务对象 xg_dorm_bed_student
+ *
+ * @author zlwu
+ * @date 2025-08-12
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = XgDormBedStudent.class, reverseConvertGenerate = false)
+public class XgDormBedStudentBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    @NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
+    private Long id;
+
+    /**
+     * 分配学院ID
+     */
+    @NotNull(message = "分配学院ID不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long collegeId;
+
+    /**
+     * 分配专业ID
+     */
+    @NotNull(message = "分配专业ID不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long majorId;
+
+    /**
+     * 分配班级ID
+     */
+    @NotNull(message = "分配班级ID不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long classId;
+
+    /**
+     * 分配学生ID
+     */
+    @NotNull(message = "分配学生ID不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long studentId;
+
+    /**
+     * 床位ID
+     */
+    @NotNull(message = "床位ID不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long bedId;
+
+    /**
+     * 房间ID
+     */
+    @NotNull(message = "房间ID不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long roomId;
+
+    /**
+     * 宿舍楼ID
+     */
+    @NotNull(message = "宿舍楼ID不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long buildingId;
+
+    /**
+     * 宿舍区ID
+     */
+    @NotNull(message = "宿舍区ID不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long areaId;
+
+    /**
+     * 校区ID
+     */
+    @NotNull(message = "校区ID不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long campusId;
+
+    /**
+     * 状态(0正常 1已退宿)
+     */
+    private String status;
+
+    /**
+     * 分配时间
+     */
+    @NotNull(message = "分配时间不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Date assignTime;
+
+    /**
+     * 退宿时间
+     */
+    private Date checkoutTime;
+
+    /**
+     * 删除标志(0代表存在 1代表删除)
+     */
+    private String deleted;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 125 - 0
backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgDormBedStudentVo.java

@@ -0,0 +1,125 @@
+package org.dromara.xg.domain.vo;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.dromara.xg.domain.XgDormBedStudent;
+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;
+import java.util.Date;
+
+
+
+/**
+ * 床位学生分配关系视图对象 xg_dorm_bed_student
+ *
+ * @author zlwu
+ * @date 2025-08-12
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = XgDormBedStudent.class)
+public class XgDormBedStudentVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 分配学院ID
+     */
+    @ExcelProperty(value = "分配学院ID")
+    private Long collegeId;
+
+    /**
+     * 分配专业ID
+     */
+    @ExcelProperty(value = "分配专业ID")
+    private Long majorId;
+
+    /**
+     * 分配班级ID
+     */
+    @ExcelProperty(value = "分配班级ID")
+    private Long classId;
+
+    /**
+     * 分配学生ID
+     */
+    @ExcelProperty(value = "分配学生ID")
+    private Long studentId;
+
+    /**
+     * 床位ID
+     */
+    @ExcelProperty(value = "床位ID")
+    private Long bedId;
+
+    /**
+     * 房间ID
+     */
+    @ExcelProperty(value = "房间ID")
+    private Long roomId;
+
+    /**
+     * 宿舍楼ID
+     */
+    @ExcelProperty(value = "宿舍楼ID")
+    private Long buildingId;
+
+    /**
+     * 宿舍区ID
+     */
+    @ExcelProperty(value = "宿舍区ID")
+    private Long areaId;
+
+    /**
+     * 校区ID
+     */
+    @ExcelProperty(value = "校区ID")
+    private Long campusId;
+
+    /**
+     * 状态(0正常 1已退宿)
+     */
+    @ExcelProperty(value = "状态(0正常 1已退宿)", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "accommodation_status")
+    private String status;
+
+    /**
+     * 分配时间
+     */
+    @ExcelProperty(value = "分配时间")
+    private Date assignTime;
+
+    /**
+     * 退宿时间
+     */
+    @ExcelProperty(value = "退宿时间")
+    private Date checkoutTime;
+
+    /**
+     * 删除标志(0代表存在 1代表删除)
+     */
+    @ExcelProperty(value = "删除标志(0代表存在 1代表删除)")
+    private String deleted;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

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

@@ -0,0 +1,15 @@
+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;
+
+/**
+ * 床位学生分配关系Mapper接口
+ *
+ * @author zlwu
+ * @date 2025-08-12
+ */
+public interface XgDormBedStudentMapper extends BaseMapperPlus<XgDormBedStudent, XgDormBedStudentVo> {
+
+}

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

@@ -0,0 +1,68 @@
+package org.dromara.xg.service;
+
+import org.dromara.xg.domain.vo.XgDormBedStudentVo;
+import org.dromara.xg.domain.bo.XgDormBedStudentBo;
+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 zlwu
+ * @date 2025-08-12
+ */
+public interface IXgDormBedStudentService {
+
+    /**
+     * 查询床位学生分配关系
+     *
+     * @param id 主键
+     * @return 床位学生分配关系
+     */
+    XgDormBedStudentVo queryById(Long id);
+
+    /**
+     * 分页查询床位学生分配关系列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 床位学生分配关系分页列表
+     */
+    TableDataInfo<XgDormBedStudentVo> queryPageList(XgDormBedStudentBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的床位学生分配关系列表
+     *
+     * @param bo 查询条件
+     * @return 床位学生分配关系列表
+     */
+    List<XgDormBedStudentVo> queryList(XgDormBedStudentBo bo);
+
+    /**
+     * 新增床位学生分配关系
+     *
+     * @param bo 床位学生分配关系
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(XgDormBedStudentBo bo);
+
+    /**
+     * 修改床位学生分配关系
+     *
+     * @param bo 床位学生分配关系
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(XgDormBedStudentBo bo);
+
+    /**
+     * 校验并批量删除床位学生分配关系信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 14 - 0
backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgStudentMsgService.java

@@ -138,4 +138,18 @@ public interface IXgStudentMsgService {
      * @return 请假审批人用户ID列表
      */
     List<Long> getCollegeLeaveApproversByStudentId(Long studentId);
+
+    /**
+     * 批量申请床位
+     *
+     * @param studentIds 学生ID列表
+     */
+    void batchApplyBed(List<Long> studentIds);
+
+    /**
+     * 批量取消床位
+     *
+     * @param studentIds 学生ID列表
+     */
+    void batchCancelBed(List<Long> studentIds);
 }

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

@@ -0,0 +1,144 @@
+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.dromara.xg.domain.bo.XgDormBedStudentBo;
+import org.dromara.xg.domain.vo.XgDormBedStudentVo;
+import org.dromara.xg.domain.XgDormBedStudent;
+import org.dromara.xg.mapper.XgDormBedStudentMapper;
+import org.dromara.xg.service.IXgDormBedStudentService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 床位学生分配关系Service业务层处理
+ *
+ * @author zlwu
+ * @date 2025-08-12
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class XgDormBedStudentServiceImpl implements IXgDormBedStudentService {
+
+    private final XgDormBedStudentMapper baseMapper;
+
+    /**
+     * 查询床位学生分配关系
+     *
+     * @param id 主键
+     * @return 床位学生分配关系
+     */
+    @Override
+    public XgDormBedStudentVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询床位学生分配关系列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 床位学生分配关系分页列表
+     */
+    @Override
+    public TableDataInfo<XgDormBedStudentVo> queryPageList(XgDormBedStudentBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<XgDormBedStudent> lqw = buildQueryWrapper(bo);
+        Page<XgDormBedStudentVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的床位学生分配关系列表
+     *
+     * @param bo 查询条件
+     * @return 床位学生分配关系列表
+     */
+    @Override
+    public List<XgDormBedStudentVo> queryList(XgDormBedStudentBo bo) {
+        LambdaQueryWrapper<XgDormBedStudent> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<XgDormBedStudent> buildQueryWrapper(XgDormBedStudentBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<XgDormBedStudent> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(XgDormBedStudent::getId);
+        lqw.eq(bo.getCollegeId() != null, XgDormBedStudent::getCollegeId, bo.getCollegeId());
+        lqw.eq(bo.getMajorId() != null, XgDormBedStudent::getMajorId, bo.getMajorId());
+        lqw.eq(bo.getClassId() != null, XgDormBedStudent::getClassId, bo.getClassId());
+        lqw.eq(bo.getStudentId() != null, XgDormBedStudent::getStudentId, bo.getStudentId());
+        lqw.eq(bo.getBedId() != null, XgDormBedStudent::getBedId, bo.getBedId());
+        lqw.eq(bo.getRoomId() != null, XgDormBedStudent::getRoomId, bo.getRoomId());
+        lqw.eq(bo.getBuildingId() != null, XgDormBedStudent::getBuildingId, bo.getBuildingId());
+        lqw.eq(bo.getAreaId() != null, XgDormBedStudent::getAreaId, bo.getAreaId());
+        lqw.eq(bo.getCampusId() != null, XgDormBedStudent::getCampusId, bo.getCampusId());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), XgDormBedStudent::getStatus, bo.getStatus());
+        lqw.eq(bo.getAssignTime() != null, XgDormBedStudent::getAssignTime, bo.getAssignTime());
+        lqw.eq(bo.getCheckoutTime() != null, XgDormBedStudent::getCheckoutTime, bo.getCheckoutTime());
+        lqw.eq(StringUtils.isNotBlank(bo.getDeleted()), XgDormBedStudent::getDeleted, bo.getDeleted());
+        return lqw;
+    }
+
+    /**
+     * 新增床位学生分配关系
+     *
+     * @param bo 床位学生分配关系
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(XgDormBedStudentBo bo) {
+        XgDormBedStudent add = MapstructUtils.convert(bo, XgDormBedStudent.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改床位学生分配关系
+     *
+     * @param bo 床位学生分配关系
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(XgDormBedStudentBo bo) {
+        XgDormBedStudent update = MapstructUtils.convert(bo, XgDormBedStudent.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(XgDormBedStudent entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除床位学生分配关系信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 69 - 0
backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgStudentMsgServiceImpl.java

@@ -35,10 +35,12 @@ import org.dromara.xg.mapper.XgStudentManagerMapper;
 import org.dromara.xg.mapper.XgStudentManagerSourceMapper;
 import org.dromara.xg.mapper.XgClassTeacherCounselorRelMapper;
 import org.dromara.xg.mapper.XgClassMsgMapper;
+import org.dromara.xg.mapper.XgDormBedStudentMapper;
 import org.dromara.xg.domain.XgStudentManager;
 import org.dromara.xg.domain.XgStudentManagerSource;
 import org.dromara.xg.domain.XgClassTeacherCounselorRel;
 import org.dromara.xg.domain.XgClassMsg;
+import org.dromara.xg.domain.XgDormBedStudent;
 import org.dromara.common.satoken.utils.LoginHelper;
 import java.util.stream.Collectors;
 
@@ -69,6 +71,7 @@ public class XgStudentMsgServiceImpl implements IXgStudentMsgService {
     private final XgStudentManagerSourceMapper xgStudentManagerSourceMapper;
     private final XgClassTeacherCounselorRelMapper xgClassTeacherCounselorRelMapper;
     private final XgClassMsgMapper xgClassMsgMapper;
+    private final XgDormBedStudentMapper xgDormBedStudentMapper;
 
     /**
      * 查询学生信息
@@ -1087,4 +1090,70 @@ public class XgStudentMsgServiceImpl implements IXgStudentMsgService {
         log.info("找到的请假审批人数量: {}", approverUserIds.size());
         return approverUserIds;
     }
+
+    /**
+     * 批量申请床位
+     *
+     * @param studentIds 学生ID列表
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void batchApplyBed(List<Long> studentIds) {
+        log.info("批量申请床位,学生ID列表: {}", studentIds);
+
+        if (studentIds == null || studentIds.isEmpty()) {
+            log.warn("学生ID列表为空,无法执行批量申请床位操作");
+            return;
+        }
+
+        // 批量更新学生信息表的is_boarder字段为1
+        LambdaQueryWrapper<XgStudentMsg> updateWrapper = Wrappers.lambdaQuery();
+        updateWrapper.in(XgStudentMsg::getId, studentIds);
+
+        XgStudentMsg updateEntity = new XgStudentMsg();
+        updateEntity.setIsBoarder(1L);
+
+        int updateCount = baseMapper.update(updateEntity, updateWrapper);
+        log.info("批量申请床位完成,共更新 {} 条学生记录", updateCount);
+    }
+
+    /**
+     * 批量取消床位
+     *
+     * @param studentIds 学生ID列表
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void batchCancelBed(List<Long> studentIds) {
+        log.info("批量取消床位,学生ID列表: {}", studentIds);
+
+        if (studentIds == null || studentIds.isEmpty()) {
+            log.warn("学生ID列表为空,无法执行批量取消床位操作");
+            return;
+        }
+
+        // 1. 批量更新学生信息表的is_boarder字段为0,同时清空宿舍楼栋和房间号
+        LambdaQueryWrapper<XgStudentMsg> updateWrapper = Wrappers.lambdaQuery();
+        updateWrapper.in(XgStudentMsg::getId, studentIds);
+
+        XgStudentMsg updateEntity = new XgStudentMsg();
+        updateEntity.setIsBoarder(0L);
+        updateEntity.setDormitoryBuilding(null); // 清空宿舍楼栋
+        updateEntity.setDormitoryRoom(null); // 清空宿舍房间号
+
+        int updateCount = baseMapper.update(updateEntity, updateWrapper);
+        log.info("批量取消床位 - 更新学生住宿状态并清空宿舍信息完成,共更新 {} 条学生记录", updateCount);
+
+        // 2. 更新宿舍床位学生表,将状态改为1(已退宿),设置退宿时间为当前时间
+        LambdaQueryWrapper<XgDormBedStudent> bedUpdateWrapper = Wrappers.lambdaQuery();
+        bedUpdateWrapper.in(XgDormBedStudent::getStudentId, studentIds);
+        bedUpdateWrapper.eq(XgDormBedStudent::getStatus, "0"); // 只更新状态为正常的记录
+
+        XgDormBedStudent bedUpdateEntity = new XgDormBedStudent();
+        bedUpdateEntity.setStatus("1"); // 设置为已退宿
+        bedUpdateEntity.setCheckoutTime(new Date()); // 设置退宿时间为当前时间
+
+        int bedUpdateCount = xgDormBedStudentMapper.update(bedUpdateEntity, bedUpdateWrapper);
+        log.info("批量取消床位 - 更新宿舍床位状态完成,共更新 {} 条床位记录", bedUpdateCount);
+    }
 }

+ 7 - 0
backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/dormBedStudent/XgDormBedStudentMapper.xml

@@ -0,0 +1,7 @@
+<?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.XgDormBedStudentMapper">
+
+</mapper>

+ 70 - 68
docs/设计文档/database/学工管理-宿舍管理/宿舍管理数据库建表脚本.sql

@@ -125,6 +125,8 @@ drop table if exists `xg_dorm_bed_student`;
 create table `xg_dorm_bed_student` (
   `id` bigint(20) not null comment '主键ID',
   `college_id` bigint(20) not null comment '分配学院ID',
+  `major_id` bigint(20) not null comment '分配专业ID',
+	`class_id` bigint(20) not null comment '分配班级ID',
   `student_id` bigint(20) not null comment '分配学生ID',
   `bed_id` bigint(20) not null comment '床位ID',
   `room_id` bigint(20) not null comment '房间ID',
@@ -200,73 +202,73 @@ create table `xg_dorm_manager_source` (
   key `idx_auth_source` (`auth_source`)
 ) engine=innodb default charset=utf8mb4 comment='管理员授权关系表';
 
--- 9. 管理员宿舍楼权限关系表
-drop table if exists `xg_dorm_manager_building`;
-create table `xg_dorm_manager_building` (
-  `id` bigint(20) not null comment '主键ID',
-  `manager_id` bigint(20) not null comment '管理员ID',
-  `building_id` bigint(20) not null comment '宿舍楼ID',
-  `status` char(1) default '0' comment '状态(0有效 1已撤销)',
-  `deleted` char(1) default '0' comment '删除标志(0代表存在 1代表删除)',
-  `tenant_id` bigint(20) default '0' comment '租户编号',
-  `create_by` bigint(20) default null comment '创建者',
-  `create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
-  `create_time` datetime default null comment '创建时间',
-  `update_by` bigint(20) default null comment '更新者',
-  `update_time` datetime default null comment '更新时间',
-  `remark` varchar(500) default null comment '备注',
-  primary key (`id`),
-  unique key `uk_manager_building` (`manager_id`, `building_id`),
-  key `idx_manager_id` (`manager_id`),
-  key `idx_building_id` (`building_id`)
-) engine=innodb default charset=utf8mb4 comment='管理员宿舍楼权限关系表';
+-- 9. 管理员宿舍楼权限关系表 -- 废弃,使用管理员授权关系表来代替
+-- drop table if exists `xg_dorm_manager_building`;
+-- create table `xg_dorm_manager_building` (
+--   `id` bigint(20) not null comment '主键ID',
+--   `manager_id` bigint(20) not null comment '管理员ID',
+--   `building_id` bigint(20) not null comment '宿舍楼ID',
+--   `status` char(1) default '0' comment '状态(0有效 1已撤销)',
+--   `deleted` char(1) default '0' comment '删除标志(0代表存在 1代表删除)',
+--   `tenant_id` bigint(20) default '0' comment '租户编号',
+--   `create_by` bigint(20) default null comment '创建者',
+--   `create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
+--   `create_time` datetime default null comment '创建时间',
+--   `update_by` bigint(20) default null comment '更新者',
+--   `update_time` datetime default null comment '更新时间',
+--   `remark` varchar(500) default null comment '备注',
+--   primary key (`id`),
+--   unique key `uk_manager_building` (`manager_id`, `building_id`),
+--   key `idx_manager_id` (`manager_id`),
+--   key `idx_building_id` (`building_id`)
+-- ) engine=innodb default charset=utf8mb4 comment='管理员宿舍楼权限关系表';
 
--- 10. 二级学院宿舍管理员信息表
-drop table if exists `xg_dorm_college_manager`;
-create table `xg_dorm_college_manager` (
-  `id` bigint(20) not null comment '主键ID',
-  `manager_name` varchar(100) not null comment '管理员姓名',
-  `college_id` bigint(20) not null comment '所属学院ID',
-  `user_id` bigint(20) default null comment '关联用户ID',
-  `phone` varchar(20) default null comment '联系电话',
-  `gender` char(1) default '0' comment '性别(0男 1女 2未知)',
-  `status` char(1) default '0' comment '状态(0正常 1停用)',
-  `deleted` char(1) default '0' comment '删除标志(0代表存在 1代表删除)',
-  `tenant_id` bigint(20) default '0' comment '租户编号',
-  `create_by` bigint(20) default null comment '创建者',
-  `create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
-  `create_time` datetime default null comment '创建时间',
-  `update_by` bigint(20) default null comment '更新者',
-  `update_time` datetime default null comment '更新时间',
-  `remark` varchar(500) default null comment '备注',
-  primary key (`id`),
-  key `idx_college_id` (`college_id`),
-  key `idx_user_id` (`user_id`)
-) engine=innodb default charset=utf8mb4 comment='二级学院宿舍管理员信息表';
+-- 10. 二级学院宿舍管理员信息表 -- 废弃,使用角色来作为二级学院管理员
+-- drop table if exists `xg_dorm_college_manager`;
+-- create table `xg_dorm_college_manager` (
+--   `id` bigint(20) not null comment '主键ID',
+--   `manager_name` varchar(100) not null comment '管理员姓名',
+--   `college_id` bigint(20) not null comment '所属学院ID',
+--   `user_id` bigint(20) default null comment '关联用户ID',
+--   `phone` varchar(20) default null comment '联系电话',
+--   `gender` char(1) default '0' comment '性别(0男 1女 2未知)',
+--   `status` char(1) default '0' comment '状态(0正常 1停用)',
+--   `deleted` char(1) default '0' comment '删除标志(0代表存在 1代表删除)',
+--   `tenant_id` bigint(20) default '0' comment '租户编号',
+--   `create_by` bigint(20) default null comment '创建者',
+--   `create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
+--   `create_time` datetime default null comment '创建时间',
+--   `update_by` bigint(20) default null comment '更新者',
+--   `update_time` datetime default null comment '更新时间',
+--   `remark` varchar(500) default null comment '备注',
+--   primary key (`id`),
+--   key `idx_college_id` (`college_id`),
+--   key `idx_user_id` (`user_id`)
+-- ) engine=innodb default charset=utf8mb4 comment='二级学院宿舍管理员信息表';
 
--- 11. 二级学院床位绑定关系表
-drop table if exists `xg_dorm_college_bed`;
-create table `xg_dorm_college_bed` (
-  `id` bigint(20) not null comment '主键ID',
-  `college_id` bigint(20) not null comment '学院ID',
-  `bed_id` bigint(20) not null comment '床位ID',
-  `building_id` bigint(20) not null comment '宿舍楼ID',
-  `room_id` bigint(20) not null comment '房间ID',
-  `status` char(1) default '0' comment '状态(0正常 1已解除)',
-  `assign_time` datetime default null comment '分配时间',
-  `release_time` datetime default null comment '到期解除时间',
-  `deleted` char(1) default '0' comment '删除标志(0代表存在 1代表删除)',
-  `tenant_id` bigint(20) default '0' comment '租户编号',
-  `create_by` bigint(20) default null comment '创建者',
-  `create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
-  `create_time` datetime default null comment '创建时间',
-  `update_by` bigint(20) default null comment '更新者',
-  `update_time` datetime default null comment '更新时间',
-  `remark` varchar(500) default null comment '备注',
-  primary key (`id`),
-  unique key `uk_college_bed` (`college_id`, `bed_id`),
-  key `idx_college_id` (`college_id`),
-  key `idx_bed_id` (`bed_id`),
-  key `idx_building_id` (`building_id`),
-  key `idx_room_id` (`room_id`)
-) engine=innodb default charset=utf8mb4 comment='二级学院床位绑定关系表';
+-- 11. 二级学院床位绑定关系表 --废弃
+-- drop table if exists `xg_dorm_college_bed`;
+-- create table `xg_dorm_college_bed` (
+--   `id` bigint(20) not null comment '主键ID',
+--   `college_id` bigint(20) not null comment '学院ID',
+--   `bed_id` bigint(20) not null comment '床位ID',
+--   `building_id` bigint(20) not null comment '宿舍楼ID',
+--   `room_id` bigint(20) not null comment '房间ID',
+--   `status` char(1) default '0' comment '状态(0正常 1已解除)',
+--   `assign_time` datetime default null comment '分配时间',
+--   `release_time` datetime default null comment '到期解除时间',
+--   `deleted` char(1) default '0' comment '删除标志(0代表存在 1代表删除)',
+--   `tenant_id` bigint(20) default '0' comment '租户编号',
+--   `create_by` bigint(20) default null comment '创建者',
+--   `create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
+--   `create_time` datetime default null comment '创建时间',
+--   `update_by` bigint(20) default null comment '更新者',
+--   `update_time` datetime default null comment '更新时间',
+--   `remark` varchar(500) default null comment '备注',
+--   primary key (`id`),
+--   unique key `uk_college_bed` (`college_id`, `bed_id`),
+--   key `idx_college_id` (`college_id`),
+--   key `idx_bed_id` (`bed_id`),
+--   key `idx_building_id` (`building_id`),
+--   key `idx_room_id` (`room_id`)
+-- ) engine=innodb default charset=utf8mb4 comment='二级学院床位绑定关系表';

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

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { DormBedStudentVO, DormBedStudentForm, DormBedStudentQuery } from '@/api/xg/xgss/dormBedStudent/dormBedStudent/types';
+
+/**
+ * 查询床位学生分配关系列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listDormBedStudent = (query?: DormBedStudentQuery): AxiosPromise<DormBedStudentVO[]> => {
+  return request({
+    url: '/dormBedStudent/dormBedStudent/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询床位学生分配关系详细
+ * @param id
+ */
+export const getDormBedStudent = (id: string | number): AxiosPromise<DormBedStudentVO> => {
+  return request({
+    url: '/dormBedStudent/dormBedStudent/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增床位学生分配关系
+ * @param data
+ */
+export const addDormBedStudent = (data: DormBedStudentForm) => {
+  return request({
+    url: '/dormBedStudent/dormBedStudent',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改床位学生分配关系
+ * @param data
+ */
+export const updateDormBedStudent = (data: DormBedStudentForm) => {
+  return request({
+    url: '/dormBedStudent/dormBedStudent',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除床位学生分配关系
+ * @param id
+ */
+export const delDormBedStudent = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/dormBedStudent/dormBedStudent/' + id,
+    method: 'delete'
+  });
+};

+ 231 - 0
web/src/api/xg/xgss/dormBedStudent/dormBedStudent/types.ts

@@ -0,0 +1,231 @@
+export interface DormBedStudentVO {
+  /**
+   * 主键ID
+   */
+  id: string | number;
+
+  /**
+   * 分配学院ID
+   */
+  collegeId: string | number;
+
+  /**
+   * 分配专业ID
+   */
+  majorId: string | number;
+
+  /**
+   * 分配班级ID
+   */
+  classId: string | number;
+
+  /**
+   * 分配学生ID
+   */
+  studentId: string | number;
+
+  /**
+   * 床位ID
+   */
+  bedId: string | number;
+
+  /**
+   * 房间ID
+   */
+  roomId: string | number;
+
+  /**
+   * 宿舍楼ID
+   */
+  buildingId: string | number;
+
+  /**
+   * 宿舍区ID
+   */
+  areaId: string | number;
+
+  /**
+   * 校区ID
+   */
+  campusId: string | number;
+
+  /**
+   * 状态(0正常 1已退宿)
+   */
+  status: string;
+
+  /**
+   * 分配时间
+   */
+  assignTime: string;
+
+  /**
+   * 退宿时间
+   */
+  checkoutTime: string;
+
+  /**
+   * 删除标志(0代表存在 1代表删除)
+   */
+  deleted: string;
+
+  /**
+   * 备注
+   */
+  remark: string;
+
+}
+
+export interface DormBedStudentForm extends BaseEntity {
+  /**
+   * 主键ID
+   */
+  id?: string | number;
+
+  /**
+   * 分配学院ID
+   */
+  collegeId?: string | number;
+
+  /**
+   * 分配专业ID
+   */
+  majorId?: string | number;
+
+  /**
+   * 分配班级ID
+   */
+  classId?: string | number;
+
+  /**
+   * 分配学生ID
+   */
+  studentId?: string | number;
+
+  /**
+   * 床位ID
+   */
+  bedId?: string | number;
+
+  /**
+   * 房间ID
+   */
+  roomId?: string | number;
+
+  /**
+   * 宿舍楼ID
+   */
+  buildingId?: string | number;
+
+  /**
+   * 宿舍区ID
+   */
+  areaId?: string | number;
+
+  /**
+   * 校区ID
+   */
+  campusId?: string | number;
+
+  /**
+   * 状态(0正常 1已退宿)
+   */
+  status?: string;
+
+  /**
+   * 分配时间
+   */
+  assignTime?: string;
+
+  /**
+   * 退宿时间
+   */
+  checkoutTime?: string;
+
+  /**
+   * 删除标志(0代表存在 1代表删除)
+   */
+  deleted?: string;
+
+  /**
+   * 备注
+   */
+  remark?: string;
+
+}
+
+export interface DormBedStudentQuery extends PageQuery {
+
+  /**
+   * 分配学院ID
+   */
+  collegeId?: string | number;
+
+  /**
+   * 分配专业ID
+   */
+  majorId?: string | number;
+
+  /**
+   * 分配班级ID
+   */
+  classId?: string | number;
+
+  /**
+   * 分配学生ID
+   */
+  studentId?: string | number;
+
+  /**
+   * 床位ID
+   */
+  bedId?: string | number;
+
+  /**
+   * 房间ID
+   */
+  roomId?: string | number;
+
+  /**
+   * 宿舍楼ID
+   */
+  buildingId?: string | number;
+
+  /**
+   * 宿舍区ID
+   */
+  areaId?: string | number;
+
+  /**
+   * 校区ID
+   */
+  campusId?: string | number;
+
+  /**
+   * 状态(0正常 1已退宿)
+   */
+  status?: string;
+
+  /**
+   * 分配时间
+   */
+  assignTime?: string;
+
+  /**
+   * 退宿时间
+   */
+  checkoutTime?: string;
+
+  /**
+   * 删除标志(0代表存在 1代表删除)
+   */
+  deleted?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 73 - 0
web/src/views/xg/xsjcxx/studentMsg/studentMsg/index.vue

@@ -87,6 +87,12 @@
               <el-col :span="1.5">
                 <el-button :disabled="single" icon="Edit" @click="handleUpdate()"> 修改 </el-button>
               </el-col>
+              <el-col :span="1.5">
+                <el-button type="primary" :disabled="multiple" @click="handleBatchApplyBed()"> 批量申请床位 </el-button>
+              </el-col>
+              <el-col :span="1.5">
+                <el-button type="danger" :disabled="multiple" @click="handleBatchCancelBed()"> 批量取消床位 </el-button>
+              </el-col>
               <!-- <el-col :span="1.5">
                 <el-button :disabled="multiple" icon="Delete" @click="handleDelete()"> 删除 </el-button>
               </el-col> -->
@@ -2125,6 +2131,73 @@ const handleDelete = async (row?: StudentVO) => {
   }
 };
 
+/** 批量申请床位按钮操作 */
+const handleBatchApplyBed = async () => {
+  if (ids.value.length === 0) {
+    ElMessage.warning('请选择要申请床位的学生');
+    return;
+  }
+
+  const [err] = await to(
+    ElMessageBox.confirm(`确认为选中的 ${ids.value.length} 名学生申请床位吗?`, '批量申请床位', {
+      confirmButtonText: '确认申请',
+      cancelButtonText: '取消',
+      type: 'info'
+    })
+  );
+
+  if (!err) {
+    try {
+      const res = await service.post('/studentMsg/studentMsg/batchApplyBed', {
+        studentIds: ids.value
+      });
+      if (res && res.code === 200) {
+        await getList();
+        ElMessage.success('批量申请床位成功');
+      } else {
+        ElMessage.error(res?.msg || '批量申请床位失败');
+      }
+    } catch (error) {
+      console.error('批量申请床位失败:', error);
+      ElMessage.error('批量申请床位失败,请重试');
+    }
+  }
+};
+
+/** 批量取消床位按钮操作 */
+const handleBatchCancelBed = async () => {
+  if (ids.value.length === 0) {
+    ElMessage.warning('请选择要取消床位的学生');
+    return;
+  }
+
+  const [err] = await to(
+    ElMessageBox.confirm('请确认是否取消,会将学生已有宿舍清除!!!', '批量取消床位', {
+      confirmButtonText: '确认取消',
+      cancelButtonText: '取消',
+      type: 'warning',
+      dangerouslyUseHTMLString: true
+    })
+  );
+
+  if (!err) {
+    try {
+      const res = await service.post('/studentMsg/studentMsg/batchCancelBed', {
+        studentIds: ids.value
+      });
+      if (res && res.code === 200) {
+        await getList();
+        ElMessage.success('批量取消床位成功');
+      } else {
+        ElMessage.error(res?.msg || '批量取消床位失败');
+      }
+    } catch (error) {
+      console.error('批量取消床位失败:', error);
+      ElMessage.error('批量取消床位失败,请重试');
+    }
+  }
+};
+
 /** 查看详情按钮操作 */
 const handleDetail = async (row: StudentVO) => {
   const studentId = row?.id;