feat(checkin): 实现打卡动态列表分页加载和日期选择优化
重构打卡动态列表为分页加载方式,提升性能 优化日期选择逻辑,自动重置分页参数并重新加载数据 修复日历日期匹配逻辑,支持完整日期格式匹配
Showing
1 changed file
with
60 additions
and
29 deletions
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2025-05-29 15:34:17 | 2 | * @Date: 2025-05-29 15:34:17 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2025-06-09 15:50:10 | 4 | + * @LastEditTime: 2025-06-10 10:20:08 |
| 5 | * @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue | 5 | * @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | --> | 7 | --> |
| ... | @@ -67,6 +67,14 @@ | ... | @@ -67,6 +67,14 @@ |
| 67 | 67 | ||
| 68 | <div class="text-wrapper"> | 68 | <div class="text-wrapper"> |
| 69 | <div class="text-header">打卡动态</div> | 69 | <div class="text-header">打卡动态</div> |
| 70 | + <van-list | ||
| 71 | + v-if="checkinDataList.length" | ||
| 72 | + v-model:loading="loading" | ||
| 73 | + :finished="finished" | ||
| 74 | + finished-text="没有更多了" | ||
| 75 | + @load="onLoad" | ||
| 76 | + class="px-4 py-3 space-y-4" | ||
| 77 | + > | ||
| 70 | <div class="post-card" v-for="post in checkinDataList" :key="post.id"> | 78 | <div class="post-card" v-for="post in checkinDataList" :key="post.id"> |
| 71 | <div class="post-header"> | 79 | <div class="post-header"> |
| 72 | <van-row> | 80 | <van-row> |
| ... | @@ -143,7 +151,8 @@ | ... | @@ -143,7 +151,8 @@ |
| 143 | <span class="like-count">{{ post.likes }}</span> | 151 | <span class="like-count">{{ post.likes }}</span> |
| 144 | </div> | 152 | </div> |
| 145 | </div> | 153 | </div> |
| 146 | - <van-empty v-if="!checkinDataList.length" image="error" description="暂无数据" /> | 154 | + </van-list> |
| 155 | + <van-empty v-else image="error" description="暂无数据" /> | ||
| 147 | </div> | 156 | </div> |
| 148 | 157 | ||
| 149 | <div style="height: 5rem;"></div> | 158 | <div style="height: 5rem;"></div> |
| ... | @@ -353,33 +362,37 @@ const onChange = (index) => { | ... | @@ -353,33 +362,37 @@ const onChange = (index) => { |
| 353 | startPosition.value = index; | 362 | startPosition.value = index; |
| 354 | } | 363 | } |
| 355 | const formatter = (day) => { | 364 | const formatter = (day) => { |
| 365 | + const year = day.date.getFullYear(); | ||
| 356 | const month = day.date.getMonth() + 1; | 366 | const month = day.date.getMonth() + 1; |
| 357 | const date = day.date.getDate(); | 367 | const date = day.date.getDate(); |
| 358 | 368 | ||
| 359 | let checkin_days = myCheckinDates.value; | 369 | let checkin_days = myCheckinDates.value; |
| 360 | 370 | ||
| 361 | - if (month === 6) { | 371 | + // 检查当前日期是否在签到日期列表中 |
| 362 | - if (checkin_days.includes(date)) { | 372 | + if (checkin_days && checkin_days.length > 0) { |
| 373 | + // 格式化当前日期为YYYY-MM-DD格式,与checkin_days中的格式匹配 | ||
| 374 | + const formattedDate = `${year}-${month.toString().padStart(2, '0')}-${date.toString().padStart(2, '0')}`; | ||
| 375 | + | ||
| 376 | + // 检查是否已签到 | ||
| 377 | + if (checkin_days.includes(formattedDate)) { | ||
| 363 | day.className = 'calendar-checkin'; | 378 | day.className = 'calendar-checkin'; |
| 364 | day.type = 'selected'; | 379 | day.type = 'selected'; |
| 365 | - day.bottomInfo = '已签到' | 380 | + day.bottomInfo = '已签到'; |
| 366 | } | 381 | } |
| 367 | } | 382 | } |
| 383 | + | ||
| 368 | // 选中今天的日期 | 384 | // 选中今天的日期 |
| 369 | if (dayjs(day.date).isSame(new Date(), 'day')) { | 385 | if (dayjs(day.date).isSame(new Date(), 'day')) { |
| 370 | day.className = 'calendar-today'; | 386 | day.className = 'calendar-today'; |
| 371 | - day.type ='selected'; | 387 | + day.type = 'selected'; |
| 372 | - day.bottomInfo = '今日' | 388 | + day.bottomInfo = '今日'; |
| 373 | } | 389 | } |
| 374 | 390 | ||
| 375 | return day; | 391 | return day; |
| 376 | } | 392 | } |
| 377 | 393 | ||
| 378 | const onSelectDay = (day) => { | 394 | const onSelectDay = (day) => { |
| 379 | - console.warn('选择了日期', dayjs(day).format('YYYY-MM-DD')); | ||
| 380 | getTaskDetail(dayjs(day).format('YYYY-MM')); | 395 | getTaskDetail(dayjs(day).format('YYYY-MM')); |
| 381 | - // 获取打卡动态列表 | ||
| 382 | - initUploadTaskList(dayjs(day).format('YYYY-MM-DD')); | ||
| 383 | // 修改浏览器地址把当前的date加入地址栏, 页面不刷新 | 396 | // 修改浏览器地址把当前的date加入地址栏, 页面不刷新 |
| 384 | router.push({ | 397 | router.push({ |
| 385 | path: route.path, | 398 | path: route.path, |
| ... | @@ -388,6 +401,12 @@ const onSelectDay = (day) => { | ... | @@ -388,6 +401,12 @@ const onSelectDay = (day) => { |
| 388 | date: dayjs(day).format('YYYY-MM-DD') | 401 | date: dayjs(day).format('YYYY-MM-DD') |
| 389 | } | 402 | } |
| 390 | }) | 403 | }) |
| 404 | + // 重置分页参数 | ||
| 405 | + page.value = 0 | ||
| 406 | + checkinDataList.value = [] | ||
| 407 | + finished.value = false | ||
| 408 | + // 重新加载数据 | ||
| 409 | + onLoad(dayjs(day).format('YYYY-MM-DD')) | ||
| 391 | } | 410 | } |
| 392 | 411 | ||
| 393 | const onClickSubtitle = (evt) => { | 412 | const onClickSubtitle = (evt) => { |
| ... | @@ -442,7 +461,6 @@ const handLike = async (post) => { | ... | @@ -442,7 +461,6 @@ const handLike = async (post) => { |
| 442 | } | 461 | } |
| 443 | 462 | ||
| 444 | const editCheckin = (post) => { | 463 | const editCheckin = (post) => { |
| 445 | - console.warn(post); | ||
| 446 | if (post.file_type === 'image') { | 464 | if (post.file_type === 'image') { |
| 447 | router.push({ | 465 | router.push({ |
| 448 | path: '/checkin/image', | 466 | path: '/checkin/image', |
| ... | @@ -505,7 +523,6 @@ const showProgress = ref(true); | ... | @@ -505,7 +523,6 @@ const showProgress = ref(true); |
| 505 | const getTaskDetail = async (month) => { | 523 | const getTaskDetail = async (month) => { |
| 506 | const { code, data } = await getTaskDetailAPI({ i: route.query.id, month }); | 524 | const { code, data } = await getTaskDetailAPI({ i: route.query.id, month }); |
| 507 | if (code) { | 525 | if (code) { |
| 508 | - console.warn(data); | ||
| 509 | taskDetail.value = data; | 526 | taskDetail.value = data; |
| 510 | progress1.value = (data.checkin_number/data.target_number)*100; // 计算进度条百分比 | 527 | progress1.value = (data.checkin_number/data.target_number)*100; // 计算进度条百分比 |
| 511 | showProgress.value = !isNaN(progress1.value); // 如果是NaN,就不显示进度条 | 528 | showProgress.value = !isNaN(progress1.value); // 如果是NaN,就不显示进度条 |
| ... | @@ -513,37 +530,45 @@ const getTaskDetail = async (month) => { | ... | @@ -513,37 +530,45 @@ const getTaskDetail = async (month) => { |
| 513 | // 获取当前用户的打卡日期 | 530 | // 获取当前用户的打卡日期 |
| 514 | myCheckinDates.value = data.my_checkin_dates; | 531 | myCheckinDates.value = data.my_checkin_dates; |
| 515 | // 把['2025-06-06'] 转化为 [6] 只取日期去掉0 | 532 | // 把['2025-06-06'] 转化为 [6] 只取日期去掉0 |
| 516 | - myCheckinDates.value = myCheckinDates.value.map(date => { | 533 | + // myCheckinDates.value = myCheckinDates.value.map(date => { |
| 517 | - return dayjs(date).date(); | 534 | + // return dayjs(date).date(); |
| 518 | - }) | 535 | + // }) |
| 519 | } | 536 | } |
| 520 | } | 537 | } |
| 521 | 538 | ||
| 522 | -const initUploadTaskList = async (date) => { | 539 | +const loading = ref(false) |
| 523 | - const toast = showLoadingToast({ | 540 | +const finished = ref(false) |
| 524 | - message: '加载中...', | 541 | +const limit = ref(3) |
| 525 | - forbidClick: true, | 542 | +const page = ref(0) |
| 543 | + | ||
| 544 | +const onLoad = async (date) => { | ||
| 545 | + const nextPage = page.value; | ||
| 546 | + const current_date = date || route.query.date || dayjs().format('YYYY-MM-DD'); | ||
| 547 | + // | ||
| 548 | + const res = await getUploadTaskListAPI({ | ||
| 549 | + limit: limit.value, | ||
| 550 | + page: nextPage, | ||
| 551 | + task_id: route.query.id, | ||
| 552 | + date: current_date | ||
| 526 | }); | 553 | }); |
| 527 | - const { code, data } = await getUploadTaskListAPI({ task_id: route.query.id, date, limit: 999 }); | 554 | + if (res.code) { |
| 528 | - if (code) { | ||
| 529 | - console.warn(data?.checkin_list); | ||
| 530 | // 整理数据结构 | 555 | // 整理数据结构 |
| 531 | - checkinDataList.value = formatData(data) | 556 | + checkinDataList.value = [...checkinDataList.value, ...formatData(res.data)]; |
| 532 | - toast.close(); | 557 | + finished.value = res.data.checkin_list.length < limit.value; |
| 558 | + page.value = nextPage + 1; | ||
| 533 | } | 559 | } |
| 534 | -} | 560 | + loading.value = false; |
| 561 | +}; | ||
| 535 | 562 | ||
| 536 | onMounted(async () => { | 563 | onMounted(async () => { |
| 537 | const current_date = route.query.date; | 564 | const current_date = route.query.date; |
| 538 | if (current_date) { | 565 | if (current_date) { |
| 539 | getTaskDetail(dayjs(current_date).format('YYYY-MM')); | 566 | getTaskDetail(dayjs(current_date).format('YYYY-MM')); |
| 540 | - // 获取打卡动态列表 | ||
| 541 | - initUploadTaskList(current_date); | ||
| 542 | myRefCalendar.value?.reset(new Date(current_date)); | 567 | myRefCalendar.value?.reset(new Date(current_date)); |
| 568 | + onLoad(current_date); | ||
| 543 | } else { | 569 | } else { |
| 544 | getTaskDetail(dayjs().format('YYYY-MM')); | 570 | getTaskDetail(dayjs().format('YYYY-MM')); |
| 545 | - // 获取打卡动态列表 | 571 | + onLoad(dayjs().format('YYYY-MM-DD')); |
| 546 | - initUploadTaskList(dayjs().format('YYYY-MM-DD')); | ||
| 547 | } | 572 | } |
| 548 | }) | 573 | }) |
| 549 | 574 | ||
| ... | @@ -606,6 +631,12 @@ const formatData = (data) => { | ... | @@ -606,6 +631,12 @@ const formatData = (data) => { |
| 606 | } | 631 | } |
| 607 | } | 632 | } |
| 608 | 633 | ||
| 634 | +.calendar-today { | ||
| 635 | + .van-calendar__selected-day { | ||
| 636 | + background: #FAAB0C !important; | ||
| 637 | + } | ||
| 638 | +} | ||
| 639 | + | ||
| 609 | .text-wrapper { | 640 | .text-wrapper { |
| 610 | padding: 1rem; | 641 | padding: 1rem; |
| 611 | color: #4caf50; | 642 | color: #4caf50; | ... | ... |
-
Please register or login to post a comment