会议管理

This commit is contained in:
FLL 2025-07-07 16:31:20 +08:00
parent 171d3ef133
commit 0e0b30d159
5 changed files with 301 additions and 12 deletions

View File

@ -1,6 +1,5 @@
import { initPreferences } from '@vben/preferences'; import { initPreferences } from '@vben/preferences';
import { unmountGlobalLoading } from '@vben/utils'; import { unmountGlobalLoading } from '@vben/utils';
import { overridesPreferences } from './preferences'; import { overridesPreferences } from './preferences';
/** /**
@ -27,5 +26,4 @@ async function initApplication() {
// 移除并销毁loading // 移除并销毁loading
unmountGlobalLoading(); unmountGlobalLoading();
} }
initApplication(); initApplication();

View File

@ -0,0 +1,127 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { cloneDeep } from '@vben/utils';
import dayjs, { Dayjs } from 'dayjs';
import { useVbenForm } from '#/adapter/form';
import { attachAdd, attachInfo, attachUpdate } from '#/api/property/roomBooking/conferenceAddServices';
import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup';
import { modalSchema } from './data';
import duration from "dayjs/plugin/duration";
import relativeTime from "dayjs/plugin/relativeTime";
dayjs.extend(duration);
dayjs.extend(relativeTime);
const emit = defineEmits<{ reload: [] }>();
const isUpdate = ref(false);
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-[60%]',
fullscreenButton: false,
onBeforeClose,
onClosed: handleClosed,
onConfirm: handleConfirm,
onOpenChange: async (isOpen) => {
if (!isOpen) {
return null;
}
modalApi.modalLoading(true);
const { id } = modalApi.getData() as { id?: number | string };
isUpdate.value = !!id;
if (isUpdate.value && id) {
const record = await attachInfo(id);
record.unit = record.unit?.toString();
record.state = record.state?.toString();
await formApi.setValues(record);
}
await markInitialized();
modalApi.modalLoading(false);
},
});
async function handleConfirm() {
try {
modalApi.lock(true);
const { valid } = await formApi.validate();
if (!valid) {
return;
}
// getValuesreadonly
const data = cloneDeep(await formApi.getValues());
await (isUpdate.value ? attachUpdate(data) : attachAdd(data));
resetInitialized();
emit('reload');
modalApi.close();
} catch (error) {
console.error(error);
} finally {
modalApi.lock(false);
}
}
async function handleClosed() {
await formApi.resetForm();
resetInitialized();
}
const CRDetail = ref({
})
</script>
<template>
<BasicModal title="会议室预约">
<div class="detail-box">
<div><span>会议室名称: 会议室01</span><span>容纳人数: 50</span></div>
<div><span>会议室地址: 5楼505</span><span>配套设备: 话筒音响大屏</span></div>
<div><span>会议室负责人: 王林</span><span>联系电话: 15809875678</span></div>
<div><span>基础费用: 600</span><span></span></div>
</div>
<BasicForm />
<div>
</div>
</BasicModal>
</template>
<style lang="scss">
.detail-box{
width: 100%;
div{
display: grid;
margin: 20px;
grid-template-columns: repeat(2, 1fr);
}
}
</style>

View File

@ -0,0 +1,92 @@
import type { FormSchemaGetter } from '#/adapter/form';
import {getDictOptions} from "#/utils/dict";
export const querySchema: FormSchemaGetter = () => [
{
component: 'Input',
fieldName: 'projectName',
label: '产品名称',
},
{
component: 'Select',
componentProps: {
options: getDictOptions('product_management_status'),
},
fieldName: 'state',
label: '状态',
},
];
export const modalSchema: FormSchemaGetter = () => [
{
label: '主键',
fieldName: 'id',
component: 'Input',
dependencies: {
show: () => false,
triggerFields: [''],
},
},
{
label: '会议预定人',
fieldName: 'projectName',
component: 'Input',
rules: 'required',
},
{
label: '使用单位',
fieldName: 'price',
component: 'Input',
rules: 'required',
},
{
label: '会议主题',
fieldName: 'price',
component: 'Input',
rules: 'required',
},
{
label: '预约日期',
fieldName: 'visitingTimeRange',
component: 'RangePicker',
componentProps: {
showTime: {
format: 'HH:mm:ss'
},
format: 'YYYY-MM-DD HH:mm:ss',
valueFormat: 'YYYY-MM-DD HH:mm:ss',
placeholder: ['开始时间', '结束时间']
},
rules: 'required',
},
{
label: '参会人数',
fieldName: 'price',
component: 'Input',
rules: 'required',
},
{
label: '参会人员',
fieldName: 'price',
component: 'Input',
rules: 'required',
},
// {
// label: '备注',
// fieldName: 'price',
// component: 'Input',
// rules: 'required',
// },
{
label: '是否需要增值服务',
fieldName: 'bookingParkingSpace',
component: 'RadioGroup',
componentProps: {
options: [
{ label: '是', value: '0' },
{ label: '否', value: '1' },
],
},
rules: 'required',
},
];

View File

@ -1,19 +1,79 @@
<template> <template>
<div> <div>
<div>请先填写以下信息查询可用会议室</div>
<a-form
:model="formState"
layout="inline"
@finish="onFinish"
@finishFailed="onFinishFailed"
class="form-box"
>
<a-form-item label="会议日期">
<a-date-picker
v-model:value="formState.username"
show-time
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择"
style="width: 330px; margin-right: 50px"
/>
</a-form-item>
<a-form-item label="参会人数" style="width: 400px;">
<a-input placeholder="请输入" v-model:value="formState.username"/>
</a-form-item>
<a-form-item class="form-button">
<a-button >重置</a-button>
<a-button type="primary" class="primary-button">搜索</a-button>
</a-form-item>
</a-form>
<div class="card-box"> <div class="card-box">
<div v-for="(item,index) in meetingList" :key="index" class="card-list"> <div v-for="(item,index) in meetingList" :key="index" class="card-list">
<div><span class="card-title">{{ item.one }}</span><a-button class="card-button" type="primary">去预约</a-button></div> <div><span class="card-title">{{ item.one }}</span><a-button class="card-button" type="primary" @click="handleAdd">去预约</a-button></div>
<div>容纳人数: {{ item.two }}</div> <div>容纳人数: {{ item.two }}</div>
<div>基础费用: {{ item.three }}</div> <div>基础费用: {{ item.three }}</div>
<div>基础服务: {{ item.four }}</div> <div>基础设备: {{ item.four }}</div>
<div>基础服务: {{ item.five }}</div> <div>基础服务: {{ item.five }}</div>
</div> </div>
</div> </div>
<modal/>
</div> </div>
</template> </template>
<script setup> <script setup lang="ts">
import { ref } from 'vue' import { ref } from 'vue'
import { reactive } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import {
Form as AForm,
FormItem as AFormItem,
Input as AInput,
Button as AButton,
DatePicker as ADatePicker,
RangePicker as ARangePicker
} from 'ant-design-vue';
import conferenceAddServicesModal from '../conferenceReservations/conferenceReservations-modal.vue';
interface FormState {
username: string;
password: string;
}
const formState = reactive<FormState>({
username: '',
password: '',
});
const [modal, modalApi] = useVbenModal({
connectedComponent: conferenceAddServicesModal,
});
function handleAdd() {
modalApi.setData({});
modalApi.open();
}
const onFinish = (values: any) => {
console.log('Success:', values);
};
const onFinishFailed = (errorInfo: any) => {
console.log('Failed:', errorInfo);
};
const meetingList = ref([ const meetingList = ref([
{ {
one: '10楼1002会议室', one: '10楼1002会议室',
@ -47,6 +107,20 @@ const meetingList = ref([
</script> </script>
<style lang="scss"> <style lang="scss">
.form-box{
width: 100%;
padding: 30px 30px 0 30px;
position: relative;
.form-button{
position: absolute;
right: 30px;
.primary-button{
margin-left: 15px;
}
}
}
.card-box{ .card-box{
width: 100%; width: 100%;
background-color: transparent; background-color: transparent;
@ -64,18 +138,15 @@ const meetingList = ref([
position: relative; position: relative;
.card-title{ .card-title{
font-size: 1.2vw; font-size: 25px;
font-weight: bold; font-weight: bold;
} }
div:nth-child(1){
margin-bottom: 5px;
}
div{ div{
line-height: 1.5vw; margin: 0.5vw 0;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
max-width: 200px; max-width: 300px;
.card-button{ .card-button{
right: 15px; right: 15px;

View File

@ -27,7 +27,8 @@ export default defineConfig(async () => {
changeOrigin: true, changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''), rewrite: (path) => path.replace(/^\/api/, ''),
// mock代理目标地址 // mock代理目标地址
target: 'http://192.168.0.106:8080', target: 'http://192.168.0.103:8080',
// target: 'http://192.168.0.106:8080',
// target: 'http://47.109.37.87:3010', // target: 'http://47.109.37.87:3010',
ws: true, ws: true,
}, },