From 2a38245ae25e81edd54228e12160408b0b10bd2f Mon Sep 17 00:00:00 2001 From: zlwu <704541015@qq.com> Date: Thu, 4 Sep 2025 12:29:51 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E5=AE=BF=E8=88=8D=E5=8C=BA?= =?UTF-8?q?=E5=8E=BB=E9=99=A4=E7=9A=84=E4=B8=9A=E5=8A=A1=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../XgDormBedStudentController.java | 4 +- .../controller/XgDormBuildingController.java | 24 +- .../XgDormBuildingTreeController.java | 57 +++- .../dromara/xg/domain/XgDormHygieneCheck.java | 2 +- .../xg/domain/XgDormHygieneStudentScore.java | 2 +- .../xg/domain/bo/XgDormBuildingBo.java | 3 +- .../vo/DormBuildingTreeSimplifiedVo.java | 104 ++++++ .../domain/vo/XgDormBuildingSimplifiedVo.java | 103 ++++++ .../vo/XgDormHygieneCheckSimplifiedVo.java | 183 ++++++++++ .../xg/service/IXgDormBedStudentService.java | 2 +- .../xg/service/IXgDormBuildingService.java | 20 ++ .../service/IXgDormBuildingTreeService.java | 19 ++ .../impl/XgDormBedStudentServiceImpl.java | 63 +++- .../impl/XgDormBuildingServiceImpl.java | 117 ++++--- .../impl/XgDormBuildingTreeServiceImpl.java | 39 +++ .../service/impl/XgDormRoomServiceImpl.java | 4 +- docs/开发文档/API/宿舍卫生检查管理API.md | 81 ++++- docs/开发文档/API/宿舍楼树形结构API.md | 176 +++++++--- docs/设计文档/database/hzdyjs_xg0820.sql | 4 +- .../DormHygieneCheckDialog.vue | 185 ++++------ .../dormHygieneCheck/index.vue | 12 +- .../xg/xgss/sslxx/dormBuilding/index.vue | 321 +++--------------- web/src/views/xg/xgss/xsssfjgl/index.vue | 168 ++++++--- web/src/views/xg/xgss/xsssgly/index.vue | 3 +- 24 files changed, 1139 insertions(+), 557 deletions(-) create mode 100644 backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/DormBuildingTreeSimplifiedVo.java create mode 100644 backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgDormBuildingSimplifiedVo.java create mode 100644 backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgDormHygieneCheckSimplifiedVo.java 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 7de403d4..2c02ae9f 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 @@ -157,7 +157,7 @@ public class XgDormBedStudentController extends BaseController { /** * 获取当前用户二级学院的宿舍楼树形结构 - * 校区-宿舍区-宿舍楼三级结构,校区和宿舍区不可选,只有宿舍楼可以选择 + * 校区-宿舍楼二级结构,校区不可选,只有宿舍楼可以选择 */ @SaCheckPermission("dormBedStudent:dormBedStudent:list") @GetMapping("/currentUserCollegeDormTree") @@ -168,7 +168,7 @@ public class XgDormBedStudentController extends BaseController { /** * 获取班主任管理的班级宿舍楼树形结构 - * 只显示班主任管理班级分配到的宿舍楼 + * 校区-宿舍楼二级结构,只显示班主任管理班级分配到的宿舍楼 */ @SaCheckPermission("dormBedStudent:dormBedStudent:list") @GetMapping("/getClassTeacherDormTree") diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgDormBuildingController.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgDormBuildingController.java index 30420e62..9d1b519b 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgDormBuildingController.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgDormBuildingController.java @@ -18,6 +18,7 @@ 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.XgDormBuildingVo; +import org.dromara.xg.domain.vo.XgDormBuildingSimplifiedVo; import org.dromara.xg.domain.bo.XgDormBuildingBo; import org.dromara.xg.domain.vo.BuildingTreeSelectVo; import org.dromara.xg.service.IXgDormBuildingService; @@ -104,7 +105,7 @@ public class XgDormBuildingController extends BaseController { /** * 获取宿舍楼树形结构数据 - * 校区-宿舍区-宿舍楼三级结构,校区和宿舍区不可选,只有宿舍楼可以选择 + * 校区-宿舍楼二级结构,校区不可选,只有宿舍楼可以选择 */ @SaCheckPermission("sslxx:dormBuilding:list") @GetMapping("/buildingTree") @@ -112,4 +113,25 @@ public class XgDormBuildingController extends BaseController { List treeData = xgDormBuildingService.getBuildingTreeData(); return R.ok(treeData); } + + /** + * 查询宿舍楼信息简化列表 + * 用于简化界面显示,隐藏宿舍区层级,直接显示校区→宿舍楼结构 + */ + @SaCheckPermission("sslxx:dormBuilding:list") + @GetMapping("/simplifiedList") + public TableDataInfo getSimplifiedList(XgDormBuildingBo bo, PageQuery pageQuery) { + return xgDormBuildingService.querySimplifiedPageList(bo, pageQuery); + } + + /** + * 查询宿舍楼信息简化列表(不分页) + * 用于下拉选择等场景 + */ + @SaCheckPermission("sslxx:dormBuilding:list") + @GetMapping("/simplifiedListAll") + public R> getSimplifiedListAll(XgDormBuildingBo bo) { + List list = xgDormBuildingService.querySimplifiedList(bo); + return R.ok(list); + } } diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgDormBuildingTreeController.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgDormBuildingTreeController.java index 01f01f94..a1cf2805 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgDormBuildingTreeController.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/controller/XgDormBuildingTreeController.java @@ -9,6 +9,7 @@ import org.springframework.validation.annotation.Validated; import org.dromara.common.web.core.BaseController; import org.dromara.common.core.domain.R; import org.dromara.xg.domain.vo.DormBuildingTreeVo; +import org.dromara.xg.domain.vo.DormBuildingTreeSimplifiedVo; import org.dromara.xg.domain.bo.DormBuildingTreeBo; import org.dromara.xg.service.IXgDormBuildingTreeService; @@ -28,24 +29,70 @@ public class XgDormBuildingTreeController extends BaseController { /** * 获取宿舍楼树形结构数据 - * 校区-宿舍区-宿舍楼三级结构,校区和宿舍区不可选,只有宿舍楼可以选择 + * 校区-宿舍楼二级结构,校区不可选,只有宿舍楼可以选择 */ @SaCheckPermission("xgss:dormBuildingTree:list") @GetMapping("/list") - public R> getDormBuildingTree(DormBuildingTreeBo bo) { - List treeData = xgDormBuildingTreeService.getDormBuildingTree(bo); + public R> getDormBuildingTree(DormBuildingTreeBo bo) { + List treeData = xgDormBuildingTreeService.getSimplifiedDormBuildingTree(bo); return R.ok(treeData); } /** * 获取所有宿舍楼树形结构数据(不考虑权限) - * 校区-宿舍区-宿舍楼三级结构,校区和宿舍区不可选,只有宿舍楼可以选择 + * 校区-宿舍楼二级结构,校区不可选,只有宿舍楼可以选择 */ @SaCheckPermission("xgss:dormBuildingTree:list") @GetMapping("/listAll") - public R> getAllDormBuildingTree(DormBuildingTreeBo bo) { + public R> getAllDormBuildingTree(DormBuildingTreeBo bo) { + List treeData = xgDormBuildingTreeService.getAllSimplifiedDormBuildingTree(bo); + return R.ok(treeData); + } + + /** + * 获取宿舍楼树形结构完整数据(包含宿舍区层级) + * 校区-宿舍区-宿舍楼三级结构,校区和宿舍区不可选,只有宿舍楼可以选择 + * 注意:此接口仅用于特殊需求,一般情况请使用/list接口 + */ + @SaCheckPermission("xgss:dormBuildingTree:list") + @GetMapping("/fullList") + public R> getFullDormBuildingTree(DormBuildingTreeBo bo) { + List treeData = xgDormBuildingTreeService.getDormBuildingTree(bo); + return R.ok(treeData); + } + + /** + * 获取所有宿舍楼树形结构完整数据(不考虑权限,包含宿舍区层级) + * 校区-宿舍区-宿舍楼三级结构,校区和宿舍区不可选,只有宿舍楼可以选择 + * 注意:此接口仅用于特殊需求,一般情况请使用/listAll接口 + */ + @SaCheckPermission("xgss:dormBuildingTree:list") + @GetMapping("/fullListAll") + public R> getAllFullDormBuildingTree(DormBuildingTreeBo bo) { List treeData = xgDormBuildingTreeService.getAllDormBuildingTree(bo); return R.ok(treeData); } + /** + * 获取宿舍楼树形结构简化数据 + * 校区-宿舍楼二级结构,隐藏宿舍区层级,校区不可选,只有宿舍楼可以选择 + */ + @SaCheckPermission("xgss:dormBuildingTree:list") + @GetMapping("/simplifiedList") + public R> getSimplifiedDormBuildingTree(DormBuildingTreeBo bo) { + List treeData = xgDormBuildingTreeService.getSimplifiedDormBuildingTree(bo); + return R.ok(treeData); + } + + /** + * 获取所有宿舍楼树形结构简化数据(不考虑权限) + * 校区-宿舍楼二级结构,隐藏宿舍区层级,校区不可选,只有宿舍楼可以选择 + */ + @SaCheckPermission("xgss:dormBuildingTree:list") + @GetMapping("/simplifiedListAll") + public R> getAllSimplifiedDormBuildingTree(DormBuildingTreeBo bo) { + List treeData = xgDormBuildingTreeService.getAllSimplifiedDormBuildingTree(bo); + return R.ok(treeData); + } + } diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgDormHygieneCheck.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgDormHygieneCheck.java index 87fa3502..e80ba06a 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgDormHygieneCheck.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgDormHygieneCheck.java @@ -111,7 +111,7 @@ public class XgDormHygieneCheck extends TenantEntity { private String campusName; /** - * 宿舍总分(0-100分) + * 宿舍扣分(0-100分) */ private Double totalScore; diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgDormHygieneStudentScore.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgDormHygieneStudentScore.java index 4bfc2c15..57c02d0d 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgDormHygieneStudentScore.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgDormHygieneStudentScore.java @@ -94,7 +94,7 @@ public class XgDormHygieneStudentScore extends TenantEntity { private String bedCode; /** - * 学生个人得分(0-100分) + * 学生个人扣分(0-100分) */ private Double studentScore; diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/bo/XgDormBuildingBo.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/bo/XgDormBuildingBo.java index 499f6725..503e3944 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/bo/XgDormBuildingBo.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/bo/XgDormBuildingBo.java @@ -41,7 +41,8 @@ public class XgDormBuildingBo extends BaseEntity { /** * 所属宿舍区ID */ - @NotNull(message = "所属宿舍区ID不能为空", groups = { AddGroup.class, EditGroup.class }) + // @NotNull(message = "所属宿舍区ID不能为空", groups = { AddGroup.class, EditGroup.class + // }) // 宿舍区轻量化改造:移除必填验证 private Long areaId; /** diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/DormBuildingTreeSimplifiedVo.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/DormBuildingTreeSimplifiedVo.java new file mode 100644 index 00000000..8d9ac7f4 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/DormBuildingTreeSimplifiedVo.java @@ -0,0 +1,104 @@ +package org.dromara.xg.domain.vo; + +import java.io.Serializable; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; + +/** + * 宿舍楼树形结构简化VO + * 用于简化界面显示,只显示校区→宿舍楼的二级结构,隐藏宿舍区层级 + * + * @author wuzilong + * @date 2025-01-03 + */ +@Data +public class DormBuildingTreeSimplifiedVo implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 节点ID + */ + private Long id; + + /** + * 节点名称 + */ + private String label; + + /** + * 节点类型 (campus:校区, building:宿舍楼) + * 注意:简化版本中移除了 area:宿舍区 类型 + */ + private String type; + + /** + * 是否禁用节点(校区节点禁用点击,宿舍楼节点可点击) + */ + private Boolean disabled; + + /** + * 宿舍楼层数(仅宿舍楼节点有此字段) + */ + private Integer buildingFloors; + + /** + * 宿舍楼类型(1男生楼 2女生楼 3混合楼)(仅宿舍楼节点有此字段) + */ + private String buildingType; + + /** + * 子节点 + */ + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private List children; + + /** + * 从完整树形VO转换为简化树形VO + * 将三级结构(校区→宿舍区→宿舍楼)转换为二级结构(校区→宿舍楼) + */ + public static DormBuildingTreeSimplifiedVo fromFullTreeVo(DormBuildingTreeVo fullTreeVo) { + if (fullTreeVo == null) { + return null; + } + + DormBuildingTreeSimplifiedVo simplified = new DormBuildingTreeSimplifiedVo(); + simplified.setId(fullTreeVo.getId()); + simplified.setLabel(fullTreeVo.getLabel()); + simplified.setBuildingFloors(fullTreeVo.getBuildingFloors()); + simplified.setBuildingType(fullTreeVo.getBuildingType()); + + // 根据节点类型进行转换 + if ("campus".equals(fullTreeVo.getType())) { + // 校区节点:保持不变 + simplified.setType("campus"); + simplified.setDisabled(true); + // 处理子节点:跳过宿舍区层级,直接提取宿舍楼 + simplified.setChildren(flattenAreaChildren(fullTreeVo.getChildren())); + } else if ("building".equals(fullTreeVo.getType())) { + // 宿舍楼节点:保持不变 + simplified.setType("building"); + simplified.setDisabled(false); + } + + return simplified; + } + + /** + * 扁平化宿舍区子节点,将宿舍区下的宿舍楼直接提升为校区的子节点 + */ + private static List flattenAreaChildren(List areaNodes) { + if (areaNodes == null || areaNodes.isEmpty()) { + return null; + } + + return areaNodes.stream() + .filter(node -> "area".equals(node.getType())) // 找到宿舍区节点 + .flatMap(areaNode -> areaNode.getChildren() != null ? areaNode.getChildren().stream() + : java.util.stream.Stream.empty()) // 提取宿舍楼 + .filter(buildingNode -> "building".equals(buildingNode.getType())) // 确保是宿舍楼节点 + .map(DormBuildingTreeSimplifiedVo::fromFullTreeVo) // 转换为简化VO + .toList(); + } +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgDormBuildingSimplifiedVo.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgDormBuildingSimplifiedVo.java new file mode 100644 index 00000000..dccc0607 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgDormBuildingSimplifiedVo.java @@ -0,0 +1,103 @@ +package org.dromara.xg.domain.vo; + +import org.dromara.xg.domain.XgDormBuilding; +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 org.springframework.beans.BeanUtils; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + +/** + * 宿舍楼信息简化视图对象 xg_dorm_building + * 用于简化界面显示,隐藏宿舍区层级,直接显示校区→宿舍楼结构 + * + * @author zlwu + * @date 2025-01-03 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = XgDormBuilding.class) +public class XgDormBuildingSimplifiedVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ExcelProperty(value = "主键ID") + private Long id; + + /** + * 宿舍楼编码 + */ + @ExcelProperty(value = "宿舍楼编码") + private String buildingCode; + + /** + * 宿舍楼名称 + */ + @ExcelProperty(value = "宿舍楼名称") + private String buildingName; + + /** + * 所属校区ID + */ + @ExcelProperty(value = "所属校区ID") + private Long campusId; + + /** + * 校区名称 + */ + @ExcelProperty(value = "校区名称") + private String campusName; + + /** + * 宿舍楼类型(1男生楼 2女生楼 3混合楼) + */ + @ExcelProperty(value = "宿舍楼类型(1男生楼 2女生楼 3混合楼)", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "dorm_type") + private String buildingType; + + /** + * 宿舍楼描述 + */ + @ExcelProperty(value = "宿舍楼描述") + private String buildingDescription; + + /** + * 排序号 + */ + @ExcelProperty(value = "排序号") + private Long sortOrder; + + /** + * 总楼层数 + */ + @ExcelProperty(value = "总楼层数") + private Integer floors; + + // 基础字段 + private Long createBy; // 创建者 + private Date createTime; // 创建时间 + private Long updateBy; // 更新者 + private Date updateTime; // 更新时间 + + /** + * 从完整VO转换为简化VO + */ + public static XgDormBuildingSimplifiedVo fromFullVo(XgDormBuildingVo fullVo) { + if (fullVo == null) { + return null; + } + XgDormBuildingSimplifiedVo simplified = new XgDormBuildingSimplifiedVo(); + BeanUtils.copyProperties(fullVo, simplified); + return simplified; + } +} diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgDormHygieneCheckSimplifiedVo.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgDormHygieneCheckSimplifiedVo.java new file mode 100644 index 00000000..51b8d632 --- /dev/null +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgDormHygieneCheckSimplifiedVo.java @@ -0,0 +1,183 @@ +package org.dromara.xg.domain.vo; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.dromara.xg.domain.XgDormHygieneCheck; +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 org.springframework.beans.BeanUtils; + +import java.io.Serial; +import java.io.Serializable; + +/** + * 宿舍卫生检查简化视图对象 xg_dorm_hygiene_check + * 用于简化界面显示,隐藏宿舍区层级,直接显示校区→宿舍楼→房间结构 + * + * @author zlwu + * @date 2025-01-03 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = XgDormHygieneCheck.class) +public class XgDormHygieneCheckSimplifiedVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ExcelProperty(value = "主键ID") + private Long id; + + /** + * 删除标志(0代表存在 1代表删除) + */ + @ExcelProperty(value = "删除标志", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "0=代表存在,1=代表删除") + private Long deleted; + + /** + * 检查标题 + */ + @ExcelProperty(value = "检查标题") + private String checkTitle; + + /** + * 检查日期 + */ + @ExcelProperty(value = "检查日期") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date checkDate; + + /** + * 检查员ID,关联sys_user.id + */ + @ExcelProperty(value = "检查员ID,关联sys_user.id") + private Long checkerId; + + /** + * 检查员姓名 + */ + @ExcelProperty(value = "检查员姓名") + private String checkerName; + + /** + * 检查类型(1日常检查 2专项检查 3突击检查 4复查) + */ + @ExcelProperty(value = "检查类型", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "xg_dorm_hygiene_check_type") + private String checkType; + + /** + * 检查级别(1宿管员 2学院 3学校) + */ + @ExcelProperty(value = "检查级别", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "xg_dorm_hygiene_check_level") + private String checkLevel; + + /** + * 宿舍房间ID,关联xg_dorm_room.id + */ + @ExcelProperty(value = "宿舍房间ID,关联xg_dorm_room.id") + private Long roomId; + + /** + * 房间编号 + */ + @ExcelProperty(value = "房间编号") + private String roomCode; + + /** + * 房间名称 + */ + @ExcelProperty(value = "房间名称") + private String roomName; + + /** + * 宿舍楼ID,关联xg_dorm_building.id + */ + @ExcelProperty(value = "宿舍楼ID,关联xg_dorm_building.id") + private Long buildingId; + + /** + * 宿舍楼名称 + */ + @ExcelProperty(value = "宿舍楼名称") + private String buildingName; + + /** + * 校区ID,关联xg_dorm_campus.id + */ + @ExcelProperty(value = "校区ID,关联xg_dorm_campus.id") + private Long campusId; + + /** + * 校区名称 + */ + @ExcelProperty(value = "校区名称") + private String campusName; + + /** + * 宿舍总分(0-100分) + */ + @ExcelProperty(value = "宿舍总分", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "0=-100分") + private Double totalScore; + + /** + * 卫生等级(A优秀 B良好 C合格 D不合格) + */ + @ExcelProperty(value = "卫生等级", converter = ExcelDictConvert.class) + @ExcelDictFormat(dictType = "xg_dorm_hygiene_grade") + private String hygieneGrade; + + /** + * 附件OSS ID列表,逗号分隔 + */ + @ExcelProperty(value = "附件OSS ID列表,逗号分隔") + private String attachmentIds; + + /** + * 检查总结 + */ + @ExcelProperty(value = "检查总结") + private String checkSummary; + + /** + * 整改建议 + */ + @ExcelProperty(value = "整改建议") + private String improvementSuggestions; + + /** + * 检查备注 + */ + @ExcelProperty(value = "检查备注") + private String checkRemarks; + + // 基础字段 + private Long createBy; // 创建者 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; // 创建时间 + private Long updateBy; // 更新者 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; // 更新时间 + + /** + * 从完整VO转换为简化VO + */ + public static XgDormHygieneCheckSimplifiedVo fromFullVo(XgDormHygieneCheckVo fullVo) { + if (fullVo == null) { + return null; + } + XgDormHygieneCheckSimplifiedVo simplified = new XgDormHygieneCheckSimplifiedVo(); + BeanUtils.copyProperties(fullVo, simplified); + return simplified; + } +} 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 bc972308..92c7523c 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 @@ -107,7 +107,7 @@ public interface IXgDormBedStudentService { /** * 获取当前用户二级学院的宿舍楼树形结构 - * 校区-宿舍区-宿舍楼三级结构,校区和宿舍区不可选,只有宿舍楼可以选择 + * 校区-宿舍楼二级结构,校区不可选,只有宿舍楼可以选择 * * @return 宿舍楼树形结构数据 */ diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgDormBuildingService.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgDormBuildingService.java index d15bdb61..d1203a18 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgDormBuildingService.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgDormBuildingService.java @@ -1,6 +1,7 @@ package org.dromara.xg.service; import org.dromara.xg.domain.vo.XgDormBuildingVo; +import org.dromara.xg.domain.vo.XgDormBuildingSimplifiedVo; import org.dromara.xg.domain.bo.XgDormBuildingBo; import org.dromara.xg.domain.vo.BuildingTreeSelectVo; import org.dromara.common.mybatis.core.page.TableDataInfo; @@ -74,4 +75,23 @@ public interface IXgDormBuildingService { * @return 树形结构数据 */ List getBuildingTreeData(); + + /** + * 分页查询宿舍楼信息简化列表 + * 用于简化界面显示,隐藏宿舍区层级,直接显示校区→宿舍楼结构 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 宿舍楼信息简化分页列表 + */ + TableDataInfo querySimplifiedPageList(XgDormBuildingBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的宿舍楼信息简化列表 + * 用于简化界面显示,隐藏宿舍区层级,直接显示校区→宿舍楼结构 + * + * @param bo 查询条件 + * @return 宿舍楼信息简化列表 + */ + List querySimplifiedList(XgDormBuildingBo bo); } diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgDormBuildingTreeService.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgDormBuildingTreeService.java index 8aea57c5..8f7c86ce 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgDormBuildingTreeService.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/IXgDormBuildingTreeService.java @@ -2,6 +2,7 @@ package org.dromara.xg.service; import java.util.List; import org.dromara.xg.domain.vo.DormBuildingTreeVo; +import org.dromara.xg.domain.vo.DormBuildingTreeSimplifiedVo; import org.dromara.xg.domain.bo.DormBuildingTreeBo; /** @@ -28,4 +29,22 @@ public interface IXgDormBuildingTreeService { */ List getAllDormBuildingTree(DormBuildingTreeBo bo); + /** + * 获取宿舍楼树形结构简化数据 + * 校区-宿舍楼二级结构,隐藏宿舍区层级 + * + * @param bo 查询参数 + * @return 简化树形结构数据 + */ + List getSimplifiedDormBuildingTree(DormBuildingTreeBo bo); + + /** + * 获取所有宿舍楼树形结构简化数据(不考虑权限) + * 校区-宿舍楼二级结构,隐藏宿舍区层级 + * + * @param bo 查询参数 + * @return 简化树形结构数据 + */ + List getAllSimplifiedDormBuildingTree(DormBuildingTreeBo bo); + } 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 232f1775..fa0226b2 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 @@ -983,7 +983,8 @@ public class XgDormBedStudentServiceImpl implements IXgDormBedStudentService { Long roomId = entry.getKey(); List roomUnallocatedBeds = entry.getValue(); String roomCode = roomCodeMap.get(roomId); - log.error("房间{}({})有{}个床位未分配:{}", roomCode, roomId, roomUnallocatedBeds.size(), roomUnallocatedBeds); + log.error("房间{}({})有{}个床位未分配:{}", roomCode, roomId, roomUnallocatedBeds.size(), + roomUnallocatedBeds); } throw new RuntimeException("床位分配不完整,存在" + (totalExpectedBeds - totalAllocatedBeds) + "个床位未分配"); @@ -1008,7 +1009,7 @@ public class XgDormBedStudentServiceImpl implements IXgDormBedStudentService { /** * 获取当前用户二级学院的宿舍楼树形结构 - * 校区-宿舍区-宿舍楼三级结构,校区和宿舍区不可选,只有宿舍楼可以选择 + * 校区-宿舍楼二级结构,校区不可选,只有宿舍楼可以选择 * * @return 宿舍楼树形结构数据 */ @@ -1159,8 +1160,8 @@ public class XgDormBedStudentServiceImpl implements IXgDormBedStudentService { .orderByAsc(XgDormCampus::getSortOrder, XgDormCampus::getId); List campuses = xgDormCampusMapper.selectList(campusWrapper); - // 构建树形结构 - return buildTreeStructure(campuses, areas, buildings); + // 构建简化版树形结构(校区-宿舍楼,去除宿舍区层级) + return buildSimplifiedTreeStructure(campuses, areas, buildings); } catch (Exception e) { log.error("构建宿舍楼树形结构失败", e); @@ -1232,6 +1233,60 @@ public class XgDormBedStudentServiceImpl implements IXgDormBedStudentService { return new ArrayList<>(campusMap.values()); } + /** + * 构建简化树形结构:校区-宿舍楼(去除宿舍区层级) + */ + private List buildSimplifiedTreeStructure(List campuses, + List areas, + List buildings) { + + // 构建校区节点(第一层) + Map campusMap = new LinkedHashMap<>(); + for (XgDormCampus campus : campuses) { + // 检查该校区下是否有宿舍楼(通过宿舍区关联) + boolean hasBuildings = buildings.stream().anyMatch(building -> areas.stream().anyMatch( + area -> area.getId().equals(building.getAreaId()) && area.getCampusId().equals(campus.getId()))); + + if (hasBuildings) { + DormBuildingTreeVo campusNode = new DormBuildingTreeVo(); + campusNode.setId(campus.getId()); + campusNode.setLabel(campus.getCampusName()); + campusNode.setType("campus"); + campusNode.setDisabled(true); // 校区节点禁止点击 + campusNode.setChildren(new ArrayList<>()); + campusMap.put(campus.getId(), campusNode); + } + } + + // 直接构建宿舍楼节点(第二层),跳过宿舍区 + for (XgDormBuilding building : buildings) { + // 通过宿舍区找到对应的校区 + XgDormArea area = areas.stream() + .filter(a -> a.getId().equals(building.getAreaId())) + .findFirst() + .orElse(null); + + if (area != null) { + DormBuildingTreeVo buildingNode = new DormBuildingTreeVo(); + buildingNode.setId(building.getId()); + buildingNode.setLabel(building.getBuildingName()); + buildingNode.setType("building"); + buildingNode.setDisabled(false); // 宿舍楼节点可以点击 + buildingNode.setBuildingFloors(building.getFloors()); + buildingNode.setBuildingType(building.getBuildingType()); + buildingNode.setChildren(new ArrayList<>()); + + // 直接添加到校区下,跳过宿舍区层级 + DormBuildingTreeVo campusNode = campusMap.get(area.getCampusId()); + if (campusNode != null) { + campusNode.getChildren().add(buildingNode); + } + } + } + + return new ArrayList<>(campusMap.values()); + } + /** * 获取班主任管理的班级宿舍楼树 * 通过当前用户所在的班级,获取该班级分配的宿舍楼 diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormBuildingServiceImpl.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormBuildingServiceImpl.java index 3cca3511..07d9e674 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormBuildingServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormBuildingServiceImpl.java @@ -12,6 +12,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.dromara.xg.domain.bo.XgDormBuildingBo; import org.dromara.xg.domain.vo.XgDormBuildingVo; +import org.dromara.xg.domain.vo.XgDormBuildingSimplifiedVo; import org.dromara.xg.domain.XgDormBuilding; import org.dromara.xg.domain.XgDormArea; import org.dromara.xg.domain.XgDormCampus; @@ -145,7 +146,7 @@ public class XgDormBuildingServiceImpl implements IXgDormBuildingService { /** * 获取宿舍楼树形结构数据 - * 校区-宿舍区-宿舍楼三级结构,校区和宿舍区不可选,只有宿舍楼可以选择 + * 校区-宿舍楼二级结构,校区不可选,只有宿舍楼可以选择 * * @return 宿舍楼树形结构数据 */ @@ -156,59 +157,41 @@ public class XgDormBuildingServiceImpl implements IXgDormBuildingService { Wrappers.lambdaQuery() .orderByAsc(XgDormCampus::getSortOrder, XgDormCampus::getId)); - // 2. 获取所有宿舍区数据 - List areaList = areaMapper.selectList( - Wrappers.lambdaQuery() - .orderByAsc(XgDormArea::getSortOrder, XgDormArea::getId)); - - // 3. 获取所有宿舍楼数据 + // 2. 获取所有宿舍楼数据 List buildingList = baseMapper.selectList( Wrappers.lambdaQuery() .orderByAsc(XgDormBuilding::getSortOrder, XgDormBuilding::getId)); - // 4. 构建树形结构 + // 3. 构建树形结构 List treeList = new ArrayList<>(); - // 5. 先构建校区节点 + // 4. 先构建校区节点 for (XgDormCampus campus : campusList) { - BuildingTreeSelectVo campusNode = new BuildingTreeSelectVo(); - campusNode.setId(campus.getId()); - campusNode.setLabel(campus.getCampusName()); - campusNode.setNodeType("campus"); - campusNode.setDisabled(true); // 校区不可选 - campusNode.setChildren(new ArrayList<>()); - - // 设置创建者和更新者字段 - campusNode.setCreateBy(campus.getCreateBy()); - campusNode.setCreateTime(campus.getCreateTime()); - campusNode.setUpdateBy(campus.getUpdateBy()); - campusNode.setUpdateTime(campus.getUpdateTime()); - - // 添加该校区下的宿舍区 - List campusAreas = areaList.stream() - .filter(area -> area.getCampusId().equals(campus.getId())) + // 检查该校区下是否有宿舍楼 + List campusBuildings = buildingList.stream() + .filter(building -> { + // 通过宿舍区找到校区 + XgDormArea area = areaMapper.selectById(building.getAreaId()); + return area != null && area.getCampusId().equals(campus.getId()); + }) .collect(Collectors.toList()); - for (XgDormArea area : campusAreas) { - BuildingTreeSelectVo areaNode = new BuildingTreeSelectVo(); - areaNode.setId(area.getId()); - areaNode.setLabel(area.getAreaName()); - areaNode.setNodeType("area"); - areaNode.setDisabled(true); // 宿舍区不可选 - areaNode.setChildren(new ArrayList<>()); + if (!campusBuildings.isEmpty()) { + BuildingTreeSelectVo campusNode = new BuildingTreeSelectVo(); + campusNode.setId(campus.getId()); + campusNode.setLabel(campus.getCampusName()); + campusNode.setNodeType("campus"); + campusNode.setDisabled(true); // 校区不可选 + campusNode.setChildren(new ArrayList<>()); // 设置创建者和更新者字段 - areaNode.setCreateBy(area.getCreateBy()); - areaNode.setCreateTime(area.getCreateTime()); - areaNode.setUpdateBy(area.getUpdateBy()); - areaNode.setUpdateTime(area.getUpdateTime()); + campusNode.setCreateBy(campus.getCreateBy()); + campusNode.setCreateTime(campus.getCreateTime()); + campusNode.setUpdateBy(campus.getUpdateBy()); + campusNode.setUpdateTime(campus.getUpdateTime()); - // 添加该宿舍区下的宿舍楼 - List areaBuildings = buildingList.stream() - .filter(building -> building.getAreaId().equals(area.getId())) - .collect(Collectors.toList()); - - for (XgDormBuilding building : areaBuildings) { + // 直接添加该校区下的宿舍楼,跳过宿舍区层级 + for (XgDormBuilding building : campusBuildings) { BuildingTreeSelectVo buildingNode = new BuildingTreeSelectVo(); buildingNode.setId(building.getId()); buildingNode.setLabel(building.getBuildingName()); @@ -222,15 +205,57 @@ public class XgDormBuildingServiceImpl implements IXgDormBuildingService { buildingNode.setUpdateBy(building.getUpdateBy()); buildingNode.setUpdateTime(building.getUpdateTime()); - areaNode.getChildren().add(buildingNode); + campusNode.getChildren().add(buildingNode); } - campusNode.getChildren().add(areaNode); + treeList.add(campusNode); } - - treeList.add(campusNode); } return treeList; } + + /** + * 分页查询宿舍楼信息简化列表 + * 用于简化界面显示,隐藏宿舍区层级,直接显示校区→宿舍楼结构 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 宿舍楼信息简化分页列表 + */ + @Override + public TableDataInfo querySimplifiedPageList(XgDormBuildingBo bo, PageQuery pageQuery) { + // 先查询完整的分页数据 + TableDataInfo fullPageList = queryPageList(bo, pageQuery); + + // 转换为简化版VO + List simplifiedList = fullPageList.getRows().stream() + .map(XgDormBuildingSimplifiedVo::fromFullVo) + .collect(Collectors.toList()); + + // 创建简化版分页结果 + TableDataInfo simplifiedPageList = new TableDataInfo<>(); + simplifiedPageList.setRows(simplifiedList); + simplifiedPageList.setTotal(fullPageList.getTotal()); + + return simplifiedPageList; + } + + /** + * 查询符合条件的宿舍楼信息简化列表 + * 用于简化界面显示,隐藏宿舍区层级,直接显示校区→宿舍楼结构 + * + * @param bo 查询条件 + * @return 宿舍楼信息简化列表 + */ + @Override + public List querySimplifiedList(XgDormBuildingBo bo) { + // 先查询完整的数据 + List fullList = queryList(bo); + + // 转换为简化版VO + return fullList.stream() + .map(XgDormBuildingSimplifiedVo::fromFullVo) + .collect(Collectors.toList()); + } } diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormBuildingTreeServiceImpl.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormBuildingTreeServiceImpl.java index 46cd2244..c96263fb 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormBuildingTreeServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormBuildingTreeServiceImpl.java @@ -8,6 +8,7 @@ import lombok.RequiredArgsConstructor; import org.dromara.xg.service.IXgDormBuildingTreeService; import org.dromara.xg.mapper.XgDormBuildingTreeMapper; import org.dromara.xg.domain.vo.DormBuildingTreeVo; +import org.dromara.xg.domain.vo.DormBuildingTreeSimplifiedVo; import org.dromara.xg.domain.vo.DormBuildingInfoVo; import org.dromara.xg.domain.bo.DormBuildingTreeBo; import org.dromara.common.satoken.utils.LoginHelper; @@ -231,4 +232,42 @@ public class XgDormBuildingTreeServiceImpl implements IXgDormBuildingTreeService return new ArrayList<>(campusMap.values()); } + /** + * 获取宿舍楼树形结构简化数据 + * 校区-宿舍楼二级结构,隐藏宿舍区层级 + * + * @param bo 查询参数 + * @return 简化树形结构数据 + */ + @Override + public List getSimplifiedDormBuildingTree(DormBuildingTreeBo bo) { + // 先获取完整的树形结构数据 + List fullTreeData = getDormBuildingTree(bo); + + // 转换为简化版树形结构 + return fullTreeData.stream() + .map(DormBuildingTreeSimplifiedVo::fromFullTreeVo) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + + /** + * 获取所有宿舍楼树形结构简化数据(不考虑权限) + * 校区-宿舍楼二级结构,隐藏宿舍区层级 + * + * @param bo 查询参数 + * @return 简化树形结构数据 + */ + @Override + public List getAllSimplifiedDormBuildingTree(DormBuildingTreeBo bo) { + // 先获取完整的树形结构数据(不考虑权限) + List fullTreeData = getAllDormBuildingTree(bo); + + // 转换为简化版树形结构 + return fullTreeData.stream() + .map(DormBuildingTreeSimplifiedVo::fromFullTreeVo) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + } diff --git a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormRoomServiceImpl.java b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormRoomServiceImpl.java index 81a5ab8e..e254bb53 100644 --- a/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormRoomServiceImpl.java +++ b/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormRoomServiceImpl.java @@ -144,8 +144,8 @@ public class XgDormRoomServiceImpl implements IXgDormRoomService { private LambdaQueryWrapper buildQueryWrapper(XgDormRoomBo bo) { Map params = bo.getParams(); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.orderByAsc(XgDormRoom::getSort); // 第一优先级:按排序号升序 - lqw.orderByAsc(XgDormRoom::getFloorNum); // 第二优先级:按楼层升序 + lqw.orderByAsc(XgDormRoom::getFloorNum); // 第一优先级:按楼层升序 + lqw.orderByAsc(XgDormRoom::getSort); // 第二优先级:按排序号升序 lqw.orderByAsc(XgDormRoom::getRoomName); // 第三优先级:按房间名称升序 lqw.like(StringUtils.isNotBlank(bo.getRoomCode()), XgDormRoom::getRoomCode, bo.getRoomCode()); lqw.like(StringUtils.isNotBlank(bo.getRoomName()), XgDormRoom::getRoomName, bo.getRoomName()); diff --git a/docs/开发文档/API/宿舍卫生检查管理API.md b/docs/开发文档/API/宿舍卫生检查管理API.md index a3ae778d..15961142 100644 --- a/docs/开发文档/API/宿舍卫生检查管理API.md +++ b/docs/开发文档/API/宿舍卫生检查管理API.md @@ -333,4 +333,83 @@ public interface DormHygieneStudentScoreMapper extends BaseMapperPlus { + // 验证宿舍总分范围 + if (form.totalScore !== null && form.totalScore !== undefined && form.totalScore !== '') { + // 处理非0分情况 + const score = parseFloat(form.totalScore.toString()); + if (isNaN(score) || score < 0 || score > 100) { + ElMessage.warning('宿舍总分必须在0-100分之间'); + form.totalScore = 0; + return; + } + // 自动为所有学生设置相同的个人得分(包括0分) + if (roomStudents.value.length > 0) { + roomStudents.value.forEach((student: any) => { + student.student_score = score; + }); + ElMessage.success(`已自动为${roomStudents.value.length}名学生设置个人得分:${score}分`); + } + } else if (form.totalScore === 0 || form.totalScore === '0') { + // 特别处理0分的情况 + if (roomStudents.value.length > 0) { + roomStudents.value.forEach((student: any) => { + student.student_score = 0; + }); + ElMessage.success(`已自动为${roomStudents.value.length}名学生设置个人得分:0分`); + } + } +}; +``` + +#### 修复问题三:房间排序问题 +**问题现象:** 选择宿舍楼名称后,房间名称按照sort序号进行排序返回,但因为每层房间的sort都从0开始编码,导致返回数据把每个楼层的第一个房间先返回。 + +**解决方案:** 修改后端`XgDormRoomServiceImpl.java`中的`buildQueryWrapper`方法,调整排序逻辑为先按楼层再按sort排序。 + +```java +// 修改前 +lqw.orderByAsc(XgDormRoom::getSort); // 第一优先级:按排序号升序 +lqw.orderByAsc(XgDormRoom::getFloorNum); // 第二优先级:按楼层升序 + +// 修改后 +lqw.orderByAsc(XgDormRoom::getFloorNum); // 第一优先级:按楼层升序 +lqw.orderByAsc(XgDormRoom::getSort); // 第二优先级:按排序号升序 +``` + +#### 修复效果 +1. **问题一**:新增时个人扣分直接显示0,用户体验更好 +2. **问题二**:宿舍扣分与个人扣分完全同步,包括0分的情况 +3. **问题三**:房间列表按楼层顺序显示,每层内部按sort排序,符合用户期望 + +#### 涉及文件 +- `web/src/views/xg/xgss/dormHygieneCheck/dormHygieneCheck/DormHygieneCheckDialog.vue` +- `backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgDormRoomServiceImpl.java` \ No newline at end of file diff --git a/docs/开发文档/API/宿舍楼树形结构API.md b/docs/开发文档/API/宿舍楼树形结构API.md index 3a2384a1..de43ee96 100644 --- a/docs/开发文档/API/宿舍楼树形结构API.md +++ b/docs/开发文档/API/宿舍楼树形结构API.md @@ -2,11 +2,13 @@ ## 接口说明 -本文档描述了获取宿舍楼树形结构数据的API接口,该接口返回校区-宿舍区-宿舍楼的三级树形结构,其中校区和宿舍区节点不可选,只有宿舍楼节点可以选择。 +本文档描述了获取宿舍楼树形结构数据的API接口。**重要变更**:根据业务需求调整,主要接口已从 "校区-宿舍区-宿舍楼" 三级结构改为 "校区-宿舍楼" 二级结构,隐藏宿舍区层级,简化用户操作。 ## 接口定义 -### 获取宿舍楼树形结构 +### 🔄 主要接口(二级结构) + +#### 1. 获取宿舍楼树形结构(推荐使用) **请求URL**:`/sslxx/dormBuilding/buildingTree` @@ -14,6 +16,8 @@ **权限标识**:`sslxx:dormBuilding:list` +**结构说明**:校区-宿舍楼二级结构,校区不可选,只有宿舍楼可以选择 + **请求参数**:无 **响应示例**: @@ -30,24 +34,16 @@ "disabled": true, "children": [ { - "id": 101, - "label": "东区宿舍区", - "nodeType": "area", - "disabled": true, - "children": [ - { - "id": 1001, - "label": "1号楼", - "nodeType": "building", - "disabled": false - }, - { - "id": 1002, - "label": "2号楼", - "nodeType": "building", - "disabled": false - } - ] + "id": 1001, + "label": "1号楼", + "nodeType": "building", + "disabled": false + }, + { + "id": 1002, + "label": "2号楼", + "nodeType": "building", + "disabled": false } ] }, @@ -58,22 +54,92 @@ "disabled": true, "children": [ { - "id": 201, - "label": "西区宿舍区", - "nodeType": "area", + "id": 2001, + "label": "3号楼", + "nodeType": "building", + "disabled": false + }, + { + "id": 2002, + "label": "4号楼", + "nodeType": "building", + "disabled": false + } + ] + } + ] +} +``` + +#### 2. 获取宿舍楼树形结构(基于权限) + +**请求URL**:`/xgss/dormBuildingTree/list` + +**请求方式**:`GET` + +**权限标识**:`xgss:dormBuildingTree:list` + +**结构说明**:校区-宿舍楼二级结构,根据当前用户权限过滤 + +**请求参数**: + +| 参数名 | 类型 | 必填 | 描述 | +|-----------|--------|------|----------------| +| campusId | Long | 否 | 校区ID过滤条件 | +| buildingName | String | 否 | 宿舍楼名称过滤条件 | + +**响应格式**:与上述接口相同 + +#### 3. 获取所有宿舍楼树形结构(不考虑权限) + +**请求URL**:`/xgss/dormBuildingTree/listAll` + +**请求方式**:`GET` + +**权限标识**:`xgss:dormBuildingTree:list` + +**结构说明**:校区-宿舍楼二级结构,返回所有数据,不进行权限过滤 + +**响应格式**:与上述接口相同 + +### 📋 特殊用途接口(三级结构) + +#### 4. 获取完整宿舍楼树形结构(包含宿舍区) + +**请求URL**:`/xgss/dormBuildingTree/fullList` + +**请求方式**:`GET` + +**权限标识**:`xgss:dormBuildingTree:list` + +**结构说明**:校区-宿舍区-宿舍楼三级结构,仅用于特殊需求 + +**响应示例**: + +```json +{ + "code": 200, + "msg": "操作成功", + "data": [ + { + "id": 1, + "label": "东校区", + "type": "campus", + "disabled": true, + "children": [ + { + "id": 101, + "label": "东区宿舍区", + "type": "area", "disabled": true, "children": [ { - "id": 2001, - "label": "3号楼", - "nodeType": "building", - "disabled": false - }, - { - "id": 2002, - "label": "4号楼", - "nodeType": "building", - "disabled": false + "id": 1001, + "label": "1号楼", + "type": "building", + "disabled": false, + "buildingFloors": 6, + "buildingType": "1" } ] } @@ -85,7 +151,7 @@ ## 数据结构 -### BuildingTreeSelectVo +### BuildingTreeSelectVo(二级结构) 树形结构节点对象: @@ -93,7 +159,7 @@ |------------|-------------------|----------------------------------------| | id | Long | 节点ID | | label | String | 节点名称 | -| nodeType | String | 节点类型:campus(校区)、area(宿舍区)、building(宿舍楼) | +| nodeType | String | 节点类型:campus(校区)、building(宿舍楼) | | disabled | Boolean | 是否禁用选择 | | children | List | 子节点列表 | | createBy | Long | 创建者 | @@ -101,6 +167,20 @@ | updateBy | Long | 更新者 | | updateTime | Date | 更新时间 | +### DormBuildingTreeVo(完整结构) + +完整三级结构节点对象: + +| 字段名 | 类型 | 描述 | +|-----------------|-------------------|----------------------------------------| +| id | Long | 节点ID | +| label | String | 节点名称 | +| type | String | 节点类型:campus(校区)、area(宿舍区)、building(宿舍楼) | +| disabled | Boolean | 是否禁用选择 | +| children | List | 子节点列表 | +| buildingFloors | Integer | 宿舍楼层数(仅宿舍楼节点) | +| buildingType | String | 宿舍楼类型(仅宿舍楼节点) | + ## 使用方法 ### 前端使用示例 @@ -114,7 +194,7 @@ import type { BuildingTreeSelectVo } from '@/api/sslxx/dormBuilding/types'; // 在组件的setup函数中 const treeData = ref([]); -// 加载宿舍楼树形数据 +// 加载宿舍楼树形数据(推荐使用二级结构) const loadBuildingTree = async () => { try { const res = await getBuildingTree(); @@ -155,20 +235,34 @@ loadBuildingTree(); ## 特殊说明 -1. 接口返回的树形结构中,校区和宿舍区节点已设置 `disabled=true`,前端无需额外处理即可实现只能选择宿舍楼节点的效果 -2. 使用 `check-strictly=true` 可以确保树形选择器的选中状态不会级联影响父子节点 -3. 该接口已支持管理员分配宿舍楼管理范围的业务需求 +### ⚠️ 重要变更说明 + +1. **主要接口结构调整**:为简化用户操作,去除宿舍区概念,主要接口已改为二级结构 +2. **向后兼容**:保留了 `fullList` 接口供需要完整三级结构的特殊场景使用 +3. **业务影响**:前端界面将不再显示宿舍区层级,用户直接在校区下选择宿舍楼 + +### 📋 使用建议 + +1. **推荐使用二级结构接口**:适用于绝大多数业务场景 +2. **校区节点设置为不可选**:确保用户只能选择宿舍楼 +3. **使用权限过滤接口**:根据用户权限显示相应的宿舍楼范围 ## 相关API接口 - [宿舍管理员授权API](./宿舍管理员授权API.md) +- [宿舍床位分配管理API](./宿舍床位分配管理API.md) ## 数据库关系 - `xg_dorm_building` 表通过 `campus_id` 字段关联 `xg_dorm_campus` 表 -- `xg_dorm_building` 表通过 `area_id` 字段关联 `xg_dorm_area` 表 +- `xg_dorm_building` 表通过 `area_id` 字段关联 `xg_dorm_area` 表(数据库保留,UI隐藏) - `xg_dorm_area` 表通过 `campus_id` 字段关联 `xg_dorm_campus` 表 +## 版本历史 + +- **2025-01-29**: 接口结构重大调整,主要接口从三级改为二级结构 +- **2025-07-20**: 初始版本,三级结构 + ## 最后更新时间 -2025-07-20 \ No newline at end of file +2025-01-29 \ No newline at end of file diff --git a/docs/设计文档/database/hzdyjs_xg0820.sql b/docs/设计文档/database/hzdyjs_xg0820.sql index 052f60d3..f8fa8b63 100644 --- a/docs/设计文档/database/hzdyjs_xg0820.sql +++ b/docs/设计文档/database/hzdyjs_xg0820.sql @@ -4376,7 +4376,7 @@ CREATE TABLE `xg_dorm_hygiene_check` ( `area_name` varchar(100) DEFAULT NULL COMMENT '宿舍区名称', `campus_id` bigint(20) DEFAULT NULL COMMENT '校区ID,关联xg_dorm_campus.id', `campus_name` varchar(100) DEFAULT NULL COMMENT '校区名称', - `total_score` decimal(5,2) DEFAULT NULL COMMENT '宿舍总分(0-100分)', + `total_score` decimal(5,2) DEFAULT NULL COMMENT '宿舍扣分(0-100分)', `hygiene_grade` char(1) DEFAULT NULL COMMENT '卫生等级(A优秀 B良好 C合格 D不合格)', `attachment_ids` text COMMENT '附件OSS ID列表,逗号分隔', `check_summary` text COMMENT '检查总结', @@ -4422,7 +4422,7 @@ CREATE TABLE `xg_dorm_hygiene_student_score` ( `college_name` varchar(100) DEFAULT NULL COMMENT '学院名称', `bed_id` bigint(20) DEFAULT NULL COMMENT '床位ID,关联xg_dorm_bed.id', `bed_code` varchar(50) DEFAULT NULL COMMENT '床位编号', - `student_score` decimal(5,2) DEFAULT NULL COMMENT '学生个人得分(0-100分)', + `student_score` decimal(5,2) DEFAULT NULL COMMENT '学生个人扣分(0-100分)', `attendance_status` char(1) DEFAULT '1' COMMENT '出勤状态(1在寝 2外出 3请假 4其他)', `student_grade` char(1) DEFAULT NULL COMMENT '学生评级(A优秀 B良好 C合格 D不合格)', `is_responsible_person` tinyint(1) DEFAULT '0' COMMENT '是否为寝室长(0否 1是)', diff --git a/web/src/views/xg/xgss/dormHygieneCheck/dormHygieneCheck/DormHygieneCheckDialog.vue b/web/src/views/xg/xgss/dormHygieneCheck/dormHygieneCheck/DormHygieneCheckDialog.vue index 9a8d40f6..e03d4962 100644 --- a/web/src/views/xg/xgss/dormHygieneCheck/dormHygieneCheck/DormHygieneCheckDialog.vue +++ b/web/src/views/xg/xgss/dormHygieneCheck/dormHygieneCheck/DormHygieneCheckDialog.vue @@ -1,7 +1,7 @@