提交宿舍区去除的业务修改
This commit is contained in:
1 parent
99b771bb51
commit
2a38245ae2
24 files changed
+1139
-557
No files matched your search
+2
-2
@@ -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")
|
||||
|
||||
+23
-1
@@ -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<BuildingTreeSelectVo> treeData = xgDormBuildingService.getBuildingTreeData();
|
||||
return R.ok(treeData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询宿舍楼信息简化列表
|
||||
* 用于简化界面显示,隐藏宿舍区层级,直接显示校区→宿舍楼结构
|
||||
*/
|
||||
@SaCheckPermission("sslxx:dormBuilding:list")
|
||||
@GetMapping("/simplifiedList")
|
||||
public TableDataInfo<XgDormBuildingSimplifiedVo> getSimplifiedList(XgDormBuildingBo bo, PageQuery pageQuery) {
|
||||
return xgDormBuildingService.querySimplifiedPageList(bo, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询宿舍楼信息简化列表(不分页)
|
||||
* 用于下拉选择等场景
|
||||
*/
|
||||
@SaCheckPermission("sslxx:dormBuilding:list")
|
||||
@GetMapping("/simplifiedListAll")
|
||||
public R<List<XgDormBuildingSimplifiedVo>> getSimplifiedListAll(XgDormBuildingBo bo) {
|
||||
List<XgDormBuildingSimplifiedVo> list = xgDormBuildingService.querySimplifiedList(bo);
|
||||
return R.ok(list);
|
||||
}
|
||||
}
|
||||
+52
-5
@@ -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<List<DormBuildingTreeVo>> getDormBuildingTree(DormBuildingTreeBo bo) {
|
||||
List<DormBuildingTreeVo> treeData = xgDormBuildingTreeService.getDormBuildingTree(bo);
|
||||
public R<List<DormBuildingTreeSimplifiedVo>> getDormBuildingTree(DormBuildingTreeBo bo) {
|
||||
List<DormBuildingTreeSimplifiedVo> treeData = xgDormBuildingTreeService.getSimplifiedDormBuildingTree(bo);
|
||||
return R.ok(treeData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有宿舍楼树形结构数据(不考虑权限)
|
||||
* 校区-宿舍区-宿舍楼三级结构,校区和宿舍区不可选,只有宿舍楼可以选择
|
||||
* 校区-宿舍楼二级结构,校区不可选,只有宿舍楼可以选择
|
||||
*/
|
||||
@SaCheckPermission("xgss:dormBuildingTree:list")
|
||||
@GetMapping("/listAll")
|
||||
public R<List<DormBuildingTreeVo>> getAllDormBuildingTree(DormBuildingTreeBo bo) {
|
||||
public R<List<DormBuildingTreeSimplifiedVo>> getAllDormBuildingTree(DormBuildingTreeBo bo) {
|
||||
List<DormBuildingTreeSimplifiedVo> treeData = xgDormBuildingTreeService.getAllSimplifiedDormBuildingTree(bo);
|
||||
return R.ok(treeData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取宿舍楼树形结构完整数据(包含宿舍区层级)
|
||||
* 校区-宿舍区-宿舍楼三级结构,校区和宿舍区不可选,只有宿舍楼可以选择
|
||||
* 注意:此接口仅用于特殊需求,一般情况请使用/list接口
|
||||
*/
|
||||
@SaCheckPermission("xgss:dormBuildingTree:list")
|
||||
@GetMapping("/fullList")
|
||||
public R<List<DormBuildingTreeVo>> getFullDormBuildingTree(DormBuildingTreeBo bo) {
|
||||
List<DormBuildingTreeVo> treeData = xgDormBuildingTreeService.getDormBuildingTree(bo);
|
||||
return R.ok(treeData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有宿舍楼树形结构完整数据(不考虑权限,包含宿舍区层级)
|
||||
* 校区-宿舍区-宿舍楼三级结构,校区和宿舍区不可选,只有宿舍楼可以选择
|
||||
* 注意:此接口仅用于特殊需求,一般情况请使用/listAll接口
|
||||
*/
|
||||
@SaCheckPermission("xgss:dormBuildingTree:list")
|
||||
@GetMapping("/fullListAll")
|
||||
public R<List<DormBuildingTreeVo>> getAllFullDormBuildingTree(DormBuildingTreeBo bo) {
|
||||
List<DormBuildingTreeVo> treeData = xgDormBuildingTreeService.getAllDormBuildingTree(bo);
|
||||
return R.ok(treeData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取宿舍楼树形结构简化数据
|
||||
* 校区-宿舍楼二级结构,隐藏宿舍区层级,校区不可选,只有宿舍楼可以选择
|
||||
*/
|
||||
@SaCheckPermission("xgss:dormBuildingTree:list")
|
||||
@GetMapping("/simplifiedList")
|
||||
public R<List<DormBuildingTreeSimplifiedVo>> getSimplifiedDormBuildingTree(DormBuildingTreeBo bo) {
|
||||
List<DormBuildingTreeSimplifiedVo> treeData = xgDormBuildingTreeService.getSimplifiedDormBuildingTree(bo);
|
||||
return R.ok(treeData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有宿舍楼树形结构简化数据(不考虑权限)
|
||||
* 校区-宿舍楼二级结构,隐藏宿舍区层级,校区不可选,只有宿舍楼可以选择
|
||||
*/
|
||||
@SaCheckPermission("xgss:dormBuildingTree:list")
|
||||
@GetMapping("/simplifiedListAll")
|
||||
public R<List<DormBuildingTreeSimplifiedVo>> getAllSimplifiedDormBuildingTree(DormBuildingTreeBo bo) {
|
||||
List<DormBuildingTreeSimplifiedVo> treeData = xgDormBuildingTreeService.getAllSimplifiedDormBuildingTree(bo);
|
||||
return R.ok(treeData);
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -111,7 +111,7 @@ public class XgDormHygieneCheck extends TenantEntity {
|
||||
private String campusName;
|
||||
|
||||
/**
|
||||
* 宿舍总分(0-100分)
|
||||
* 宿舍扣分(0-100分)
|
||||
*/
|
||||
private Double totalScore;
|
||||
|
||||
|
||||
+1
-1
@@ -94,7 +94,7 @@ public class XgDormHygieneStudentScore extends TenantEntity {
|
||||
private String bedCode;
|
||||
|
||||
/**
|
||||
* 学生个人得分(0-100分)
|
||||
* 学生个人扣分(0-100分)
|
||||
*/
|
||||
private Double studentScore;
|
||||
|
||||
|
||||
+2
-1
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
+104
@@ -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<DormBuildingTreeSimplifiedVo> 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<DormBuildingTreeSimplifiedVo> flattenAreaChildren(List<DormBuildingTreeVo> 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();
|
||||
}
|
||||
}
|
||||
+103
@@ -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;
|
||||
}
|
||||
}
|
||||
+183
@@ -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;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -107,7 +107,7 @@ public interface IXgDormBedStudentService {
|
||||
|
||||
/**
|
||||
* 获取当前用户二级学院的宿舍楼树形结构
|
||||
* 校区-宿舍区-宿舍楼三级结构,校区和宿舍区不可选,只有宿舍楼可以选择
|
||||
* 校区-宿舍楼二级结构,校区不可选,只有宿舍楼可以选择
|
||||
*
|
||||
* @return 宿舍楼树形结构数据
|
||||
*/
|
||||
|
||||
+20
@@ -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<BuildingTreeSelectVo> getBuildingTreeData();
|
||||
|
||||
/**
|
||||
* 分页查询宿舍楼信息简化列表
|
||||
* 用于简化界面显示,隐藏宿舍区层级,直接显示校区→宿舍楼结构
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @param pageQuery 分页参数
|
||||
* @return 宿舍楼信息简化分页列表
|
||||
*/
|
||||
TableDataInfo<XgDormBuildingSimplifiedVo> querySimplifiedPageList(XgDormBuildingBo bo, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询符合条件的宿舍楼信息简化列表
|
||||
* 用于简化界面显示,隐藏宿舍区层级,直接显示校区→宿舍楼结构
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 宿舍楼信息简化列表
|
||||
*/
|
||||
List<XgDormBuildingSimplifiedVo> querySimplifiedList(XgDormBuildingBo bo);
|
||||
}
|
||||
+19
@@ -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<DormBuildingTreeVo> getAllDormBuildingTree(DormBuildingTreeBo bo);
|
||||
|
||||
/**
|
||||
* 获取宿舍楼树形结构简化数据
|
||||
* 校区-宿舍楼二级结构,隐藏宿舍区层级
|
||||
*
|
||||
* @param bo 查询参数
|
||||
* @return 简化树形结构数据
|
||||
*/
|
||||
List<DormBuildingTreeSimplifiedVo> getSimplifiedDormBuildingTree(DormBuildingTreeBo bo);
|
||||
|
||||
/**
|
||||
* 获取所有宿舍楼树形结构简化数据(不考虑权限)
|
||||
* 校区-宿舍楼二级结构,隐藏宿舍区层级
|
||||
*
|
||||
* @param bo 查询参数
|
||||
* @return 简化树形结构数据
|
||||
*/
|
||||
List<DormBuildingTreeSimplifiedVo> getAllSimplifiedDormBuildingTree(DormBuildingTreeBo bo);
|
||||
|
||||
}
|
||||
+59
-4
@@ -983,7 +983,8 @@ public class XgDormBedStudentServiceImpl implements IXgDormBedStudentService {
|
||||
Long roomId = entry.getKey();
|
||||
List<Long> 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<XgDormCampus> 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<DormBuildingTreeVo> buildSimplifiedTreeStructure(List<XgDormCampus> campuses,
|
||||
List<XgDormArea> areas,
|
||||
List<XgDormBuilding> buildings) {
|
||||
|
||||
// 构建校区节点(第一层)
|
||||
Map<Long, DormBuildingTreeVo> 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());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取班主任管理的班级宿舍楼树
|
||||
* 通过当前用户所在的班级,获取该班级分配的宿舍楼
|
||||
|
||||
+71
-46
@@ -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.<XgDormCampus>lambdaQuery()
|
||||
.orderByAsc(XgDormCampus::getSortOrder, XgDormCampus::getId));
|
||||
|
||||
// 2. 获取所有宿舍区数据
|
||||
List<XgDormArea> areaList = areaMapper.selectList(
|
||||
Wrappers.<XgDormArea>lambdaQuery()
|
||||
.orderByAsc(XgDormArea::getSortOrder, XgDormArea::getId));
|
||||
|
||||
// 3. 获取所有宿舍楼数据
|
||||
// 2. 获取所有宿舍楼数据
|
||||
List<XgDormBuilding> buildingList = baseMapper.selectList(
|
||||
Wrappers.<XgDormBuilding>lambdaQuery()
|
||||
.orderByAsc(XgDormBuilding::getSortOrder, XgDormBuilding::getId));
|
||||
|
||||
// 4. 构建树形结构
|
||||
// 3. 构建树形结构
|
||||
List<BuildingTreeSelectVo> 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<XgDormArea> campusAreas = areaList.stream()
|
||||
.filter(area -> area.getCampusId().equals(campus.getId()))
|
||||
// 检查该校区下是否有宿舍楼
|
||||
List<XgDormBuilding> 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<XgDormBuilding> 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<XgDormBuildingSimplifiedVo> querySimplifiedPageList(XgDormBuildingBo bo, PageQuery pageQuery) {
|
||||
// 先查询完整的分页数据
|
||||
TableDataInfo<XgDormBuildingVo> fullPageList = queryPageList(bo, pageQuery);
|
||||
|
||||
// 转换为简化版VO
|
||||
List<XgDormBuildingSimplifiedVo> simplifiedList = fullPageList.getRows().stream()
|
||||
.map(XgDormBuildingSimplifiedVo::fromFullVo)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 创建简化版分页结果
|
||||
TableDataInfo<XgDormBuildingSimplifiedVo> simplifiedPageList = new TableDataInfo<>();
|
||||
simplifiedPageList.setRows(simplifiedList);
|
||||
simplifiedPageList.setTotal(fullPageList.getTotal());
|
||||
|
||||
return simplifiedPageList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询符合条件的宿舍楼信息简化列表
|
||||
* 用于简化界面显示,隐藏宿舍区层级,直接显示校区→宿舍楼结构
|
||||
*
|
||||
* @param bo 查询条件
|
||||
* @return 宿舍楼信息简化列表
|
||||
*/
|
||||
@Override
|
||||
public List<XgDormBuildingSimplifiedVo> querySimplifiedList(XgDormBuildingBo bo) {
|
||||
// 先查询完整的数据
|
||||
List<XgDormBuildingVo> fullList = queryList(bo);
|
||||
|
||||
// 转换为简化版VO
|
||||
return fullList.stream()
|
||||
.map(XgDormBuildingSimplifiedVo::fromFullVo)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
+39
@@ -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<DormBuildingTreeSimplifiedVo> getSimplifiedDormBuildingTree(DormBuildingTreeBo bo) {
|
||||
// 先获取完整的树形结构数据
|
||||
List<DormBuildingTreeVo> fullTreeData = getDormBuildingTree(bo);
|
||||
|
||||
// 转换为简化版树形结构
|
||||
return fullTreeData.stream()
|
||||
.map(DormBuildingTreeSimplifiedVo::fromFullTreeVo)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有宿舍楼树形结构简化数据(不考虑权限)
|
||||
* 校区-宿舍楼二级结构,隐藏宿舍区层级
|
||||
*
|
||||
* @param bo 查询参数
|
||||
* @return 简化树形结构数据
|
||||
*/
|
||||
@Override
|
||||
public List<DormBuildingTreeSimplifiedVo> getAllSimplifiedDormBuildingTree(DormBuildingTreeBo bo) {
|
||||
// 先获取完整的树形结构数据(不考虑权限)
|
||||
List<DormBuildingTreeVo> fullTreeData = getAllDormBuildingTree(bo);
|
||||
|
||||
// 转换为简化版树形结构
|
||||
return fullTreeData.stream()
|
||||
.map(DormBuildingTreeSimplifiedVo::fromFullTreeVo)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -144,8 +144,8 @@ public class XgDormRoomServiceImpl implements IXgDormRoomService {
|
||||
private LambdaQueryWrapper<XgDormRoom> buildQueryWrapper(XgDormRoomBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<XgDormRoom> 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());
|
||||
|
||||
@@ -333,4 +333,83 @@ public interface DormHygieneStudentScoreMapper extends BaseMapperPlus<DormHygien
|
||||
|
||||
**文档版本:** v1.0
|
||||
**创建时间:** 2025-01-28
|
||||
**维护人员:** 系统开发团队
|
||||
**维护人员:** 系统开发团队
|
||||
|
||||
---
|
||||
|
||||
## 修复记录
|
||||
|
||||
### 2025-01-29 界面问题修复
|
||||
|
||||
#### 修复问题一:新增时个人扣分默认值显示
|
||||
**问题现象:** 点击新增按钮时,弹窗中房间学生信息列表的个人扣分列显示默认0分placeholder,而不是直接填入0。
|
||||
|
||||
**解决方案:** 修改`DormHygieneCheckDialog.vue`中`loadRoomStudents`方法,将新增模式下学生的`student_score`默认值从`null`改为`0`。
|
||||
|
||||
```javascript
|
||||
// 修改前
|
||||
student_score: student.student_score || null, // 个人得分,默认为空
|
||||
|
||||
// 修改后
|
||||
student_score: 0, // 个人得分,新增时默认为0
|
||||
```
|
||||
|
||||
#### 修复问题二:宿舍扣分变为0时个人扣分不同步更新
|
||||
**问题现象:** 当宿舍扣分从1改成0时,房间学生信息列表中个人扣分还是1,没有变成0。
|
||||
|
||||
**解决方案:** 修改`handleTotalScoreChange`方法,添加对0分的特别处理逻辑。
|
||||
|
||||
```javascript
|
||||
// 修改后的逻辑
|
||||
const handleTotalScoreChange = () => {
|
||||
// 验证宿舍总分范围
|
||||
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`
|
||||
+135
-41
@@ -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<BuildingTreeSelectVo> | 子节点列表 |
|
||||
| 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<DormBuildingTreeVo> | 子节点列表 |
|
||||
| buildingFloors | Integer | 宿舍楼层数(仅宿舍楼节点) |
|
||||
| buildingType | String | 宿舍楼类型(仅宿舍楼节点) |
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 前端使用示例
|
||||
@@ -114,7 +194,7 @@ import type { BuildingTreeSelectVo } from '@/api/sslxx/dormBuilding/types';
|
||||
// 在组件的setup函数中
|
||||
const treeData = ref<BuildingTreeSelectVo[]>([]);
|
||||
|
||||
// 加载宿舍楼树形数据
|
||||
// 加载宿舍楼树形数据(推荐使用二级结构)
|
||||
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
|
||||
2025-01-29
|
||||
@@ -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是)',
|
||||
|
||||
+60
-125
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<el-dialog :title="dialogTitle" v-model="dialogVisible" width="1200px" append-to-body @close="handleClose">
|
||||
<el-form ref="dormHygieneCheckFormRef" :model="form" :rules="rules" label-width="120px">
|
||||
<!-- 第一行:检查标题、校区名称、宿舍区名称 -->
|
||||
<!-- 第一行:检查标题、校区名称、宿舍楼名称 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="检查标题" prop="checkTitle">
|
||||
@@ -23,26 +23,6 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="宿舍区名称" prop="areaId">
|
||||
<el-select
|
||||
v-model="form.areaId"
|
||||
placeholder="请选择宿舍区"
|
||||
clearable
|
||||
filterable
|
||||
:loading="dormLoading"
|
||||
@change="handleAreaChange"
|
||||
style="width: 100%"
|
||||
:disabled="!form.campusId"
|
||||
>
|
||||
<el-option v-for="area in areaOptions" :key="area.id" :label="area.areaName" :value="area.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 第二行:宿舍楼名称、房间名称、宿舍总分 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="宿舍楼名称" prop="buildingId">
|
||||
<el-select
|
||||
@@ -53,12 +33,16 @@
|
||||
:loading="dormLoading"
|
||||
@change="handleBuildingChange"
|
||||
style="width: 100%"
|
||||
:disabled="!form.areaId"
|
||||
:disabled="!form.campusId"
|
||||
>
|
||||
<el-option v-for="building in buildingOptions" :key="building.id" :label="building.buildingName" :value="building.id" />
|
||||
<el-option v-for="building in buildingOptions" :key="building.id" :label="getBuildingDisplayName(building)" :value="building.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 第二行:房间名称、宿舍扣分、卫生等级 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="房间名称" prop="roomId">
|
||||
<el-select
|
||||
@@ -76,10 +60,10 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="宿舍总分" prop="totalScore">
|
||||
<el-form-item label="宿舍扣分" prop="totalScore">
|
||||
<el-input
|
||||
v-model="form.totalScore"
|
||||
placeholder="请输入宿舍总分(0-100分)"
|
||||
placeholder="请输入宿舍扣分(默认0分)"
|
||||
type="number"
|
||||
:min="0"
|
||||
:max="100"
|
||||
@@ -88,10 +72,6 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 第三行:卫生等级、检查类型、检查级别 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="卫生等级" prop="hygieneGrade">
|
||||
<el-select v-model="form.hygieneGrade" placeholder="请选择卫生等级" style="width: 100%" @change="handleHygieneGradeChange">
|
||||
@@ -99,6 +79,10 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 第三行:检查类型、检查级别、检查员姓名 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="检查类型" prop="checkType">
|
||||
<el-select v-model="form.checkType" placeholder="请选择检查类型" style="width: 100%">
|
||||
@@ -113,10 +97,6 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 第四行:检查员姓名、检查日期 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="检查员姓名" prop="checkerName">
|
||||
<el-select
|
||||
@@ -140,6 +120,10 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 第四行:检查日期 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="检查日期" prop="checkDate">
|
||||
<el-date-picker
|
||||
@@ -167,12 +151,12 @@
|
||||
<div class="room-students-container">
|
||||
<div class="room-students-table-wrapper">
|
||||
<el-table :data="roomStudents" stripe size="small" table-layout="auto">
|
||||
<!-- 学生个人得分 -->
|
||||
<el-table-column label="个人得分" width="120" fixed="left">
|
||||
<!-- 学生个人扣分 -->
|
||||
<el-table-column label="个人扣分" width="120" fixed="left">
|
||||
<template #default="scope">
|
||||
<el-input
|
||||
v-model="scope.row.student_score"
|
||||
placeholder="0-100分"
|
||||
placeholder="默认0分"
|
||||
size="small"
|
||||
type="number"
|
||||
:min="0"
|
||||
@@ -415,14 +399,10 @@ interface CampusOptionVO {
|
||||
campusName: string;
|
||||
}
|
||||
|
||||
interface AreaOptionVO {
|
||||
id: string | number;
|
||||
areaName: string;
|
||||
}
|
||||
|
||||
interface BuildingOptionVO {
|
||||
id: string | number;
|
||||
buildingName: string;
|
||||
buildingType?: string; // 宿舍楼类型(1男生楼 2女生楼 3混合楼)
|
||||
}
|
||||
|
||||
interface RoomOptionVO {
|
||||
@@ -457,7 +437,6 @@ const dormHygieneCheckFormRef = ref();
|
||||
|
||||
// 宿舍级联选择器相关状态
|
||||
const campusOptions = ref<CampusOptionVO[]>([]);
|
||||
const areaOptions = ref<AreaOptionVO[]>([]);
|
||||
const buildingOptions = ref<BuildingOptionVO[]>([]);
|
||||
const roomOptions = ref<RoomOptionVO[]>([]);
|
||||
const dormLoading = ref(false);
|
||||
@@ -517,11 +496,9 @@ const initFormData: DormHygieneCheckForm = {
|
||||
roomName: undefined,
|
||||
buildingId: undefined,
|
||||
buildingName: undefined,
|
||||
areaId: undefined,
|
||||
areaName: undefined,
|
||||
campusId: undefined,
|
||||
campusName: undefined,
|
||||
totalScore: undefined,
|
||||
totalScore: 0,
|
||||
hygieneGrade: 'A', // 默认 A - 优秀
|
||||
attachmentIds: undefined,
|
||||
checkSummary: undefined,
|
||||
@@ -722,8 +699,7 @@ const resetForm = () => {
|
||||
attachmentList.value = [];
|
||||
roomStudents.value = [];
|
||||
|
||||
// 清空宿舍级联选项
|
||||
areaOptions.value = [];
|
||||
// 清空宿舍级联选项 - 移除宿舍区相关
|
||||
buildingOptions.value = [];
|
||||
roomOptions.value = [];
|
||||
|
||||
@@ -812,15 +788,12 @@ const loadCampusOptions = async () => {
|
||||
/** 校区选择变化处理 */
|
||||
const handleCampusChange = async (campusId: string | number) => {
|
||||
console.log('校区选择变化处理', campusId);
|
||||
// 清空下级选项
|
||||
form.areaId = undefined;
|
||||
form.areaName = undefined;
|
||||
// 清空下级选项 - 移除宿舍区相关字段
|
||||
form.buildingId = undefined;
|
||||
form.buildingName = undefined;
|
||||
form.roomId = undefined;
|
||||
form.roomName = undefined;
|
||||
|
||||
areaOptions.value = [];
|
||||
buildingOptions.value = [];
|
||||
roomOptions.value = [];
|
||||
|
||||
@@ -832,77 +805,22 @@ const handleCampusChange = async (campusId: string | number) => {
|
||||
form.campusName = selectedCampus.campusName;
|
||||
}
|
||||
|
||||
// 加载宿舍区选项
|
||||
await loadAreaOptions(campusId);
|
||||
// 直接加载宿舍楼选项(根据校区过滤)
|
||||
await loadBuildingOptions(campusId);
|
||||
} else {
|
||||
form.campusId = undefined;
|
||||
form.campusName = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
/** 加载宿舍区选项 */
|
||||
const loadAreaOptions = async (campusId: string | number) => {
|
||||
try {
|
||||
const cacheKey = `area_${campusId}`;
|
||||
const cachedData = getCachedData(cacheKey);
|
||||
|
||||
if (cachedData) {
|
||||
areaOptions.value = cachedData;
|
||||
return;
|
||||
}
|
||||
|
||||
dormLoading.value = true;
|
||||
const res = await request({
|
||||
url: '/ssqxx/dormArea/list',
|
||||
method: 'get',
|
||||
params: { campusId }
|
||||
});
|
||||
const data = res.rows || [];
|
||||
areaOptions.value = data;
|
||||
setCachedData(cacheKey, data);
|
||||
} catch (error) {
|
||||
console.error('加载宿舍区选项失败:', error);
|
||||
areaOptions.value = [];
|
||||
} finally {
|
||||
dormLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
/** 宿舍区选择变化处理 */
|
||||
const handleAreaChange = async (areaId: string | number) => {
|
||||
// 清空下级选项
|
||||
form.buildingId = undefined;
|
||||
form.buildingName = undefined;
|
||||
form.roomId = undefined;
|
||||
form.roomName = undefined;
|
||||
|
||||
buildingOptions.value = [];
|
||||
roomOptions.value = [];
|
||||
|
||||
if (areaId) {
|
||||
// 设置宿舍区名称
|
||||
const selectedArea = areaOptions.value.find((area) => area.id === areaId);
|
||||
if (selectedArea) {
|
||||
form.areaId = areaId;
|
||||
form.areaName = selectedArea.areaName;
|
||||
}
|
||||
|
||||
// 加载宿舍楼选项
|
||||
await loadBuildingOptions(areaId);
|
||||
} else {
|
||||
form.areaId = undefined;
|
||||
form.areaName = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
/** 加载宿舍楼选项 */
|
||||
const loadBuildingOptions = async (areaId: string | number) => {
|
||||
/** 加载宿舍楼选项 - 修改为直接根据校区ID过滤 */
|
||||
const loadBuildingOptions = async (campusId: string | number) => {
|
||||
try {
|
||||
dormLoading.value = true;
|
||||
const res = await request({
|
||||
url: '/sslxx/dormBuilding/list',
|
||||
method: 'get',
|
||||
params: { areaId }
|
||||
params: { campusId } // 直接使用校区ID过滤,不再使用areaId
|
||||
});
|
||||
buildingOptions.value = res.rows || [];
|
||||
} catch (error) {
|
||||
@@ -1075,18 +993,13 @@ const loadCascadeOptionsForUpdate = async (formData: DormHygieneCheckForm) => {
|
||||
// 并行加载所有需要的宿舍选项,提升性能
|
||||
const loadTasks = [];
|
||||
|
||||
// 如果有校区ID,加载宿舍区选项
|
||||
// 如果有校区ID,加载宿舍楼选项
|
||||
if (formData.campusId) {
|
||||
loadTasks.push(loadAreaOptions(formData.campusId));
|
||||
loadTasks.push(loadBuildingOptions(formData.campusId));
|
||||
|
||||
// 如果有宿舍区ID,加载宿舍楼选项
|
||||
if (formData.areaId) {
|
||||
loadTasks.push(loadBuildingOptions(formData.areaId));
|
||||
|
||||
// 如果有宿舍楼ID,加载房间选项
|
||||
if (formData.buildingId) {
|
||||
loadTasks.push(loadRoomOptions(formData.buildingId));
|
||||
}
|
||||
// 如果有宿舍楼ID,加载房间选项
|
||||
if (formData.buildingId) {
|
||||
loadTasks.push(loadRoomOptions(formData.buildingId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1163,7 +1076,7 @@ const loadRoomStudents = async () => {
|
||||
// 为每个学生设置默认值
|
||||
roomStudents.value = res.data.map((student: any) => ({
|
||||
...student,
|
||||
student_score: student.student_score || null, // 个人得分,默认为空
|
||||
student_score: 0, // 个人得分,新增时默认为0
|
||||
attendance_status: student.attendance_status || '1', // 出勤状态,默认1-在寝
|
||||
student_grade: student.student_grade || 'A' // 学生评级,默认A-优秀
|
||||
}));
|
||||
@@ -1414,6 +1327,20 @@ const handleAttachmentData = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 宿舍楼选项显示格式
|
||||
const getBuildingDisplayName = (building: BuildingOptionVO) => {
|
||||
let displayName = building.buildingName;
|
||||
if (building.buildingType) {
|
||||
if (building.buildingType === '1') {
|
||||
displayName = `(男)${displayName}`;
|
||||
} else if (building.buildingType === '2') {
|
||||
displayName = `(女)${displayName}`;
|
||||
}
|
||||
// 混合楼(3)不显示性别标识
|
||||
}
|
||||
return displayName;
|
||||
};
|
||||
|
||||
// 组件挂载时加载校区选项
|
||||
const initCampusOptions = async () => {
|
||||
await loadCampusOptions();
|
||||
@@ -1482,21 +1409,29 @@ const handleStudentGradeChange = (student: any) => {
|
||||
// 处理宿舍总分变化 - 自动填写学生个人得分
|
||||
const handleTotalScoreChange = () => {
|
||||
// 验证宿舍总分范围
|
||||
if (form.totalScore !== null && form.totalScore !== undefined && form.totalScore !== 0 && String(form.totalScore) !== '0') {
|
||||
if (form.totalScore !== null && form.totalScore !== undefined && form.totalScore !== '') {
|
||||
const score = parseFloat(form.totalScore.toString());
|
||||
if (isNaN(score) || score < 0 || score > 100) {
|
||||
ElMessage.warning('宿舍总分必须在0-100分之间');
|
||||
form.totalScore = null;
|
||||
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分`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -106,9 +106,8 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="房间名称" align="center" prop="roomName" />
|
||||
<el-table-column label="宿舍楼名称" align="center" prop="buildingName" />
|
||||
<el-table-column label="宿舍区名称" align="center" prop="areaName" />
|
||||
<el-table-column label="校区名称" align="center" prop="campusName" />
|
||||
<el-table-column label="宿舍总分" align="center" prop="totalScore" />
|
||||
<el-table-column label="宿舍扣分" align="center" prop="totalScore" />
|
||||
<el-table-column label="卫生等级" align="center" prop="hygieneGrade">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="xg_dorm_hygiene_grade" :value="scope.row.hygieneGrade" />
|
||||
@@ -138,16 +137,17 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
<pagination v-show="total > 0" :total="total" :page="queryParams.pageNum" :limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 宿舍卫生检查弹窗组件 -->
|
||||
<DormHygieneCheckDialog
|
||||
v-model="dialog.visible"
|
||||
:visible="dialog.visible"
|
||||
:title="dialog.title"
|
||||
:form-data="form"
|
||||
@submit="handleDialogSubmit"
|
||||
@close="handleDialogClose"
|
||||
@update:visible="(value) => (dialog.visible = value)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -164,7 +164,7 @@ import {
|
||||
addDormHygieneCheck,
|
||||
updateDormHygieneCheck,
|
||||
exportDormHygieneCheck
|
||||
} from '@/api/xg/xgss/dormHygieneCheck/dormHygieneCheck';
|
||||
} from '@/api/xg/xgss/dormHygieneCheck/dormHygieneCheck/index';
|
||||
import {
|
||||
DormHygieneCheckVO,
|
||||
DormHygieneCheckQuery,
|
||||
@@ -223,7 +223,7 @@ const initFormData: DormHygieneCheckForm = {
|
||||
areaName: undefined,
|
||||
campusId: undefined,
|
||||
campusName: undefined,
|
||||
totalScore: undefined,
|
||||
totalScore: 0,
|
||||
hygieneGrade: 'A',
|
||||
attachmentIds: undefined,
|
||||
checkSummary: undefined,
|
||||
|
||||
@@ -17,24 +17,11 @@
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="所属校区" prop="campusId">
|
||||
<el-select v-model="queryParams.campusId" placeholder="请选择所属校区" clearable @change="handleCampusChange">
|
||||
<el-select v-model="queryParams.campusId" placeholder="请选择所属校区" clearable>
|
||||
<el-option v-for="item in campusList" :key="item.id" :label="item.campusName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="所属宿舍区" prop="areaId">
|
||||
<el-tree-select
|
||||
v-model="queryParams.areaId"
|
||||
:data="areaTreeData"
|
||||
:props="{ label: 'areaName', value: 'id' }"
|
||||
placeholder="请选择所属宿舍区"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="宿舍楼类型" prop="buildingType">
|
||||
<el-select v-model="queryParams.buildingType" placeholder="请选择宿舍楼类型" clearable>
|
||||
@@ -72,9 +59,6 @@
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['sslxx:dormBuilding:export']">导出</el-button>
|
||||
</el-col> -->
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
@@ -85,7 +69,6 @@
|
||||
<el-table-column label="宿舍楼编码" align="center" prop="buildingCode" />
|
||||
<el-table-column label="宿舍楼名称" align="center" prop="buildingName" />
|
||||
<el-table-column label="所属校区" align="center" prop="campusName" />
|
||||
<el-table-column label="所属宿舍区" align="center" prop="areaName" />
|
||||
<el-table-column label="总楼层数" align="center" prop="floors" />
|
||||
<el-table-column label="宿舍楼类型" align="center" prop="buildingType">
|
||||
<template #default="scope">
|
||||
@@ -112,19 +95,10 @@
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="dormBuildingFormRef" :model="form" :rules="rules" label-width="120px">
|
||||
<el-form-item label="所属校区" prop="campusId">
|
||||
<el-select v-model="form.campusId" placeholder="请选择所属校区" clearable @change="handleFormCampusChange">
|
||||
<el-select v-model="form.campusId" placeholder="请选择所属校区" clearable>
|
||||
<el-option v-for="item in campusList" :key="item.id" :label="item.campusName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="所属宿舍区" prop="areaId">
|
||||
<el-tree-select
|
||||
v-model="form.areaId"
|
||||
:data="formAreaTreeData"
|
||||
:props="{ label: 'areaName', value: 'id' }"
|
||||
placeholder="请选择所属宿舍区"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="宿舍楼编码" prop="buildingCode">
|
||||
<el-input v-model="form.buildingCode" placeholder="请输入宿舍楼编码" />
|
||||
</el-form-item>
|
||||
@@ -171,13 +145,12 @@ import {
|
||||
delDormBuilding,
|
||||
addDormBuilding,
|
||||
updateDormBuilding,
|
||||
listCampusOptions,
|
||||
listAreaTreeData
|
||||
listCampusOptions
|
||||
} from '@/api/xg/xgss/sslxx/dormBuilding';
|
||||
import { DormBuildingVO, DormBuildingQuery, DormBuildingForm } from '@/api/xg/xgss/sslxx/dormBuilding/types';
|
||||
import { DormCampusVO } from '@/api/xg/xgss/xqxx/dormCampus/types';
|
||||
import { DormAreaVO } from '@/api/xg/xgss/ssqxx/dormArea/types';
|
||||
import { getCurrentInstance, ComponentInternalInstance, ref, reactive, toRefs, onMounted } from 'vue';
|
||||
import { ElForm, ElMessageBox, ElMessage } from 'element-plus';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { dorm_type } = toRefs<any>(proxy?.useDict('dorm_type'));
|
||||
@@ -191,11 +164,9 @@ const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const campusList = ref<DormCampusVO[]>([]); // 校区列表
|
||||
const areaTreeData = ref<any[]>([]); // 宿舍区树形数据
|
||||
const formAreaTreeData = ref<any[]>([]); // 表单宿舍区树形数据
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const dormBuildingFormRef = ref<ElFormInstance>();
|
||||
const queryFormRef = ref<InstanceType<typeof ElForm>>();
|
||||
const dormBuildingFormRef = ref<InstanceType<typeof ElForm>>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
@@ -206,7 +177,6 @@ const initFormData: DormBuildingForm = {
|
||||
id: undefined,
|
||||
buildingCode: undefined,
|
||||
buildingName: undefined,
|
||||
areaId: undefined,
|
||||
campusId: undefined,
|
||||
buildingType: undefined,
|
||||
buildingDescription: undefined,
|
||||
@@ -220,7 +190,6 @@ const data = reactive<PageData<DormBuildingForm, DormBuildingQuery>>({
|
||||
pageSize: 10,
|
||||
buildingCode: undefined,
|
||||
buildingName: undefined,
|
||||
areaId: undefined,
|
||||
campusId: undefined,
|
||||
buildingType: undefined,
|
||||
sortOrder: undefined,
|
||||
@@ -230,7 +199,6 @@ const data = reactive<PageData<DormBuildingForm, DormBuildingQuery>>({
|
||||
id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
|
||||
buildingCode: [{ required: true, message: '宿舍楼编码不能为空', trigger: 'blur' }],
|
||||
buildingName: [{ required: true, message: '宿舍楼名称不能为空', trigger: 'blur' }],
|
||||
areaId: [{ required: true, message: '所属宿舍区ID不能为空', trigger: 'blur' }],
|
||||
campusId: [{ required: true, message: '所属校区ID不能为空', trigger: 'blur' }]
|
||||
}
|
||||
});
|
||||
@@ -252,102 +220,6 @@ const loadCampusOptions = async () => {
|
||||
campusList.value = res.rows || [];
|
||||
};
|
||||
|
||||
/** 加载宿舍区树形数据 */
|
||||
const loadAreaTreeData = async (campusId?: string | number) => {
|
||||
const res = await listAreaTreeData(campusId);
|
||||
if (campusId) {
|
||||
// 如果指定了校区ID,只展示该校区的宿舍区
|
||||
areaTreeData.value = res.rows || [];
|
||||
formAreaTreeData.value = res.rows || []; // 同时更新表单树形数据
|
||||
} else {
|
||||
// 如果没有指定校区ID,按照校区分组展示宿舍区
|
||||
const campusMap = new Map();
|
||||
|
||||
// 先将校区列表转为Map
|
||||
campusList.value.forEach((campus) => {
|
||||
campusMap.set(campus.id, {
|
||||
id: campus.id,
|
||||
areaName: campus.campusName,
|
||||
children: []
|
||||
});
|
||||
});
|
||||
|
||||
// 将宿舍区按校区分组
|
||||
const areas = res.rows || [];
|
||||
areas.forEach((area: DormAreaVO) => {
|
||||
if (campusMap.has(area.campusId)) {
|
||||
campusMap.get(area.campusId).children.push({
|
||||
id: area.id,
|
||||
areaName: area.areaName
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 转换为树形结构
|
||||
areaTreeData.value = Array.from(campusMap.values());
|
||||
formAreaTreeData.value = Array.from(campusMap.values());
|
||||
}
|
||||
};
|
||||
|
||||
/** 校区选择变化处理函数 */
|
||||
const handleCampusChange = (value: string | number) => {
|
||||
queryParams.value.areaId = undefined; // 清空已选择的宿舍区
|
||||
loadAreaTreeData(value);
|
||||
};
|
||||
|
||||
/** 表单校区选择变化处理函数 */
|
||||
const handleFormCampusChange = (value: string | number) => {
|
||||
form.value.areaId = undefined; // 清空已选择的宿舍区
|
||||
loadFormAreaTreeData(value);
|
||||
};
|
||||
|
||||
/** 加载表单宿舍区树形数据 */
|
||||
const loadFormAreaTreeData = async (campusId?: string | number) => {
|
||||
const res = await listAreaTreeData(campusId);
|
||||
if (campusId) {
|
||||
// 如果指定了校区ID,只展示该校区的宿舍区
|
||||
formAreaTreeData.value = res.rows || [];
|
||||
} else {
|
||||
// 如果没有指定校区ID,按照校区分组展示宿舍区
|
||||
const campusMap = new Map();
|
||||
|
||||
// 先将校区列表转为Map
|
||||
campusList.value.forEach((campus) => {
|
||||
campusMap.set(campus.id, {
|
||||
id: campus.id,
|
||||
areaName: campus.campusName,
|
||||
children: []
|
||||
});
|
||||
});
|
||||
|
||||
// 将宿舍区按校区分组
|
||||
const areas = res.rows || [];
|
||||
areas.forEach((area: DormAreaVO) => {
|
||||
if (campusMap.has(area.campusId)) {
|
||||
campusMap.get(area.campusId).children.push({
|
||||
id: area.id,
|
||||
areaName: area.areaName
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 转换为树形结构
|
||||
formAreaTreeData.value = Array.from(campusMap.values());
|
||||
}
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
};
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
dormBuildingFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
@@ -363,7 +235,7 @@ const resetQuery = () => {
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: DormBuildingVO[]) => {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
single.value = selection.length !== 1;
|
||||
multiple.value = !selection.length;
|
||||
};
|
||||
|
||||
@@ -380,10 +252,6 @@ const handleUpdate = async (row?: DormBuildingVO) => {
|
||||
const _id = row?.id || ids.value[0];
|
||||
const res = await getDormBuilding(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
// 加载表单中的宿舍区数据
|
||||
if (form.value.campusId) {
|
||||
loadFormAreaTreeData(form.value.campusId);
|
||||
}
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改宿舍楼信息';
|
||||
};
|
||||
@@ -394,13 +262,22 @@ const submitForm = () => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
if (form.value.id) {
|
||||
await updateDormBuilding(form.value).finally(() => (buttonLoading.value = false));
|
||||
await updateDormBuilding(form.value)
|
||||
.then(() => {
|
||||
ElMessage.success('修改成功');
|
||||
dialog.visible = false;
|
||||
getList();
|
||||
})
|
||||
.finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
await addDormBuilding(form.value).finally(() => (buttonLoading.value = false));
|
||||
await addDormBuilding(form.value)
|
||||
.then(() => {
|
||||
ElMessage.success('新增成功');
|
||||
dialog.visible = false;
|
||||
getList();
|
||||
})
|
||||
.finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -408,148 +285,48 @@ const submitForm = () => {
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: DormBuildingVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
|
||||
let confirmMsg = '';
|
||||
if (row) {
|
||||
confirmMsg = `是否确认删除宿舍楼信息编号为"${row?.buildingName}"的数据项?`;
|
||||
} else if (Array.isArray(ids.value) && ids.value.length > 1) {
|
||||
confirmMsg = `是否确认删除选中的${ids.value.length}个宿舍楼信息?`;
|
||||
} else {
|
||||
confirmMsg = '是否确认删除选中的宿舍楼信息?';
|
||||
}
|
||||
await proxy?.$modal.confirm(confirmMsg).finally(() => (loading.value = false));
|
||||
|
||||
await delDormBuilding(_ids);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
await getList();
|
||||
await ElMessageBox.confirm('是否确认删除宿舍楼信息编号为"' + _ids + '"的数据项?')
|
||||
.then(() => {
|
||||
loading.value = true;
|
||||
return delDormBuilding(_ids);
|
||||
})
|
||||
.then(() => {
|
||||
loading.value = false;
|
||||
getList();
|
||||
ElMessage.success('删除成功');
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download(
|
||||
'sslxx/dormBuilding/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`dormBuilding_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
/** 重置操作表单 */
|
||||
const reset = () => {
|
||||
form.value = { ...initFormData };
|
||||
dormBuildingFormRef.value?.resetFields();
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
dialog.visible = false;
|
||||
reset();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
loadCampusOptions().then(() => {
|
||||
loadAreaTreeData();
|
||||
});
|
||||
loadCampusOptions();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 页面容器样式 */
|
||||
.page-container {
|
||||
padding: 8px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
/* 表格卡片布局 */
|
||||
.table-card {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.table-card :deep(.el-card__body) {
|
||||
padding: 0px 20px 20px 20px !important;
|
||||
}
|
||||
|
||||
/* 移除按钮栏底部边框 */
|
||||
.button-card :deep(.el-card__header) {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
.image-gallery {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.image-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 6px;
|
||||
background-color: #fff;
|
||||
padding: 4px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.image-item:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.no-image {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 120px;
|
||||
height: 80px;
|
||||
border: 1px dashed #dcdfe6;
|
||||
border-radius: 4px;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.no-image-text {
|
||||
color: #909399;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.table-no-image {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border: 1px dashed #dcdfe6;
|
||||
border-radius: 4px;
|
||||
background-color: #fafafa;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.table-no-image-text {
|
||||
color: #909399;
|
||||
font-size: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.view-text {
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.view-description {
|
||||
padding: 12px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
line-height: 1.6;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
overflow-y: auto;
|
||||
}
|
||||
/* 搜索按钮容器样式 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.fixed-width-input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@@ -98,52 +98,73 @@
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<!-- 楼层卡片 -->
|
||||
<div v-for="floor in floorList" :key="floor" class="mb-4">
|
||||
<el-divider>
|
||||
<el-tag type="success" effect="dark" class="mr-2">{{ floor }}层</el-tag>
|
||||
<el-button type="primary" icon="Plus" size="small" @click="handleAddAllRoom(floor)">自动添加房间</el-button>
|
||||
<el-button type="primary" icon="Plus" size="small" @click="handleAddRoom(floor)">添加房间</el-button>
|
||||
</el-divider>
|
||||
|
||||
<div class="room-container">
|
||||
<el-empty v-if="getRoomsByFloor(floor).length === 0" description="暂无房间数据" />
|
||||
<div v-else class="room-grid">
|
||||
<el-card
|
||||
v-for="room in getRoomsByFloor(floor)"
|
||||
:key="room.id"
|
||||
class="room-card"
|
||||
:class="{ 'room-disabled': room.roomStatus !== '0' }"
|
||||
>
|
||||
<template #header>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-bold">{{ room.roomName }}</span>
|
||||
<div>
|
||||
<el-tag v-if="room.roomStatus === '0'" type="success" size="small">正常</el-tag>
|
||||
<el-tag v-else-if="room.roomStatus === '1'" type="warning" size="small">维修中</el-tag>
|
||||
<el-tag v-else type="danger" size="small">停用</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="room-info">
|
||||
<div class="mb-2">
|
||||
<span class="text-gray-500">类型:</span>{{ room.roomType === '1' ? '标准间' : room.roomType === '2' ? '单人间' : '套间' }}
|
||||
</div>
|
||||
<div class="mb-2"><span class="text-gray-500">床位:</span>{{ room.currentBeds || 0 }}/{{ room.actualBeds }}</div>
|
||||
<div class="mb-2"><span class="text-gray-500">排序:</span>{{ room.sort || 0 }}</div>
|
||||
<div class="flex justify-between mt-4">
|
||||
<div>
|
||||
<el-button type="primary" link size="small" @click="handleManageBeds(room)">床位管理</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-button type="primary" link icon="Edit" @click="handleEditRoom(room)" />
|
||||
<el-button type="danger" link icon="Delete" @click="handleDeleteRoom(room)" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<!-- 右侧房间信息区域 -->
|
||||
<div class="room-info-area">
|
||||
<!-- 加载状态 -->
|
||||
<div v-if="roomLoading" class="loading-container">
|
||||
<div class="loading-content">
|
||||
<el-icon class="loading-icon" :size="32">
|
||||
<Loading />
|
||||
</el-icon>
|
||||
<p class="loading-text">正在加载房间数据...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 房间数据展示 -->
|
||||
<div v-else-if="roomList.length > 0" class="room-display">
|
||||
<div v-for="floor in floorList" :key="floor" class="mb-4">
|
||||
<el-divider>
|
||||
<el-tag type="success" effect="dark" class="mr-2">{{ floor }}层</el-tag>
|
||||
<el-button type="primary" icon="Plus" size="small" @click="handleAddAllRoom(floor)">自动添加房间</el-button>
|
||||
<el-button type="primary" icon="Plus" size="small" @click="handleAddRoom(floor)">添加房间</el-button>
|
||||
</el-divider>
|
||||
|
||||
<div class="room-container">
|
||||
<el-empty v-if="getRoomsByFloor(floor).length === 0" description="暂无房间数据" />
|
||||
<div v-else class="room-grid">
|
||||
<el-card
|
||||
v-for="room in getRoomsByFloor(floor)"
|
||||
:key="room.id"
|
||||
class="room-card"
|
||||
:class="{ 'room-disabled': room.roomStatus !== '0' }"
|
||||
>
|
||||
<template #header>
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-bold">{{ room.roomName }}</span>
|
||||
<div>
|
||||
<el-tag v-if="room.roomStatus === '0'" type="success" size="small">正常</el-tag>
|
||||
<el-tag v-else-if="room.roomStatus === '1'" type="warning" size="small">维修中</el-tag>
|
||||
<el-tag v-else type="danger" size="small">停用</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="room-info">
|
||||
<div class="mb-2">
|
||||
<span class="text-gray-500">类型:</span
|
||||
>{{ room.roomType === '1' ? '标准间' : room.roomType === '2' ? '单人间' : '套间' }}
|
||||
</div>
|
||||
<div class="mb-2"><span class="text-gray-500">床位:</span>{{ room.currentBeds || 0 }}/{{ room.actualBeds }}</div>
|
||||
<div class="mb-2"><span class="text-gray-500">排序:</span>{{ room.sort || 0 }}</div>
|
||||
<div class="flex justify-between mt-4">
|
||||
<div>
|
||||
<el-button type="primary" size="small" @click="handleManageBeds(room)">床位管理</el-button>
|
||||
</div>
|
||||
<div>
|
||||
<el-button type="primary" link size="small" icon="Edit" @click="handleEditRoom(room)" />
|
||||
<el-button type="danger" link size="small" icon="Delete" @click="handleDeleteRoom(room)" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 空状态展示 -->
|
||||
<div v-else class="empty-state">
|
||||
<el-empty description="请先选择左侧宿舍楼查看房间信息" />
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
@@ -213,7 +234,7 @@
|
||||
<script setup name="DormRoomManagement" lang="ts">
|
||||
import { ref, computed, reactive, onMounted, nextTick, watch } from 'vue';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { InfoFilled, Search } from '@element-plus/icons-vue';
|
||||
import { InfoFilled, Search, Loading } from '@element-plus/icons-vue';
|
||||
import { DormTreeNode, BedInfo, DormQuery, BedForm } from '@/api/xg/xgss/xsssfjgl/types';
|
||||
import { DormRoomVO, DormRoomQuery } from '@/api/xg/xgss/dormRoom/types';
|
||||
import { getDormTree } from '@/api/xg/xgss/xsssfjgl';
|
||||
@@ -230,6 +251,8 @@ const dormTreeRef = ref();
|
||||
const queryFormRef = ref();
|
||||
const buildingName = ref('');
|
||||
const showSearch = ref(true);
|
||||
// 添加房间数据加载状态
|
||||
const roomLoading = ref(false);
|
||||
const animate = reactive({
|
||||
searchAnimate: {
|
||||
enter: 'animate__animated animate__fadeInDown',
|
||||
@@ -356,6 +379,9 @@ const handleNodeClick = (data: DormTreeNode) => {
|
||||
const loadRoomData = async () => {
|
||||
if (!queryParams.buildingId) return;
|
||||
|
||||
// 开始加载,设置loading状态
|
||||
roomLoading.value = true;
|
||||
|
||||
try {
|
||||
const res = await listDormRoom(queryParams);
|
||||
roomList.value = res?.rows;
|
||||
@@ -375,6 +401,9 @@ const loadRoomData = async () => {
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('获取房间列表失败', error);
|
||||
} finally {
|
||||
// 加载完成,取消loading状态
|
||||
roomLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -862,4 +891,53 @@ watch(
|
||||
min-width: 100%; /* 确保树至少占满容器宽度 */
|
||||
width: max-content; /* 允许内容扩展 */
|
||||
}
|
||||
|
||||
/* 加载状态样式 */
|
||||
.loading-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 400px;
|
||||
background: #fafafa;
|
||||
border-radius: 8px;
|
||||
border: 1px dashed #d9d9d9;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.loading-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.loading-icon {
|
||||
color: var(--el-color-primary);
|
||||
animation: rotate 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes rotate {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 14px;
|
||||
color: var(--el-text-color-regular);
|
||||
margin: 0;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 空状态样式 */
|
||||
.empty-state {
|
||||
min-height: 400px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
@@ -103,8 +103,8 @@
|
||||
</el-table>
|
||||
</el-card>
|
||||
</el-tab-pane>
|
||||
<!-- 隐藏宿舍区管理员tab页
|
||||
<el-tab-pane label="宿舍区管理员" name="area">
|
||||
<!-- 检索栏(宿舍区管理员) -->
|
||||
<div class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form :inline="true" :model="areaSearchForm" class="search-form">
|
||||
@@ -155,6 +155,7 @@
|
||||
</el-table>
|
||||
</el-card>
|
||||
</el-tab-pane>
|
||||
-->
|
||||
<el-tab-pane label="宿舍楼管理员" name="building">
|
||||
<!-- 检索栏(宿舍楼管理员) -->
|
||||
<div class="mb-[10px]">
|
||||
|
||||
Reference in new issue
Block a user