<template>
|
<view style="background-color: #fff;"
|
class="client-visit-detail">
|
<PageHeader title="会议申请"
|
@back="goBack" />
|
<view>
|
<view v-for="item in applicationTypes"
|
:key="item.value"
|
class="application-type-item"
|
:class="{ active: meetingForm.applicationType === item.value }"
|
@click="selectApplicationType(item)">
|
<view class="application-type-info">
|
<view class="application-type-name">{{ item.name }}</view>
|
<view class="application-type-desc">{{ item.desc }}</view>
|
</view>
|
</view>
|
</view>
|
<u-form ref="formRef"
|
label-width="90">
|
<!-- 客户信息 -->
|
<u-cell-group title="会议申请">
|
<u-form-item label="会议主题"
|
prop="title"
|
required
|
border-bottom>
|
<u-input v-model="meetingForm.title"
|
placeholder="请输入会议主题" />
|
</u-form-item>
|
<u-form-item label="会议室"
|
prop="roomId"
|
required
|
border-bottom>
|
<u-input v-model="meetingForm.roomName"
|
placeholder="请选择会议室"
|
readonly
|
@click="showRoomPicker = true" />
|
<template #right>
|
<up-icon name="arrow-right"
|
@click="showRoomPicker = true"></up-icon>
|
</template>
|
</u-form-item>
|
<u-form-item label="主持人"
|
prop="host"
|
required
|
border-bottom>
|
<u-input v-model="meetingForm.host"
|
placeholder="请输入主持人姓名" />
|
</u-form-item>
|
<u-form-item label="会议日期"
|
prop="meetingDate"
|
required
|
border-bottom>
|
<u-input v-model="meetingForm.meetingDate"
|
placeholder="请选择会议日期"
|
readonly
|
@click="showDatePicker = true" />
|
<template #right>
|
<up-icon name="calendar"
|
@click="showDatePicker = true"></up-icon>
|
</template>
|
</u-form-item>
|
<u-form-item label="开始时间"
|
prop="startTime"
|
required
|
border-bottom>
|
<u-input v-model="meetingForm.startTime"
|
placeholder="请选择开始时间"
|
readonly
|
@click="showStartTimePicker = true" />
|
<template #right>
|
<up-icon name="clock"
|
@click="showStartTimePicker = true"></up-icon>
|
</template>
|
</u-form-item>
|
<u-form-item label="结束时间"
|
prop="endTime"
|
required
|
border-bottom>
|
<u-input v-model="meetingForm.endTime"
|
placeholder="请选择结束时间"
|
readonly
|
@click="showEndTimePicker = true" />
|
<template #right>
|
<up-icon name="clock"
|
@click="showEndTimePicker = true"></up-icon>
|
</template>
|
</u-form-item>
|
<u-form-item label="参会人员"
|
prop="participants"
|
required
|
border-bottom>
|
<u-input v-model="meetingForm.participantsNames"
|
placeholder="请选择参会人员"
|
readonly
|
@click="showEquipmentSheet = true" />
|
<template #right>
|
<up-icon name="arrow-right"
|
@click="openParticipantPicker"></up-icon>
|
</template>
|
</u-form-item>
|
<u-form-item label="会议说明"
|
prop="description"
|
border-bottom>
|
<u-input v-model="meetingForm.description"
|
placeholder="请输入会议说明" />
|
</u-form-item>
|
</u-cell-group>
|
<!-- 提交按钮 -->
|
</u-form>
|
<view class="footer-btns">
|
<u-button class="cancel-btn"
|
@click="resetForm">重置</u-button>
|
<u-button class="save-btn"
|
@click="handleSubmit">保存</u-button>
|
</view>
|
<!-- 日期选择器 -->
|
<up-datetime-picker v-model="meetingForm.meetingDate"
|
mode="date"
|
:show="showDatePicker"
|
@confirm="onDateSelect"
|
@cancel="showDatePicker = false"
|
format="YYYY-MM-DD"
|
value-format="YYYY-MM-DD"
|
:min-date="minDate" />
|
<!-- 开始时间选择器 -->
|
<up-action-sheet :show="showStartTimePicker"
|
:actions="timeOptions"
|
@select="onStartTimeSelect"
|
@close="showStartTimePicker = false" />
|
<!-- 结束时间选择器 -->
|
<up-action-sheet :show="showEndTimePicker"
|
:actions="timeOptions"
|
@select="onEndTimeSelect"
|
@close="showEndTimePicker = false" />
|
<!-- 会议室选择器 -->
|
<up-action-sheet :show="showRoomPicker"
|
:actions="meetingRooms"
|
@select="onRoomSelect"
|
@close="showRoomPicker = false" />
|
<u-popup :show="showEquipmentSheet"
|
mode="bottom"
|
@close="showEquipmentSheet = false"
|
height="200px">
|
<view class="popup-content">
|
<view class="popup-body">
|
<u-checkbox-group v-model="meetingForm.participants"
|
@change="handleParticipantChange"
|
icon-placement="right"
|
placement="row">
|
<view style="width:100%;padding:10px;margin-top:20px;">
|
<u-checkbox v-for="option in employees"
|
:key="option.id"
|
:name="option.id"
|
:label="`${option.staffName} (${option.postJob})`"
|
class="checkbox-item"></u-checkbox>
|
</view>
|
</u-checkbox-group>
|
</view>
|
</view>
|
</u-popup>
|
</view>
|
</template>
|
|
<script setup>
|
// 替换 toast 方法
|
defineOptions({ name: "meeting-settings-detail" });
|
const showToast = message => {
|
uni.showToast({
|
title: message,
|
icon: "none",
|
});
|
};
|
|
import { ref, reactive, onMounted, computed } from "vue";
|
import PageHeader from "@/components/PageHeader.vue";
|
import useUserStore from "@/store/modules/user";
|
import {
|
saveMeetingApplication,
|
getRoomEnum,
|
} from "@/api/managementMeetings/meeting";
|
import { getStaffOnJob } from "@/api/personnelManagement/onboarding";
|
import dayjs from "dayjs";
|
|
const userStore = useUserStore();
|
|
// 表单数据
|
const meetingForm = reactive({
|
title: "",
|
type: "",
|
roomId: "",
|
roomName: "",
|
host: "",
|
meetingDate: "",
|
startTime: "",
|
endTime: "",
|
participants: [],
|
description: "",
|
participantsNames: [],
|
applicationType: "department",
|
});
|
// 申请类型选项
|
const applicationTypes = ref([
|
{
|
value: "approval",
|
name: "审批流程会议",
|
desc: "需要经过多级审批的会议申请",
|
// icon: Document,
|
},
|
{
|
value: "department",
|
name: "部门级会议",
|
desc: "部门内部会议申请流程",
|
// icon: Promotion,
|
},
|
{
|
value: "notification",
|
name: "会议通知",
|
desc: "无需审批直接发布的会议通知",
|
// icon: Bell,
|
},
|
]);
|
// 页面状态
|
const loading = ref(false);
|
const formRef = ref(null);
|
const showDatePicker = ref(false);
|
const showStartTimePicker = ref(false);
|
const showEndTimePicker = ref(false);
|
const showRoomPicker = ref(false);
|
|
// 最小日期(今天)
|
const minDate = computed(() => {
|
return dayjs().format("YYYY-MM-DD");
|
});
|
|
// 选择申请类型
|
const selectApplicationType = item => {
|
meetingForm.applicationType = item.value;
|
};
|
|
// 返回上一页
|
const goBack = () => {
|
uni.navigateBack();
|
};
|
const showEquipmentSheet = ref(false);
|
const openParticipantPicker = () => {
|
showEquipmentSheet.value = true;
|
};
|
|
// 重置表单
|
const resetForm = () => {
|
meetingForm.title = "";
|
meetingForm.type = "";
|
meetingForm.roomId = "";
|
meetingForm.roomName = "";
|
meetingForm.host = "";
|
meetingForm.meetingDate = "";
|
meetingForm.startTime = "";
|
meetingForm.endTime = "";
|
meetingForm.participants = [];
|
meetingForm.participantsNames = [];
|
meetingForm.description = "";
|
meetingForm.applicationType = "department";
|
};
|
const handleParticipantChange = val => {
|
console.log("val", val);
|
|
meetingForm.participants = val;
|
meetingForm.participantsNames = employees.value
|
.filter(employee => val.includes(employee.id))
|
.map(employee => employee.staffName);
|
};
|
// 提交表单
|
const handleSubmit = async () => {
|
console.log("meetingForm", meetingForm);
|
if (!meetingForm.title) {
|
showToast("请输入会议主题");
|
return;
|
}
|
|
if (!meetingForm.roomId) {
|
showToast("请选择会议室");
|
return;
|
}
|
|
if (!meetingForm.host) {
|
showToast("请输入主持人");
|
return;
|
}
|
|
if (!meetingForm.meetingDate) {
|
showToast("请选择会议日期");
|
return;
|
}
|
|
if (!meetingForm.startTime) {
|
showToast("请选择开始时间");
|
return;
|
}
|
|
if (!meetingForm.endTime) {
|
showToast("请选择结束时间");
|
return;
|
}
|
|
if (!meetingForm.participants) {
|
showToast("请选择参会人员");
|
return;
|
}
|
|
// 验证开始时间必须小于结束时间
|
if (meetingForm.startTime >= meetingForm.endTime) {
|
showToast("开始时间必须小于结束时间");
|
return;
|
}
|
|
try {
|
loading.value = true;
|
|
let formData = { ...meetingForm };
|
formData.startTime = `${meetingForm.meetingDate} ${meetingForm.startTime}:00`;
|
formData.endTime = `${meetingForm.meetingDate} ${meetingForm.endTime}:00`;
|
formData.participants = JSON.stringify(meetingForm.participants);
|
|
console.log(formData);
|
|
// 调用实际的API
|
const res = await saveMeetingApplication(formData);
|
|
if (res.code === 200) {
|
showToast("保存成功");
|
setTimeout(() => {
|
goBack();
|
}, 500);
|
} else {
|
showToast(res.message || "保存失败,请重试");
|
}
|
} catch (e) {
|
console.error("保存失败:", e);
|
showToast("保存失败,请重试");
|
} finally {
|
loading.value = false;
|
}
|
};
|
// 日期选择器确认回调
|
const onDateSelect = action => {
|
console.log(action.value);
|
|
if (action.value) {
|
meetingForm.meetingDate = dayjs(action.value).format("YYYY-MM-DD");
|
} else {
|
meetingForm.meetingDate = dayjs().format("YYYY-MM-DD");
|
}
|
|
showDatePicker.value = false;
|
};
|
const onStartTimeSelect = action => {
|
meetingForm.startTime = action.value;
|
showStartTimePicker.value = false;
|
};
|
const onEndTimeSelect = action => {
|
meetingForm.endTime = action.value;
|
showEndTimePicker.value = false;
|
};
|
|
// 会议室选择回调
|
const onRoomSelect = action => {
|
meetingForm.roomId = action.id;
|
meetingForm.roomName = action.name;
|
showRoomPicker.value = false;
|
};
|
// 时间选项(以半小时为间隔)
|
const timeOptions = ref([]);
|
|
// 初始化时间选项
|
const initTimeOptions = () => {
|
const options = [];
|
for (let hour = 8; hour <= 18; hour++) {
|
// 每个小时添加两个选项:整点和半点
|
options.push({
|
value: `${hour.toString().padStart(2, "0")}:00`,
|
name: `${hour.toString().padStart(2, "0")}:00`,
|
});
|
|
if (hour < 18) {
|
// 18:00之后没有半点选项
|
options.push({
|
value: `${hour.toString().padStart(2, "0")}:30`,
|
name: `${hour.toString().padStart(2, "0")}:30`,
|
});
|
}
|
}
|
timeOptions.value = options;
|
};
|
// 会议室列表
|
const employees = ref([]);
|
const meetingRooms = ref([]);
|
const getMeetingRooms = async () => {
|
try {
|
const res = await getRoomEnum();
|
if (res.code === 200) {
|
meetingRooms.value = res.data || [];
|
} else {
|
showToast(res.message || "获取会议室列表失败");
|
}
|
} catch (e) {
|
console.error("获取会议室列表失败:", e);
|
showToast("获取会议室列表失败,请重试");
|
}
|
};
|
|
onMounted(() => {
|
initPageData();
|
initTimeOptions();
|
getMeetingRooms();
|
getStaffOnJob().then(res => {
|
employees.value = res.data.sort((a, b) =>
|
a.postJob.localeCompare(b.postJob)
|
);
|
});
|
});
|
|
const initPageData = () => {
|
// 初始化数据
|
};
|
</script>
|
|
<style scoped lang="scss">
|
@import "@/static/scss/form-common.scss";
|
|
.footer-btns {
|
position: fixed;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
background: #fff;
|
display: flex;
|
justify-content: space-around;
|
align-items: center;
|
padding: 0.75rem 0;
|
box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05);
|
z-index: 1000;
|
}
|
|
.cancel-btn {
|
font-weight: 400;
|
font-size: 1rem;
|
color: #ffffff;
|
width: 6.375rem;
|
background: #c7c9cc;
|
box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
|
border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
|
}
|
|
.save-btn {
|
font-weight: 400;
|
font-size: 1rem;
|
color: #ffffff;
|
width: 14rem;
|
background: linear-gradient(140deg, #00baff 0%, #006cfb 100%);
|
box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
|
border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
|
}
|
.application-type-item {
|
width: 94%;
|
margin-left: 3%;
|
// height: 120rpx;
|
background-color: #f1f1f1;
|
border-radius: 10rpx;
|
margin-top: 20rpx;
|
padding: 20rpx;
|
box-shadow: 0 2rpx 12rpx 0 rgba(246, 244, 244, 0.1);
|
transition: box-shadow 0.3s ease;
|
}
|
.application-type-item.active {
|
box-shadow: 0 4rpx 16rpx 0 rgba(0, 0, 0, 0.15);
|
background-color: #fff;
|
border: 1rpx solid #0078a3;
|
}
|
|
.application-type-name {
|
font-weight: 400;
|
font-size: 1rem;
|
color: #000000;
|
}
|
.application-type-item.active .application-type-name {
|
color: #0078a3;
|
}
|
.application-type-desc {
|
font-weight: 400;
|
font-size: 0.875rem;
|
margin-top: 0.5rem;
|
color: #757575;
|
}
|
.application-type-item.active .application-type-desc {
|
color: #0078a3;
|
}
|
</style>
|