feat: 个人中心

This commit is contained in:
fyy
2025-08-06 16:47:42 +08:00
parent 90531f1598
commit 3bb04f80eb
47 changed files with 6522 additions and 52 deletions

View File

@@ -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;