123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580 |
- <template>
- <PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
- <div class="h-full bg-white mr-2" style="width: 350px">
- <div class="h-full m-2">
- <BasicForm @register="formStudent">
- <template #formFooter>
- <div style="display: flex; justify-content: flex-end">
- <a-button type="primary" class="w-20" @click="handelStudenSearch">搜索</a-button>
- </div>
- </template>
- </BasicForm>
- <div class="h-full">
- <div style="height: calc(100% - 130px)">
- <ScrollContainer>
- <div class="student-list" v-for="(item, index) in studentGroup" :key="index">
- <div class="student-list-title">{{ item.name }}</div>
- <div class="student-list-title">已缴费</div>
- <div class="student-list-wrap grid gap-2 grid-cols-3">
- <Badge
- :count="
- getStudentSelectedIndex(it.userId) > -1
- ? getStudentSelectedIndex(it.userId) + 1
- : 0
- "
- v-for="(it, ix) in item.studentList.filter((item) => item.payStatus === 1)"
- :key="ix"
- :number-style="{ backgroundColor: '#13c2c2' }"
- >
- <div
- class="student-list-item"
- :class="{
- 'student-list-item-active': getStudentSelectedIndex(it.userId) > -1,
- 'student-list-item-ext': it.buildName,
- }"
- @click="handelStudentClick(it, item.teacherId)"
- >
- <div class="student-list-item-text">
- <div class="student-list-item-text-title">{{ it.studentName }}</div>
- <div class="student-list-item-text-sex">{{ it.genderCn }}</div>
- </div>
- <div class="student-list-item-note">
- <div v-if="it.buildName">
- <div>{{ it.buildName }}</div>
- <div>{{ it.roomName }} - {{ it.bedNumber }}</div>
- </div>
- <div v-else>未分配</div>
- </div>
- </div>
- </Badge>
- </div>
- <div class="student-list-title">未缴费</div>
- <div class="student-list-wrap grid gap-2 grid-cols-3">
- <Badge
- :count="
- getStudentSelectedIndex(it.userId) > -1
- ? getStudentSelectedIndex(it.userId) + 1
- : 0
- "
- v-for="(it, ix) in item.studentList.filter((item) => item.payStatus === 0)"
- :key="ix"
- :number-style="{ backgroundColor: '#13c2c2' }"
- >
- <div
- class="student-list-item"
- :class="{
- 'student-list-item-active': getStudentSelectedIndex(it.userId) > -1,
- 'student-list-item-ext': it.buildName,
- }"
- @click="handelStudentClick(it, item.teacherId)"
- >
- <div class="student-list-item-text">
- <div class="student-list-item-text-title">{{ it.studentName }}</div>
- <div class="student-list-item-text-sex">{{ it.genderCn }}</div>
- </div>
- <div class="student-list-item-note">
- <div v-if="it.buildName">
- <div>{{ it.buildName }}</div>
- <div>{{ it.roomName }} - {{ it.bedNumber }}</div>
- </div>
- <div v-else>未分配</div>
- </div>
- </div>
- </Badge>
- </div>
- </div>
- </ScrollContainer>
- </div>
- </div>
- </div>
- </div>
- <div class="bg-white mr-2 h-full" style="flex: 1">
- <div class="m-2 h-full">
- <BasicForm @register="formRoom">
- <template #formFooter>
- <div style="display: flex; justify-content: flex-end">
- <a-button type="primary" class="w-20 mr-2" @click="handelRoomSearch">搜索</a-button>
- <a-button class="w-20" @click="handleClear">重置</a-button>
- </div>
- </template>
- </BasicForm>
- <div class="h-full">
- <div style="height: calc(100% - 230px)">
- <ScrollContainer>
- <div class="room-group grid gap-4 grid-cols-3">
- <div class="room-group-wrap" v-for="(item, index) in roomGroup" :key="index">
- <div class="room-group-item">
- <div class="room-group-title">
- <div>{{ item[0].buildName }}-{{ item[0].roomName }}</div>
- <div style="color: #ff0000">
- {{ item[0].isMax === 1 ? '[混合寝室]' : '' }}
- {{ `[${item[0].genderCn}寝]` }}
- </div>
- </div>
- <div class="room-list grid gap-2 grid-cols-4">
- <div class="room-list-item" v-for="(it, ix) in item" :key="ix">
- <div class="room-list-item-wrap" @click="handelRoomEdit(it)">
- <div class="room-list-item-text"> {{ it.className }}</div>
- <div class="room-list-item-text"> {{ it.studentName }}</div>
- <div class="room-list-item-text room-list-item-number">
- {{ it.bedNumber }}号床位
- </div>
- </div>
- <div
- class="room-list-item-delete"
- @click="handelRoomDelete(it)"
- v-if="it.studentUserId"
- >
- <Icon icon="lets-icons:dell-fill" :size="16" />
- </div>
- </div>
- </div>
- <div class="room-group-tool">
- <div class="room-group-tool-item" @click="handelRoomDeleteBath(item)">
- 批量移出
- </div>
- </div>
- <div
- class="room-group-class flex"
- style="flex-wrap: wrap"
- v-if="item[0].isMax === 1"
- >
- <div
- class="room-group-class-item"
- style="margin: 4px"
- v-for="(ir, id) in getGroupClass(item)"
- :key="id"
- >
- {{ ir.className }}【{{ ir.total }}人】
- </div>
- </div>
- </div>
- </div>
- </div>
- </ScrollContainer>
- </div>
- <div style="height: 100px; width: 100%; display: block">
- <div class="flex items-center">
- <div class="student-del-list flex-1">
- <Badge
- style="margin-right: 8px"
- :count="
- getStudentSelectedIndex(it.userId) > -1
- ? getStudentSelectedIndex(it.userId) + 1
- : 0
- "
- v-for="(it, ix) in studentDeleted"
- :key="ix"
- :number-style="{ backgroundColor: '#13c2c2' }"
- >
- <div
- class="student-del-list-item"
- :class="{
- 'student-del-list-item-active': getStudentSelectedIndex(it.userId) > -1,
- }"
- @click="handelStudentClick(it, it.teacherId, true)"
- >
- {{ it.userName }}
- </div>
- </Badge>
- </div>
- <div style="width: 60px">
- <a-button type="primary" @click="handelConfirm" :loading="saveLoading">
- 确定
- </a-button>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </PageWrapper>
- </template>
- <script setup lang="ts">
- import { ref, onMounted } from 'vue';
- import { Badge } from 'ant-design-vue';
- import { PageWrapper } from '/@/components/Page';
- import { BasicForm, useForm } from '/@/components/Form';
- import { formStudentSchema, formRoomSchema } from './data.config';
- import {
- getRoomBedAdjustClassStudent,
- getRoomBedAdjustBedStudent,
- putRoomBedAdjustAdjustBedBatch,
- getRoomBedAdjustIsClassTeacher,
- } from '/@/services/apis/RoomBedAdjustController';
- import { ScrollContainer } from '/@/components/Container/index';
- import { Icon } from '/@/components/Icon';
- import { groupBy } from 'lodash-es';
- import { useMessage } from '/@/hooks/web/useMessage';
- import { useUserStore } from '/@/store/modules/user';
- const { createMessage } = useMessage();
- const studentGroup = ref<any>([]);
- const roomGroup = ref<any>([]);
- const userStore = useUserStore();
- const studentSelected = ref<string[]>([]);
- const studentSelectedList = ref<Recordable[]>([]);
- const studentDeleted = ref<any[]>([]);
- const studentUpdateList = ref<Recordable[]>([]);
- const classTeacher = ref<boolean>(false);
- const saveLoading = ref<boolean>(false);
- const getStudentSelectedIndex = (id) => {
- return studentSelected.value.findIndex((row) => row === id);
- };
- const handleClear = () => {
- resetFields();
- };
- const [formStudent, { validate: validateStudent }] = useForm({
- labelWidth: 60,
- schemas: formStudentSchema,
- compact: true,
- showActionButtonGroup: false,
- actionColOptions: { span: 24 },
- });
- const [formRoom, { validate: validateRoom, resetFields }] = useForm({
- labelWidth: 80,
- schemas: formRoomSchema,
- compact: true,
- showActionButtonGroup: false,
- actionColOptions: { span: 24 },
- });
- const handelStudenSearch = async (cleara: boolean) => {
- try {
- const values = await validateStudent();
- studentGroup.value = await getRoomBedAdjustClassStudent(values);
- if (cleara) {
- studentSelected.value = [];
- studentSelectedList.value = [];
- studentDeleted.value = [];
- studentUpdateList.value = [];
- }
- } catch {}
- };
- const handelRoomSearch = async () => {
- try {
- const values = await validateRoom();
- const data = await getRoomBedAdjustBedStudent(values);
- roomGroup.value = groupBy(data, 'roomId');
- } catch {}
- };
- const handelStudentClick = (item, teacherId, del = false) => {
- if (teacherId && teacherId !== userStore.getUserInfo.id && classTeacher.value === true) {
- createMessage.error(`只能调整本班学生`);
- return;
- }
- if (studentSelected.value.includes(item.userId)) {
- studentSelected.value.splice(
- studentSelected.value.findIndex((row) => row === item.userId),
- 1,
- );
- studentSelectedList.value.splice(
- studentSelectedList.value.findIndex((row) => row.userId === item.userId),
- 1,
- );
- } else {
- if (!studentUpdateList.value.find((row) => row.userId === item.userId) || del === true) {
- studentSelected.value.push(item.userId);
- studentSelectedList.value.push({
- userId: item.userId,
- genderCn: item.genderCn,
- // roomId: item.roomId,
- bedNumber: item.bedNumber,
- className: item.className,
- studentName: item.userName || item.studentName,
- teacherId: teacherId,
- });
- }
- }
- };
- const handelRoomDelete = async (item) => {
- if (item.teacherId !== userStore.getUserInfo.id && classTeacher.value === true) {
- createMessage.error(`只能调整本班学生`);
- return;
- }
- try {
- const findIndex = studentUpdateList.value.findIndex(
- (row) => row.userId === item.studentUserId,
- );
- let isAddDel = true;
- if (findIndex > -1) {
- if (studentUpdateList.value[findIndex].bedNumber) {
- studentUpdateList.value[findIndex].bedId = 0;
- } else {
- studentUpdateList.value.splice(findIndex, 1);
- isAddDel = false;
- }
- } else {
- studentUpdateList.value.push({
- userId: item.studentUserId,
- bedId: 0,
- bedNumber: item.bedNumber,
- });
- }
- if (isAddDel) {
- if (!studentDeleted.value.find((row) => row.userId === item.studentUserId)) {
- studentDeleted.value.push({
- userId: item.studentUserId,
- userName: item.studentName,
- genderCn: item.genderCn,
- bedNumber: item.bedNumber,
- className: item.className,
- teacherId: item.teacherId,
- });
- }
- }
- item.className = null;
- item.studentName = '';
- item.studentUserId = '';
- } catch {}
- };
- const handelRoomEdit = async (item) => {
- if (!item.studentUserId) {
- try {
- if (studentSelected.value.length > 0) {
- const userInfo = studentSelectedList.value[0];
- if (item.genderCn !== userInfo.genderCn) {
- createMessage.error(`${item.genderCn}生寝室不能调入${userInfo.genderCn}生`);
- return;
- }
- // item.bedNumber = userInfo.bedNumber;
- item.className = userInfo.className;
- item.studentName = userInfo.studentName;
- item.studentUserId = userInfo.userId;
- item.teacherId = userInfo.teacherId;
- const findIndex = studentUpdateList.value.findIndex(
- (row) => row.userId === userInfo.userId,
- );
- if (findIndex > -1) {
- studentUpdateList.value[findIndex].bedId = item.id;
- } else {
- studentUpdateList.value.push({
- userId: userInfo.userId,
- bedId: item.id,
- bedNumber: userInfo.bedNumber,
- });
- }
- // studentUpdateList.value.push({
- // userId: userInfo.userId,
- // bedId: item.id,
- // bedNumber: userInfo.bedNumber,
- // });
- studentSelected.value.splice(0, 1);
- studentSelectedList.value.splice(0, 1);
- if (studentDeleted.value.find((row) => row.userId === userInfo.userId)) {
- studentDeleted.value.splice(
- studentDeleted.value.findIndex((row) => row.userId === userInfo.userId),
- 1,
- );
- }
- // await handelStudenSearch(false);
- // await handelRoomSearch();
- }
- } catch {}
- }
- };
- const handelRoomDeleteBath = async (list) => {
- list.forEach((item) => {
- if (classTeacher.value === true) {
- if (item.studentUserId && item.teacherId === userStore.getUserInfo.id) {
- handelRoomDelete(item);
- }
- } else {
- if (item.studentUserId) {
- handelRoomDelete(item);
- }
- }
- });
- };
- const getGroupClass = (data) => {
- const groupClass = groupBy(data, 'className');
- const resData: any[] = [];
- for (let item in groupClass) {
- if (item !== 'null') {
- resData.push({ className: item, total: groupClass[item].length });
- }
- }
- return resData;
- };
- const handelConfirm = async () => {
- if (studentDeleted.value.length > 0) {
- createMessage.info(`还有未分配完的学生!`);
- return;
- }
- if (studentUpdateList.value.length === 0) {
- createMessage.info(`没有调整的学生`);
- return;
- }
- saveLoading.value = true;
- try {
- const postData = studentUpdateList.value.map((item) => {
- return { studentUserId: item.userId, bedId: item.bedId };
- });
- await putRoomBedAdjustAdjustBedBatch(postData);
- await handelStudenSearch(true);
- await handelRoomSearch();
- createMessage.success(`调整成功`);
- } finally {
- // createMessage.error(`调整失败`);
- saveLoading.value = false;
- }
- };
- const getIsTeacher = async () => {
- const data = await getRoomBedAdjustIsClassTeacher({});
- classTeacher.value = data === 1;
- if (data === 1) {
- await handelStudenSearch(false);
- }
- };
- onMounted(async () => {
- await getIsTeacher();
- });
- </script>
- <style scoped lang="less">
- .student-list {
- margin-top: 8px;
- padding: 8px;
- background-color: #f7f7f7;
- border-radius: 8px;
- &:last-child {
- margin-bottom: 16px;
- }
- &-title {
- margin: 8px 0;
- }
- &-item {
- border: 2px dashed rgba(255, 182, 0, 0.4);
- background-color: rgba(255, 182, 0, 0.4);
- padding: 4px;
- cursor: pointer;
- &-ext {
- background-color: rgba(rgba(0, 255, 25, 0.4));
- border: 2px dashed rgba(rgba(0, 255, 25, 0.4));
- }
- &-active {
- border: 2px dashed rgba(rgba(14, 4, 150, 0.4));
- }
- &-text {
- display: flex;
- justify-content: space-between;
- }
- &-note {
- margin-top: 4px;
- text-align: center;
- word-break: keep-all;
- }
- }
- }
- .room {
- &-group {
- &-wrap {
- margin-top: 8px;
- padding: 8px;
- background-color: #f7f7f7;
- border-radius: 8px;
- }
- &-item {
- position: relative;
- }
- &-title {
- display: flex;
- justify-content: space-between;
- margin: 8px 0;
- }
- &-tool {
- display: flex;
- justify-content: flex-end;
- margin-top: 8px;
- &-item {
- padding: 4px 16px;
- background-color: rgb(48, 111, 253);
- font-size: 12px;
- color: #fff;
- cursor: pointer;
- }
- }
- }
- &-list {
- position: relative;
- &-item {
- position: relative;
- border: 1px solid rgb(121, 121, 121);
- background-color: #fff;
- text-align: center;
- cursor: pointer;
- &-text {
- height: 25px;
- display: block;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- &-number {
- margin-top: 8px;
- }
- &-delete {
- position: absolute;
- z-index: 1000;
- right: -8px;
- top: -8px;
- }
- }
- }
- }
- .student-del-list {
- margin: 8px;
- padding: 8px;
- background-color: #f7f7f7;
- display: flex;
- flex-wrap: wrap;
- &-item {
- padding: 8px 16px;
- cursor: pointer;
- &-active {
- background-color: rgba(rgba(0, 255, 25, 0.4));
- }
- }
- }
- </style>
|