feat: 个人中心
This commit is contained in:
@@ -7,6 +7,7 @@ import dayjs from 'dayjs';
|
||||
import arrangementModal from './arrangement-modal.vue';
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
import { arrangementCalender } from '#/api/property/attendanceManagement/arrangement'; // 导入接口
|
||||
import { Modal } from 'ant-design-vue';
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'changeView', value: boolean): void;
|
||||
@@ -19,6 +20,8 @@ const calendarData = reactive<any[]>([]);
|
||||
const loading = ref(false);
|
||||
// 查询日历数据
|
||||
const fetchCalendarData = async (month?: string) => {
|
||||
console.log(123);
|
||||
|
||||
try {
|
||||
loading.value = true;
|
||||
const params = {
|
||||
@@ -32,47 +35,150 @@ const fetchCalendarData = async (month?: string) => {
|
||||
month ||
|
||||
selectedDate.value?.format('YYYY-MM') ||
|
||||
dayjs().format('YYYY-MM'); //当前月份的开始日期
|
||||
|
||||
// 清空之前的数据
|
||||
calendarData.length = 0;
|
||||
|
||||
// 生成日历渲染数据结构
|
||||
for (const row of res.rows) {
|
||||
if (row.endDate) {
|
||||
const startDate = dayjs(row.startDate);
|
||||
const endDate = dayjs(row.endDate);
|
||||
const currentMonthStart = dayjs(currentMonth).startOf('month');
|
||||
const currentMonthEnd = dayjs(currentMonth).endOf('month');
|
||||
|
||||
//当开始时间小于当前月份的开始日期
|
||||
if (row.startDate <= currentMonth) {
|
||||
console.log(row, '小');
|
||||
|
||||
if (startDate.isBefore(currentMonthStart) || startDate.isSame(currentMonthStart, 'day')) {
|
||||
console.log(row, '小 - 开始时间小于等于当前月份开始时间');
|
||||
console.log('开始时间:', row.startDate);
|
||||
console.log('结束时间:', row.endDate);
|
||||
console.log('当前月份开始:', currentMonthStart.format('YYYY-MM-DD'));
|
||||
console.log('当前月份结束:', currentMonthEnd.format('YYYY-MM-DD'));
|
||||
|
||||
//如果结束时间小于当前月份的结束时间,则生成当前月份开始时间到row.endDate结束时间的n条数据
|
||||
//如果结束时间大于等于当前月份的结束时间,则生成当前月份开始时间到当前月份结束时间(即当前月份天数)的n条数据
|
||||
|
||||
// 确定结束日期:取row.endDate和当前月份结束日期的较小值
|
||||
const actualEndDate = endDate.isBefore(currentMonthEnd) ? endDate : currentMonthEnd;
|
||||
console.log('实际结束日期:', actualEndDate.format('YYYY-MM-DD'));
|
||||
|
||||
// 生成从当前月份开始到实际结束日期的数据
|
||||
let currentDate = currentMonthStart;
|
||||
let generatedCount = 0;
|
||||
while (currentDate.isSame(actualEndDate, 'day') || currentDate.isBefore(actualEndDate, 'day')) {
|
||||
calendarData.push({
|
||||
date: currentDate.format('YYYY-MM-DD'),
|
||||
item: {
|
||||
id: row.id,
|
||||
groupName: row.attendanceGroup.groupName,
|
||||
groupId: row.attendanceGroup.id,
|
||||
startDate: row.startDate,
|
||||
endDate: row.endDate,
|
||||
},
|
||||
});
|
||||
generatedCount++;
|
||||
currentDate = currentDate.add(1, 'day');
|
||||
}
|
||||
console.log(`生成了 ${generatedCount} 条数据`);
|
||||
} else {
|
||||
//当开始时间大于当前月份的开始日期
|
||||
//如果结束时间小于当前月份的结束时间,则生成开始时间到结束时间的n条数据
|
||||
console.log(row, '大');
|
||||
console.log(row, '大 - 开始时间大于当前月份开始时间');
|
||||
console.log('开始时间:', row.startDate);
|
||||
console.log('结束时间:', row.endDate);
|
||||
console.log('当前月份开始:', currentMonthStart.format('YYYY-MM-DD'));
|
||||
console.log('当前月份结束:', currentMonthEnd.format('YYYY-MM-DD'));
|
||||
|
||||
// 确定结束日期:取row.endDate和当前月份结束日期的较小值
|
||||
const actualEndDate = endDate.isBefore(currentMonthEnd) ? endDate : currentMonthEnd;
|
||||
console.log('实际结束日期:', actualEndDate.format('YYYY-MM-DD'));
|
||||
|
||||
// 生成从开始日期到实际结束日期的数据
|
||||
let currentDate = startDate;
|
||||
let generatedCount = 0;
|
||||
while (currentDate.isSame(actualEndDate, 'day') || currentDate.isBefore(actualEndDate, 'day')) {
|
||||
calendarData.push({
|
||||
date: currentDate.format('YYYY-MM-DD'),
|
||||
item: {
|
||||
id: row.id,
|
||||
groupName: row.attendanceGroup.groupName,
|
||||
groupId: row.attendanceGroup.id,
|
||||
startDate: row.startDate,
|
||||
endDate: row.endDate,
|
||||
},
|
||||
});
|
||||
generatedCount++;
|
||||
currentDate = currentDate.add(1, 'day');
|
||||
}
|
||||
console.log(`生成了 ${generatedCount} 条数据`);
|
||||
}
|
||||
} else {
|
||||
// 没有结束日期的情况,只在开始日期添加一条数据
|
||||
calendarData.push({
|
||||
data: row.startDate,
|
||||
date: row.startDate,
|
||||
item: {
|
||||
id: row.id,
|
||||
groupName: row.attendanceGroup.groupName,
|
||||
groupId: row.attendanceGroup.id,
|
||||
startDate: row.startDate,
|
||||
endDate: row.endDate,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
// if (response) {
|
||||
// calendarData.value = response.data || [];
|
||||
// console.log('日历数据:', calendarData.value);
|
||||
// }
|
||||
console.log('日历数据:', calendarData);
|
||||
//变量calendarData,日期相同的数据放到一个对象中,数据结构为scheduleData
|
||||
|
||||
// 将calendarData按日期分组,形成scheduleData结构
|
||||
const groupedData = new Map<string, any[]>();
|
||||
|
||||
// 遍历calendarData,按日期分组
|
||||
calendarData.forEach(item => {
|
||||
const date = item.date;
|
||||
if (!groupedData.has(date)) {
|
||||
groupedData.set(date, []);
|
||||
}
|
||||
groupedData.get(date)!.push(item.item);
|
||||
});
|
||||
|
||||
// 转换为scheduleData格式
|
||||
scheduleData.length = 0; // 清空原有数据
|
||||
groupedData.forEach((items, date) => {
|
||||
scheduleData.push({
|
||||
date: date,
|
||||
list: items.map(item => ({
|
||||
type: 'success' as BadgeProps['status'],
|
||||
content: item.groupName || '排班安排',
|
||||
item: item
|
||||
}))
|
||||
});
|
||||
});
|
||||
|
||||
console.log('处理后的scheduleData:', scheduleData);
|
||||
|
||||
// 测试:验证生成的日历数据
|
||||
console.log('=== 日历数据验证 ===');
|
||||
console.log('当前月份:', currentMonth);
|
||||
console.log('原始数据条数:', res.rows.length);
|
||||
console.log('生成的日历数据条数:', calendarData.length);
|
||||
console.log('分组后的数据条数:', scheduleData.length);
|
||||
|
||||
// 验证是否有重复日期
|
||||
const dateCounts = new Map<string, number>();
|
||||
calendarData.forEach(item => {
|
||||
const count = dateCounts.get(item.date) || 0;
|
||||
dateCounts.set(item.date, count + 1);
|
||||
});
|
||||
|
||||
console.log('日期分布:', Object.fromEntries(dateCounts));
|
||||
console.log('=== 验证完成 ===');
|
||||
} catch (error) {
|
||||
console.error('获取日历数据失败:', error);
|
||||
message.error('获取日历数据失败');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 切换视图模式
|
||||
function handleViewModeChange(e: RadioChangeEvent): void {
|
||||
// 将父组件的isCalenderView变为true
|
||||
emit('changeView', e.target.value);
|
||||
}
|
||||
|
||||
// 日历模拟数据
|
||||
const scheduleData: {
|
||||
date: string;
|
||||
list: { type: BadgeProps['status']; content: string }[];
|
||||
@@ -81,18 +187,25 @@ const scheduleData: {
|
||||
{ date: '2025-07-06', list: [{ type: 'success', content: '8月8日事件' }] },
|
||||
// ...
|
||||
];
|
||||
// 切换视图模式
|
||||
function handleViewModeChange(e: RadioChangeEvent): void {
|
||||
// 将父组件的isCalenderView变为true
|
||||
emit('changeView', e.target.value);
|
||||
}
|
||||
|
||||
const getListData2 = (
|
||||
current: Dayjs,
|
||||
): { type: BadgeProps['status']; content: string }[] => {
|
||||
): { type: BadgeProps['status']; content: string; item?: any }[] => {
|
||||
const dateStr = current.format('YYYY-MM-DD');
|
||||
// 优先使用接口数据
|
||||
if (calendarData.length > 0) {
|
||||
const found = calendarData.find((item) => item.date === dateStr);
|
||||
|
||||
// 使用scheduleData结构
|
||||
if (scheduleData.length > 0) {
|
||||
const found = scheduleData.find((item) => item.date === dateStr);
|
||||
if (found) {
|
||||
return found.list || [];
|
||||
return found.list;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有找到数据,返回空数组
|
||||
return [];
|
||||
};
|
||||
@@ -130,13 +243,8 @@ const getListData = (
|
||||
return listData || [];
|
||||
};
|
||||
|
||||
const getMonthData = (value: Dayjs) => {
|
||||
if (value.month() === 8) {
|
||||
return 1394;
|
||||
}
|
||||
};
|
||||
function customHeader() {
|
||||
// 返回你想要的VNode或null
|
||||
// 返回想要的VNode或null
|
||||
return null; // 什么都不显示
|
||||
}
|
||||
const [ArrangementModal, modalApi] = useVbenModal({
|
||||
@@ -147,6 +255,57 @@ function handleAdd() {
|
||||
modalApi.open();
|
||||
}
|
||||
|
||||
// 编辑排班
|
||||
function handleEdit(item: any) {
|
||||
console.log(815328);
|
||||
|
||||
// modalApi.setData({
|
||||
// id: item.id,
|
||||
// groupId: item.groupId,
|
||||
// startDate: item.startDate,
|
||||
// endDate: item.endDate,
|
||||
// });
|
||||
// modalApi.open();
|
||||
}
|
||||
|
||||
// 删除排班
|
||||
function handleDelete(item: any) {
|
||||
Modal.confirm({
|
||||
title: '确认删除',
|
||||
content: '确定要删除这个排班安排吗?',
|
||||
onOk: async () => {
|
||||
try {
|
||||
// 这里需要调用删除接口
|
||||
// await deleteArrangement(item.id);
|
||||
message.success('删除成功');
|
||||
fetchCalendarData();
|
||||
} catch (error) {
|
||||
console.error('删除失败:', error);
|
||||
message.error('删除失败');
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 查看详情
|
||||
function handleViewDetails(item: any) {
|
||||
// 这里可以打开详情弹窗或跳转到详情页面
|
||||
console.log('查看详情:', item);
|
||||
}
|
||||
|
||||
// 获取指定日期的所有排班项目
|
||||
function getScheduleItemsByDate(date: string) {
|
||||
const found = scheduleData.find((item) => item.date === date);
|
||||
return found ? found.list : [];
|
||||
}
|
||||
|
||||
// 查看某日期的所有排班详情
|
||||
function handleViewDateDetails(date: string) {
|
||||
const items = getScheduleItemsByDate(date);
|
||||
console.log(`${date} 的所有排班安排:`, items);
|
||||
// 这里可以打开详情弹窗显示该日期的所有排班
|
||||
}
|
||||
|
||||
// 页面初始化时加载数据
|
||||
onMounted(() => {
|
||||
fetchCalendarData();
|
||||
@@ -169,6 +328,7 @@ onMounted(() => {
|
||||
picker="month"
|
||||
v-model:value="selectedDate"
|
||||
@change="fetchCalendarData()"
|
||||
@select="fetchCalendarData()"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -187,29 +347,32 @@ onMounted(() => {
|
||||
<ul class="events">
|
||||
<li v-for="item in getListData2(current)" :key="item.content">
|
||||
<span>
|
||||
<!-- <Badge :status="item.type" :text="item.content" /> -->
|
||||
<span>{{ item.content }}</span>
|
||||
<a style="margin-left: 4px; color: #1890ff; cursor: pointer"
|
||||
>编辑</a
|
||||
>
|
||||
<a style="margin-left: 4px; color: #ff4d4f; cursor: pointer"
|
||||
>删除</a
|
||||
>
|
||||
<div class="action-buttons">
|
||||
<a
|
||||
style="margin-left: 4px; color: #1890ff; cursor: pointer"
|
||||
@click.stop="handleEdit(item.item)"
|
||||
>
|
||||
编辑
|
||||
</a>
|
||||
<a
|
||||
style="margin-left: 4px; color: #ff4d4f; cursor: pointer"
|
||||
@click.stop="handleDelete(item.item)"
|
||||
>
|
||||
删除
|
||||
</a>
|
||||
</div>
|
||||
</span>
|
||||
</li>
|
||||
<a
|
||||
v-if="getListData2(current).length > 0"
|
||||
style="margin-left: 4px; color: #1890ff; cursor: pointer"
|
||||
>详情</a
|
||||
@click.stop="handleViewDateDetails(current.format('YYYY-MM-DD'))"
|
||||
>
|
||||
详情
|
||||
</a>
|
||||
</ul>
|
||||
</template>
|
||||
<template #monthCellRender="{ current }">
|
||||
<div v-if="getMonthData(current)" class="notes-month">
|
||||
<section>{{ getMonthData(current) }}</section>
|
||||
<span>Backlog number</span>
|
||||
</div>
|
||||
</template>
|
||||
</Calendar>
|
||||
</div>
|
||||
<ArrangementModal @reload="fetchCalendarData()" />
|
||||
@@ -228,6 +391,32 @@ onMounted(() => {
|
||||
text-overflow: ellipsis;
|
||||
font-size: 12px;
|
||||
}
|
||||
.events li {
|
||||
margin-bottom: 4px;
|
||||
padding: 4px;
|
||||
/* background-color: #f6ffed; */
|
||||
/* border: 1px solid #b7eb8f; */
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.events li span {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.events li .action-buttons {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.events li a {
|
||||
font-size: 11px;
|
||||
text-decoration: none;
|
||||
}
|
||||
.events li a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.notes-month {
|
||||
text-align: center;
|
||||
font-size: 28px;
|
||||
|
Reference in New Issue
Block a user