refactor(打卡): 优化文件哈希计算和补打卡功能
- 使用 qiniuFileHash 替代浏览器MD5方案计算文件哈希 - 添加补打卡标识和日期处理逻辑 - 优化日历组件中已打卡和补打卡的样式显示
Showing
2 changed files
with
31 additions
and
29 deletions
| ... | @@ -3,7 +3,7 @@ import { useRoute, useRouter } from 'vue-router' | ... | @@ -3,7 +3,7 @@ import { useRoute, useRouter } from 'vue-router' |
| 3 | import { showToast, showLoadingToast } from 'vant' | 3 | import { showToast, showLoadingToast } from 'vant' |
| 4 | import { qiniuTokenAPI, qiniuUploadAPI, saveFileAPI } from '@/api/common' | 4 | import { qiniuTokenAPI, qiniuUploadAPI, saveFileAPI } from '@/api/common' |
| 5 | import { addUploadTaskAPI, getUploadTaskInfoAPI, editUploadTaskInfoAPI } from "@/api/checkin" | 5 | import { addUploadTaskAPI, getUploadTaskInfoAPI, editUploadTaskInfoAPI } from "@/api/checkin" |
| 6 | -import BMF from 'browser-md5-file' | 6 | +import { qiniuFileHash } from '@/utils/qiniuFileHash'; |
| 7 | import { useAuth } from '@/contexts/auth' | 7 | import { useAuth } from '@/contexts/auth' |
| 8 | 8 | ||
| 9 | /** | 9 | /** |
| ... | @@ -45,21 +45,13 @@ export function useCheckin() { | ... | @@ -45,21 +45,13 @@ export function useCheckin() { |
| 45 | }) | 45 | }) |
| 46 | 46 | ||
| 47 | /** | 47 | /** |
| 48 | - * 获取文件MD5值 | 48 | + * 获取文件哈希(与七牛云ETag一致) |
| 49 | - * @param {File} file - 文件对象 | 49 | + * @param {File} file 文件对象 |
| 50 | - * @returns {Promise<string>} MD5值 | 50 | + * @returns {Promise<string>} 哈希字符串 |
| 51 | + * 注释:使用 qiniuFileHash 进行计算,替代浏览器MD5方案。 | ||
| 51 | */ | 52 | */ |
| 52 | - const getFileMD5 = (file) => { | 53 | + const getFileMD5 = async (file) => { |
| 53 | - return new Promise((resolve, reject) => { | 54 | + return await qiniuFileHash(file) |
| 54 | - const bmf = new BMF() | ||
| 55 | - bmf.md5(file, (err, md5) => { | ||
| 56 | - if (err) { | ||
| 57 | - reject(err) | ||
| 58 | - return | ||
| 59 | - } | ||
| 60 | - resolve(md5) | ||
| 61 | - }) | ||
| 62 | - }) | ||
| 63 | } | 55 | } |
| 64 | 56 | ||
| 65 | /** | 57 | /** |
| ... | @@ -290,7 +282,8 @@ export function useCheckin() { | ... | @@ -290,7 +282,8 @@ export function useCheckin() { |
| 290 | task_id: route.query.id, | 282 | task_id: route.query.id, |
| 291 | note: message.value, | 283 | note: message.value, |
| 292 | file_type: activeType.value, | 284 | file_type: activeType.value, |
| 293 | - meta_id: [] | 285 | + meta_id: [], |
| 286 | + makeup_time: route.query.is_patch ? route.query.date : '', | ||
| 294 | } | 287 | } |
| 295 | 288 | ||
| 296 | // 如果有文件,添加文件ID | 289 | // 如果有文件,添加文件ID | ... | ... |
| 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-11-10 10:38:27 | 4 | + * @LastEditTime: 2025-11-13 17:22:35 |
| 5 | * @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue | 5 | * @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | --> | 7 | --> |
| ... | @@ -72,11 +72,18 @@ | ... | @@ -72,11 +72,18 @@ |
| 72 | <div class="post-header"> | 72 | <div class="post-header"> |
| 73 | <van-row> | 73 | <van-row> |
| 74 | <van-col span="3"> | 74 | <van-col span="3"> |
| 75 | - <van-image round width="2.5rem" height="2.5rem" :src="post.user.avatar || 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg'" fit="cover" /> | 75 | + <van-image round width="2.5rem" height="2.5rem" :src="post.user.avatar || 'https://cdn.ipadbiz.cn/mlaj/images/icon_1.jpeg?imageMogr2/thumbnail/200x/strip/quality/70'" fit="cover" /> |
| 76 | </van-col> | 76 | </van-col> |
| 77 | <van-col span="18"> | 77 | <van-col span="18"> |
| 78 | <div class="user-info"> | 78 | <div class="user-info"> |
| 79 | - <div class="username">{{ post.user.name }}</div> | 79 | + <div class="username"> |
| 80 | + {{ post.user.name }} | ||
| 81 | + <!-- 补打卡标识标签 --> | ||
| 82 | + <span | ||
| 83 | + v-if="post.user.is_makeup" | ||
| 84 | + class="MakeupTag inline-flex items-center ml-2 px-2 py-0.5 rounded-full text-xs font-medium bg-green-50 text-green-600 border border-green-300" | ||
| 85 | + >补打卡</span> | ||
| 86 | + </div> | ||
| 80 | <div class="post-time">{{ post.user.time }}</div> | 87 | <div class="post-time">{{ post.user.time }}</div> |
| 81 | </div> | 88 | </div> |
| 82 | </van-col> | 89 | </van-col> |
| ... | @@ -99,7 +106,7 @@ | ... | @@ -99,7 +106,7 @@ |
| 99 | <div v-for="(v, idx) in post.videoList" :key="idx"> | 106 | <div v-for="(v, idx) in post.videoList" :key="idx"> |
| 100 | <!-- 视频封面和播放按钮 --> | 107 | <!-- 视频封面和播放按钮 --> |
| 101 | <div v-if="v.video && !v.isPlaying" class="relative w-full rounded-lg overflow-hidden" style="aspect-ratio: 16/9; margin-bottom: 1rem;"> | 108 | <div v-if="v.video && !v.isPlaying" class="relative w-full rounded-lg overflow-hidden" style="aspect-ratio: 16/9; margin-bottom: 1rem;"> |
| 102 | - <img :src="v.videoCover || 'https://cdn.ipadbiz.cn/mlaj/images/cover_video_2.png'" | 109 | + <img :src="v.videoCover || 'https://cdn.ipadbiz.cn/mlaj/images/cover_video_2.png?imageMogr2/thumbnail/200x/strip/quality/70'" |
| 103 | :alt="v.content" class="w-full h-full object-cover" /> | 110 | :alt="v.content" class="w-full h-full object-cover" /> |
| 104 | <div class="absolute inset-0 flex items-center justify-center cursor-pointer bg-black/20" | 111 | <div class="absolute inset-0 flex items-center justify-center cursor-pointer bg-black/20" |
| 105 | @click="startPlay(v)"> | 112 | @click="startPlay(v)"> |
| ... | @@ -444,15 +451,13 @@ const formatter = (day) => { | ... | @@ -444,15 +451,13 @@ const formatter = (day) => { |
| 444 | 451 | ||
| 445 | // 检查是否已打卡 | 452 | // 检查是否已打卡 |
| 446 | if (checkin_days.includes(formattedDate)) { | 453 | if (checkin_days.includes(formattedDate)) { |
| 454 | + day.type = 'selected'; | ||
| 455 | + day.bottomInfo = '已打卡'; | ||
| 447 | // 如果是当前选中的已打卡日期,使用特殊样式 | 456 | // 如果是当前选中的已打卡日期,使用特殊样式 |
| 448 | if (selectedDate.value === formattedDate) { | 457 | if (selectedDate.value === formattedDate) { |
| 449 | day.className = 'calendar-selected'; | 458 | day.className = 'calendar-selected'; |
| 450 | - day.type = 'selected'; | ||
| 451 | - day.bottomInfo = '已打卡'; | ||
| 452 | } else { | 459 | } else { |
| 453 | day.className = 'calendar-checkin'; | 460 | day.className = 'calendar-checkin'; |
| 454 | - day.type = 'selected'; | ||
| 455 | - day.bottomInfo = '已打卡'; | ||
| 456 | } | 461 | } |
| 457 | } | 462 | } |
| 458 | } | 463 | } |
| ... | @@ -464,14 +469,14 @@ const formatter = (day) => { | ... | @@ -464,14 +469,14 @@ const formatter = (day) => { |
| 464 | // 检查是否已补卡 | 469 | // 检查是否已补卡 |
| 465 | if (fill_checkin_days.includes(formattedDate)) { | 470 | if (fill_checkin_days.includes(formattedDate)) { |
| 466 | // 如果是当前选中的已补卡日期,使用特殊样式 | 471 | // 如果是当前选中的已补卡日期,使用特殊样式 |
| 472 | + day.type = 'selected'; | ||
| 473 | + day.bottomInfo = '待补卡'; | ||
| 467 | if (selectedDate.value === formattedDate) { | 474 | if (selectedDate.value === formattedDate) { |
| 468 | day.className = 'calendar-selected'; | 475 | day.className = 'calendar-selected'; |
| 469 | - day.type = 'selected'; | 476 | + // 选中的是补卡日期 |
| 470 | - day.bottomInfo = '待补卡'; | 477 | + isPatchCheckin.value = true; |
| 471 | } else { | 478 | } else { |
| 472 | day.className = 'calendar-fill-checkin'; | 479 | day.className = 'calendar-fill-checkin'; |
| 473 | - day.type = 'selected'; | ||
| 474 | - day.bottomInfo = '待补卡'; | ||
| 475 | } | 480 | } |
| 476 | } | 481 | } |
| 477 | } | 482 | } |
| ... | @@ -564,7 +569,8 @@ const goToCheckinDetailPage = () => { | ... | @@ -564,7 +569,8 @@ const goToCheckinDetailPage = () => { |
| 564 | path: '/checkin/detail', | 569 | path: '/checkin/detail', |
| 565 | query: { | 570 | query: { |
| 566 | id: route.query.id, | 571 | id: route.query.id, |
| 567 | - date: current_date | 572 | + date: current_date, |
| 573 | + is_patch: isPatchCheckin.value ? '1' : '0', | ||
| 568 | } | 574 | } |
| 569 | }) | 575 | }) |
| 570 | } | 576 | } |
| ... | @@ -674,6 +680,8 @@ const myCheckinDates = ref([]); | ... | @@ -674,6 +680,8 @@ const myCheckinDates = ref([]); |
| 674 | const myFillCheckinDates = ref([]); | 680 | const myFillCheckinDates = ref([]); |
| 675 | const checkinDataList = ref([]); | 681 | const checkinDataList = ref([]); |
| 676 | const showProgress = ref(true); | 682 | const showProgress = ref(true); |
| 683 | +// 是否为补卡模式 | ||
| 684 | +const isPatchCheckin = ref(false); | ||
| 677 | 685 | ||
| 678 | // 作品类型选项 | 686 | // 作品类型选项 |
| 679 | const attachmentTypeOptions = ref([]); | 687 | const attachmentTypeOptions = ref([]); |
| ... | @@ -783,6 +791,7 @@ const formatData = (data) => { | ... | @@ -783,6 +791,7 @@ const formatData = (data) => { |
| 783 | name: item.username, | 791 | name: item.username, |
| 784 | avatar: item.avatar, | 792 | avatar: item.avatar, |
| 785 | time: item.created_time_desc, | 793 | time: item.created_time_desc, |
| 794 | + is_makeup: item.is_makeup, | ||
| 786 | }, | 795 | }, |
| 787 | content: item.note, | 796 | content: item.note, |
| 788 | images, | 797 | images, | ... | ... |
-
Please register or login to post a comment