Files
school-developer/src/views/stuwork/dormroomstudent/transfer.vue
吴红兵 b997b3ba48 fix
2026-03-07 12:35:45 +08:00

198 lines
5.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<el-dialog title="转宿" v-model="visible" :close-on-click-modal="false" draggable width="800px">
<el-form ref="dataFormRef" :model="form" :rules="dataRules" label-width="100px" :validate-on-rule-change="false" v-loading="loading">
<el-row :gutter="24">
<el-col :span="12" class="mb20">
<el-form-item label="房间号" prop="roomNo">
<el-select v-model="form.roomNo" placeholder="请选择房间号" clearable filterable style="width: 100%" @change="handleRoomChange">
<el-option v-for="item in roomList" :key="item.roomNo" :label="item.roomNo" :value="item.roomNo"> </el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="床位号" prop="bedNo">
<el-select v-model="form.bedNo" placeholder="请选择床位号" clearable style="width: 100%">
<el-option v-for="item in bedNoList" :key="item.bedNo" :value="item.bedNo">
<span :class="{ 'bed-option-occupied': item.haveStudent }"> {{ item.bedNo }}{{ item.haveStudent ? ' (有人)' : '' }} </span>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="学号" prop="stuNo">
<el-input v-model="form.stuNo" placeholder="请输入学号" disabled />
</el-form-item>
</el-col>
<el-col :span="12" class="mb20">
<el-form-item label="是否舍长" prop="isLeader">
<el-select v-model="form.isLeader" placeholder="请选择" clearable style="width: 100%">
<el-option label="是" value="1" />
<el-option label="否" value="0" />
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="visible = false"> </el-button>
<el-button type="primary" @click="onSubmit" :disabled="loading"> </el-button>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts" name="DormRoomStudentTransferDialog">
import { ref, reactive, nextTick, onMounted } from 'vue';
import { useMessage } from '/@/hooks/message';
import { editObj } from '/@/api/stuwork/dormroomstudent';
import { getRoomList } from '/@/api/stuwork/dormroom';
import { fearchRoomStuNum } from '/@/api/stuwork/dormroomstudent';
const emit = defineEmits(['refresh']);
// 定义变量内容
const dataFormRef = ref();
const visible = ref(false);
const loading = ref(false);
const roomList = ref<any[]>([]);
// 床位列表:支持 haveStudent 标记true=有人false=无人)
const bedNoList = ref<Array<{ bedNo: string; haveStudent: boolean }>>([]);
// 提交表单数据
const form = reactive({
id: '',
roomNo: '',
bedNo: '',
stuNo: '',
isLeader: '0',
});
// 定义校验规则
const dataRules = {
roomNo: [{ required: true, message: '请选择房间号', trigger: 'change' }],
bedNo: [{ required: true, message: '请选择床位号', trigger: 'change' }],
isLeader: [{ required: true, message: '请选择是否舍长', trigger: 'change' }],
};
// 房间号变化时获取床位号列表(支持 haveStudenttrue=有人false=无人)
const handleRoomChange = async (roomNo: string) => {
if (!roomNo) {
bedNoList.value = [];
form.bedNo = '';
return;
}
const toBedItem = (item: any): { bedNo: string; haveStudent: boolean } => {
if (typeof item === 'number' || typeof item === 'string') {
return { bedNo: String(item), haveStudent: false };
}
return {
bedNo: String(item?.bedNo ?? item?.value ?? item ?? ''),
haveStudent: !!(item && item.haveStudent === true),
};
};
try {
const res = await fearchRoomStuNum(roomNo);
if (res.data) {
if (Array.isArray(res.data)) {
bedNoList.value = res.data.map(toBedItem).filter((b) => b.bedNo);
} else if (res.data.bedNos && Array.isArray(res.data.bedNos)) {
bedNoList.value = res.data.bedNos.map((item: any) =>
toBedItem(typeof item === 'object' ? item : { bedNo: String(item), haveStudent: false })
);
} else {
bedNoList.value = [];
}
} else {
bedNoList.value = [];
}
form.bedNo = '';
} catch (err) {
bedNoList.value = [];
form.bedNo = '';
}
};
// 打开弹窗
const openDialog = async (row: any) => {
visible.value = true;
// 重置表单数据
await nextTick();
dataFormRef.value?.resetFields();
form.id = row.id || '';
form.roomNo = row.roomNo || '';
form.bedNo = row.bedNo || '';
form.stuNo = row.stuNo || '';
form.isLeader = row.isLeader || '0';
bedNoList.value = [];
// 如果有房间号,先拉取床位列表再回填床位号(避免 handleRoomChange 清空 bedNo
if (form.roomNo) {
await handleRoomChange(form.roomNo);
form.bedNo = row.bedNo || '';
}
};
// 提交表单
const onSubmit = async () => {
if (!dataFormRef.value) return;
await dataFormRef.value.validate(async (valid: boolean) => {
if (!valid) return;
loading.value = true;
try {
await editObj({
id: form.id,
roomNo: form.roomNo,
bedNo: form.bedNo,
stuNo: form.stuNo,
isLeader: form.isLeader,
});
useMessage().success('转宿成功');
visible.value = false;
emit('refresh');
} catch (err: any) {
// 统一交给全局拦截器处理错误提示,避免在这里重复弹出一次
console.error('转宿失败', err);
} finally {
loading.value = false;
}
});
};
// 获取房间号列表
const getRoomListData = async () => {
try {
const res = await getRoomList();
if (res.data) {
roomList.value = Array.isArray(res.data) ? res.data : [];
}
} catch (err) {
roomList.value = [];
}
};
// 初始化
onMounted(() => {
getRoomListData();
});
// 暴露方法给父组件
defineExpose({
openDialog,
});
</script>
<style scoped lang="scss">
.bed-option-occupied {
color: var(--el-color-warning);
}
</style>