admin-vben5/apps/web-antd/src/views/property/roomBooking/conferenceReservations/conferenceReservations-modal.vue
2025-07-10 16:20:21 +08:00

239 lines
7.1 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.

<script setup lang="ts">
import {useVbenModal} from '@vben/common-ui';
import {cloneDeep} from '@vben/utils';
import {useVbenForm} from '#/adapter/form';
import {attachListAll} from '#/api/property/roomBooking/conferenceAddServices';
import {meetInfo} from '#/api/property/roomBooking/conferenceSettings';
import {defaultFormValueGetter, useBeforeCloseDiff} from '#/utils/popup';
import {modalSchema} from './data';
import type {conferenceSettingsDetail} from "#/api/property/roomBooking/conferenceSettings/model";
import type {AttachVO} from "#/api/property/roomBooking/conferenceAddServices/model";
import {addServiceColumns} from "./data";
import {Table, InputNumber, TimeRangePicker} from "ant-design-vue";
import {renderDictValue} from "#/utils/render";
import {personList} from "#/api/property/resident/person";
import {resident_unitList} from "#/api/property/resident/unit";
import {reservationAdd} from "#/api/property/roomBooking/conferenceReservations";
import {ref} from "vue";
const emit = defineEmits<{ reload: [] }>();
const conferenceSettingDetail = ref<conferenceSettingsDetail>()
const addServiceList = ref<AttachVO[]>([])
const totalAmount = ref<number>(0)
const [BasicForm, formApi] = useVbenForm({
commonConfig: {
// 默认占满两列
formItemClass: 'col-span-1',
// 默认label宽度 px
labelWidth: 80,
// 通用配置项 会影响到所有表单项
componentProps: {
class: 'w-full',
}
},
schema: modalSchema(),
showDefaultActions: false,
wrapperClass: 'grid-cols-2',
});
const {onBeforeClose, markInitialized, resetInitialized} = useBeforeCloseDiff(
{
initializedGetter: defaultFormValueGetter(formApi),
currentGetter: defaultFormValueGetter(formApi),
},
);
const [BasicModal, modalApi] = useVbenModal({
class: 'w-[70%]',
fullscreenButton: false,
onBeforeClose,
onClosed: handleClosed,
onConfirm: handleConfirm,
onOpenChange: async (isOpen) => {
if (!isOpen) {
return null;
}
modalApi.modalLoading(true);
await handleOpenChange()
await queryAddServices()
await queryPersonData()
await queryUnitData()
await formApi.setValues({
attach: '1',
})
await markInitialized();
modalApi.modalLoading(false);
},
});
async function handleConfirm() {
try {
modalApi.lock(true);
const {valid} = await formApi.validate();
if (!valid) {
return;
}
// getValues获取为一个readonly的对象 需要修改必须先深拷贝一次
const data = cloneDeep(await formApi.getValues());
data.meetId=conferenceSettingDetail.value?.id;
data.name=conferenceSettingDetail.value?.name;
if (data.timeSpan && data.timeSpan.length) {
data.scheduledStarttime = data.timeSpan[0]?.format("HH:mm");
data.scheduledEndtime = data.timeSpan[1]?.format("HH:mm");
}
data.price=totalAmount.value
if(data.attach=='0'){
data.meetAttachOrderBoList=addServiceList.value.filter(item=>item.quantity>0);
}
await (reservationAdd(data));
resetInitialized();
emit('reload');
modalApi.close();
} catch (error) {
console.error(error);
} finally {
modalApi.lock(false);
}
}
async function handleClosed() {
await formApi.resetForm();
resetInitialized();
}
async function handleOpenChange() {
const {id} = modalApi.getData() as { id?: number };
if (id) {
conferenceSettingDetail.value = await meetInfo(id);
}
}
async function queryAddServices() {
const res = await attachListAll()
addServiceList.value = res.map(item => ({
meetAttachId: item.id,
projectName: item.projectName,
price: item.price,
unit: item.unit,
quantity: 0
}))
console.log(res,addServiceList.value);
}
async function queryPersonData() {
let params = {
pageSize: 1000,
pageNum: 1,
}
const res = await personList(params);
const options = res.rows.map((user) => ({
label: user.userName + '-' + renderDictValue(user.gender, 'sys_user_sex') + '-' + user.phone,
value: user.id,
}));
formApi.updateSchema([{
componentProps: () => ({
options: options,
filterOption: filterOption
}),
fieldName: 'person',
}])
}
async function queryUnitData() {
let params = {
pageSize: 1000,
pageNum: 1,
}
const res = await resident_unitList(params);
const options = res.rows.map((item) => ({
label: item.name,
value: item.id,
}));
formApi.updateSchema([{
componentProps: () => ({
options: options,
filterOption: filterOption
}),
fieldName: 'unit',
}])
}
const filterOption = (input: string, option: any) => {
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0;
};
async function changeProjectNum() {
totalAmount.value = 0;
addServiceList.value.forEach(item => {
totalAmount.value += item.price * item.quantity
})
}
</script>
<template>
<BasicModal title="会议室预约">
<div class="detail-box" v-if="conferenceSettingDetail">
<div>
<span>会议室名称: {{ conferenceSettingDetail.name }}</span>
<span>容纳人数: {{ conferenceSettingDetail.personNumber }}</span>
</div>
<div><span>会议室地址: {{ conferenceSettingDetail.locationName }}</span>
<span>配套设备: {{ conferenceSettingDetail.baseService }}</span>
</div>
<div><span>会议室负责人: {{ conferenceSettingDetail.principalsName }}</span>
<span>联系电话: {{ conferenceSettingDetail.phoneNo }}</span>
</div>
<div><span>基础费用: {{
conferenceSettingDetail.expenseType == '2' ? conferenceSettingDetail.basePrice + '元' :
renderDictValue(conferenceSettingDetail.expenseType, 'wy_fyms')
}}</span>
<span>开放时段{{ conferenceSettingDetail.openHours }}</span>
</div>
</div>
<BasicForm>
<template #timeSpan="slotProps">
<TimeRangePicker style="width: 200px;" format="HH:mm"
v-bind="slotProps"></TimeRangePicker>
</template>
<template #serverInfo="slotProps">
<Table :dataSource="addServiceList" v-bind="slotProps" :columns="addServiceColumns"
:pagination="false"
size="small" :show-header="false" bordered>
<template #bodyCell="{ column, record, index }">
<template v-if="column.field === 'price'">
{{ record.price + '元/' + renderDictValue(record.unit, 'pro_product_unit') }}
</template>
<template v-else-if="column.field === 'quantity'">
<InputNumber id="inputNumber" v-model:value="record.quantity" :min="0"
:precision="0" @change="changeProjectNum"/>
</template>
<template v-else>
{{ record[column.field] }}
</template>
</template>
<template #footer v-if="totalAmount">
<div style="text-align: right;margin-right: 20px">
<b>总金额(元):</b>
{{ totalAmount }}
</div>
</template>
</Table>
</template>
</BasicForm>
</BasicModal>
</template>
<style lang="scss">
.detail-box {
width: 100%;
div {
display: grid;
margin: 20px;
grid-template-columns: repeat(2, 1fr);
}
}
</style>