feat: 优化大屏

This commit is contained in:
fyy
2025-08-05 17:07:10 +08:00
parent c847bd29e1
commit 2beb771185
24 changed files with 1671 additions and 1481 deletions

View File

@@ -34,12 +34,47 @@ const isUpdate = ref(false);
const title = computed(() => {
return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add');
});
//表单项
let formModel = reactive<{
id: string;
groupId: string;
attendanceType: string;
dateType: number | undefined;
startDate: string;
endDate: string;
userGroupList: any[];
}>({
id: '',
groupId: '',
attendanceType: '', //考勤组类型
dateType: undefined, //日期类型1-单个日期2-长期有效3-期间有效
// dateSingle: null,
// dateLong: null,
// dateRange: [null, null],
startDate: '', //开始日期
endDate: '', //结束日期
userGroupList: [
// scheduleId:undefined,//排班ID
// employeeId:undefined,//员工ID
// employeeName:undefined,//员工姓名
// deptId:undefined,//部门ID
// deptName:undefined,//部门名称
], //考勤组人员列表
});
const formRef = ref();
let singleDate = ref(''); //排班日期单个日期
let longDate = ref(''); //排班日期从此日起长期有效
let rangeDate = ref(['', '']); //排班日期在此期间有效
const rules = {
groupId: [{ required: true, message: '请选择考勤组' }],
attendanceType: [{ required: true }],
dateType: [{ required: true, message: '请选择排班日期' }],
};
const groupOptions = ref<any[]>([]);
const groupMap = ref<Record<string, any>>({}); // 用于快速查找
const tableData = reactive<
let tableData = reactive<
{ dept: { unitId: string | number; unitName: string }; users: PersonVO[] }[]
>([]);
>([]); //存放考勤组人员列表数据
const columns = [
{
title: '序号',
@@ -108,44 +143,44 @@ function handleRemoveRow(index: number) {
}
function handleTableData(newTableData: any) {
tableData.splice(0, tableData.length, ...newTableData);
// 如果现有数据为空,直接替换
if (tableData.length === 0) {
tableData.splice(0, 0, ...newTableData);
return;
}
// 如果新数据为空,不做处理
if (newTableData.length === 0) {
return;
}
// 处理有数据的情况
for (const newItem of newTableData) {
// 查找是否已存在相同部门
const existingDeptIndex = tableData.findIndex(
(item) => item.dept.unitId === newItem.dept.unitId,
);
if (existingDeptIndex !== -1) {
// 找到相同部门,检查人员是否有重复
const existingDept = tableData[existingDeptIndex];
for (const newUser of newItem.users) {
// 检查该用户是否已存在
const userExists = existingDept?.users.some(
(existingUser) => existingUser.id === newUser.id,
);
if (!userExists) {
// 用户不存在,添加到现有部门
existingDept?.users.push(newUser);
}
}
} else {
// 部门不存在,直接添加新部门
tableData.push(newItem);
}
}
}
//表单项
const formModel = reactive<{
id: string;
groupId: string;
attendanceType: string;
dateType: number | undefined;
startDate: string;
endDate: string;
userGroupList: any[];
}>({
id: '',
groupId: '',
attendanceType: '', //考勤组类型
dateType: undefined, //日期类型1-单个日期2-长期有效3-期间有效
// dateSingle: null,
// dateLong: null,
// dateRange: [null, null],
startDate: '', //开始日期
endDate: '', //结束日期
userGroupList: [
// scheduleId:undefined,//排班ID
// employeeId:undefined,//员工ID
// employeeName:undefined,//员工姓名
// deptId:undefined,//部门ID
// deptName:undefined,//部门名称
], //考勤组人员列表
});
const singleDate = ref('');
const longDate = ref('');
const rangeDate = ref(['', '']);
const formRef = ref();
const rules = {
groupId: [{ required: true, message: '请选择考勤组' }],
attendanceType: [{ required: true }],
dateType: [{ required: true, message: '请选择排班日期' }],
};
const [BasicForm, formApi] = useVbenForm({
commonConfig: {
// 默认占满两列
@@ -173,7 +208,7 @@ const [UnitPersonModal, unitPersonmodalApi] = useVbenModal({
});
const [BasicModal, modalApi] = useVbenModal({
// 在这里更改宽度
class: 'w-[70%]',
class: 'w-[85%]',
fullscreenButton: false,
onBeforeClose,
onClosed: handleClosed,
@@ -183,7 +218,6 @@ const [BasicModal, modalApi] = useVbenModal({
return null;
}
await getGroupList();
console.log(getDictOptions('wy_kqlx'));
modalApi.modalLoading(true);
const { id } = modalApi.getData() as { id?: number | string };
isUpdate.value = !!id;
@@ -220,7 +254,6 @@ async function getGroupList() {
});
}
function chooseGroup(value: any) {
console.log(value);
const group = groupMap.value[value];
if (group) {
formModel.attendanceType = String(group.attendanceType);
@@ -232,12 +265,10 @@ async function handleDateTypeChange(value: any) {
async function handleConfirm() {
try {
modalApi.lock(true);
// await formRef.value.validate(); // 先校验
await formRef.value.validate(); // 先校验
const data = formModel;
const { id } = modalApi.getData() as { id?: string };
data.id = id ? id : '';
console.log(data);
if (data.dateType == 1) {
if (singleDate.value) {
data.startDate = dayjs(singleDate.value).format('YYYY-MM-DD');
@@ -264,10 +295,36 @@ async function handleConfirm() {
data.endDate = dayjs(rangeDate.value[1]).format('YYYY-MM-DD');
}
}
// await (isUpdate.value ? arrangementUpdate(data) : arrangementAdd(data));
for (const item of tableData) {
for (const user of item.users) {
data.userGroupList.push({
deptId: item.dept.unitId, //部门ID
deptName: item.dept.unitName, //部门名称
employeeId: user.id, //员工ID
employeeName: user.userName, //员工姓名
});
}
}
await (isUpdate.value ? arrangementUpdate(data) : arrangementAdd(data));
resetInitialized();
emit('reload');
// 重置表单数据
Object.assign(formModel, {
id: '',
groupId: '',
attendanceType: '',
dateType: undefined,
startDate: '',
endDate: '',
userGroupList: [],
});
// 重置其他数据
tableData.length = 0;
singleDate.value = '';
longDate.value = '';
rangeDate.value = ['', ''];
modalApi.close();
await formApi.resetForm();
} catch (error) {
console.error(error);
} finally {
@@ -276,8 +333,27 @@ async function handleConfirm() {
}
async function handleClosed() {
// 重置表单数据
Object.assign(formModel, {
id: '',
groupId: '',
attendanceType: '',
dateType: undefined,
startDate: '',
endDate: '',
userGroupList: [],
});
// 重置其他数据
tableData.length = 0;
singleDate.value = '';
longDate.value = '';
rangeDate.value = ['', ''];
// 重置表单状态
await formApi.resetForm();
resetInitialized();
modalApi.close();
}
onMounted(() => {});
</script>

View File

@@ -1,11 +1,13 @@
<script lang="ts" setup>
import { Radio, Button, Calendar, DatePicker } from 'ant-design-vue';
import { Radio, Button, Calendar, DatePicker, message } from 'ant-design-vue';
import type { RadioChangeEvent, BadgeProps } from 'ant-design-vue';
import { ref } from 'vue';
import { ref, onMounted, reactive } from 'vue';
import { Dayjs } from 'dayjs';
import dayjs from 'dayjs';
import arrangementModal from './arrangement-modal.vue';
import { useVbenModal } from '@vben/common-ui';
import type { PersonVO } from './type';
import { arrangementCalender } from '#/api/property/attendanceManagement/arrangement'; // 导入接口
const emit = defineEmits<{
(e: 'changeView', value: boolean): void;
}>();
@@ -13,6 +15,57 @@ const props = defineProps<{
viewMode: 'calender' | 'schedule';
}>();
const selectedDate = ref();
const calendarData = reactive<any[]>([]);
const loading = ref(false);
// 查询日历数据
const fetchCalendarData = async (month?: string) => {
try {
loading.value = true;
const params = {
month:
month ||
selectedDate.value?.format('YYYY-MM') ||
dayjs().format('YYYY-MM'),
};
const res = await arrangementCalender(params);
const currentMonth =
month ||
selectedDate.value?.format('YYYY-MM') ||
dayjs().format('YYYY-MM'); //当前月份的开始日期
// 生成日历渲染数据结构
for (const row of res.rows) {
if (row.endDate) {
//当开始时间小于当前月份的开始日期
if (row.startDate <= currentMonth) {
console.log(row, '小');
//如果结束时间小于当前月份的结束时间则生成当前月份开始时间到row.endDate结束时间的n条数据
//如果结束时间大于等于当前月份的结束时间则生成当前月份开始时间到当前月份结束时间即当前月份天数的n条数据
} else {
//当开始时间大于当前月份的开始日期
//如果结束时间小于当前月份的结束时间则生成开始时间到结束时间的n条数据
console.log(row, '大');
}
} else {
calendarData.push({
data: row.startDate,
item: {
id: row.id,
groupName: row.attendanceGroup.groupName,
groupId: row.attendanceGroup.id,
},
});
}
}
// if (response) {
// calendarData.value = response.data || [];
// console.log('日历数据:', calendarData.value);
// }
} finally {
loading.value = false;
}
};
// 切换视图模式
function handleViewModeChange(e: RadioChangeEvent): void {
// 将父组件的isCalenderView变为true
@@ -28,13 +81,22 @@ const scheduleData: {
{ date: '2025-07-06', list: [{ type: 'success', content: '8月8日事件' }] },
// ...
];
const getListData2 = (
current: Dayjs,
): { type: BadgeProps['status']; content: string }[] => {
const dateStr = current.format('YYYY-MM-DD');
const found = scheduleData.find((item) => item.date === dateStr);
return found ? found.list : [];
// 优先使用接口数据
if (calendarData.length > 0) {
const found = calendarData.find((item) => item.date === dateStr);
if (found) {
return found.list || [];
}
}
// 如果没有找到数据,返回空数组
return [];
};
const getListData = (
value: Dayjs,
): { type: BadgeProps['status']; content: string }[] => {
@@ -84,6 +146,11 @@ function handleAdd() {
modalApi.setData({});
modalApi.open();
}
// 页面初始化时加载数据
onMounted(() => {
fetchCalendarData();
});
</script>
<template>
<div class="flex h-full flex-col">
@@ -98,7 +165,11 @@ function handleAdd() {
</Radio.Group>
<div class="my-auto flex gap-1">
<div class="my-auto">排班日历</div>
<DatePicker picker="month" v-model:value="selectedDate" />
<DatePicker
picker="month"
v-model:value="selectedDate"
@change="fetchCalendarData()"
/>
</div>
</div>
<div>
@@ -110,6 +181,7 @@ function handleAdd() {
v-model:value="selectedDate"
:mode="'month'"
:headerRender="customHeader"
:loading="loading"
>
<template #dateCellRender="{ current }">
<ul class="events">
@@ -140,7 +212,7 @@ function handleAdd() {
</template>
</Calendar>
</div>
<ArrangementModal @reload="" />
<ArrangementModal @reload="fetchCalendarData()" />
</div>
</template>
<style scoped>

View File

@@ -62,10 +62,10 @@ const deptTree = reactive<
]);
//勾选内容
const selectedUsers = ref<PersonVO[]>([]);
let selectedUsers = ref<PersonVO[]>([]);
//已选内容,需要展示到父组件
const tableData = reactive<
let tableData = reactive<
{
dept: { unitId: string | number; unitName: string };
users: PersonVO[];
@@ -236,6 +236,8 @@ async function handleConfirm() {
console.log(tableData);
resetInitialized();
emit('reload', tableData);
tableData = [];
selectedUsers.value =[];
modalApi.close();
} catch (error) {
console.error(error);