提交宿舍区去除的业务修改
This commit is contained in:
1 parent
99b771bb51
commit
2a38245ae2
24 files changed
+1139
-557
No files matched your search
+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