fix(文件上传): 限制视频上传格式并添加MOV格式提示
在视频上传前检查文件格式,拦截MOV文件并显示兼容性提示对话框 将视频上传的accept类型限制为MP4格式,更新上传提示信息
Showing
1 changed file
with
27 additions
and
5 deletions
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2025-09-30 17:05 | 2 | * @Date: 2025-09-30 17:05 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2026-01-23 16:59:38 | 4 | + * @LastEditTime: 2026-01-24 15:23:44 |
| 5 | * @FilePath: /mlaj/src/views/checkin/CheckinDetailPage.vue | 5 | * @FilePath: /mlaj/src/views/checkin/CheckinDetailPage.vue |
| 6 | * @Description: 用户打卡详情页 | 6 | * @Description: 用户打卡详情页 |
| 7 | --> | 7 | --> |
| ... | @@ -99,7 +99,7 @@ | ... | @@ -99,7 +99,7 @@ |
| 99 | <!-- 文件上传区域 --> | 99 | <!-- 文件上传区域 --> |
| 100 | <div v-if="activeType !== '' && activeType !== 'text'" class="upload-area"> | 100 | <div v-if="activeType !== '' && activeType !== 'text'" class="upload-area"> |
| 101 | <van-uploader v-model="displayFileList" :max-count="maxCount" :max-size="maxFileSizeBytes" | 101 | <van-uploader v-model="displayFileList" :max-count="maxCount" :max-size="maxFileSizeBytes" |
| 102 | - :before-read="beforeRead" :after-read="afterRead" @delete="onDelete" | 102 | + :before-read="beforeReadGuard" :after-read="afterRead" @delete="onDelete" |
| 103 | @click-preview="onClickPreview" multiple :accept="getAcceptType()" result-type="file" | 103 | @click-preview="onClickPreview" multiple :accept="getAcceptType()" result-type="file" |
| 104 | :deletable="true" upload-icon="plus" /> | 104 | :deletable="true" upload-icon="plus" /> |
| 105 | 105 | ||
| ... | @@ -191,7 +191,7 @@ import AudioPlayer from '@/components/media/AudioPlayer.vue' | ... | @@ -191,7 +191,7 @@ import AudioPlayer from '@/components/media/AudioPlayer.vue' |
| 191 | import VideoPlayer from '@/components/media/VideoPlayer.vue' | 191 | import VideoPlayer from '@/components/media/VideoPlayer.vue' |
| 192 | import AddTargetDialog from '@/components/count/AddTargetDialog.vue' | 192 | import AddTargetDialog from '@/components/count/AddTargetDialog.vue' |
| 193 | import CheckinTargetList from '@/components/count/CheckinTargetList.vue' | 193 | import CheckinTargetList from '@/components/count/CheckinTargetList.vue' |
| 194 | -import { showToast, showLoadingToast } from 'vant' | 194 | +import { showToast, showLoadingToast, showDialog } from 'vant' |
| 195 | import dayjs from 'dayjs' | 195 | import dayjs from 'dayjs' |
| 196 | 196 | ||
| 197 | const route = useRoute() | 197 | const route = useRoute() |
| ... | @@ -224,6 +224,28 @@ const { | ... | @@ -224,6 +224,28 @@ const { |
| 224 | gratitudeFormList | 224 | gratitudeFormList |
| 225 | } = useCheckin() | 225 | } = useCheckin() |
| 226 | 226 | ||
| 227 | +const beforeReadGuard = (file) => { | ||
| 228 | + if (activeType.value !== 'video') return beforeRead(file) | ||
| 229 | + | ||
| 230 | + const files = Array.isArray(file) ? file : [file] | ||
| 231 | + const hasMov = files.some(item => { | ||
| 232 | + const fileName = String(item?.name || '').toLowerCase() | ||
| 233 | + const fileType = String(item?.type || '').toLowerCase() | ||
| 234 | + return fileName.endsWith('.mov') || fileType.includes('quicktime') | ||
| 235 | + }) | ||
| 236 | + | ||
| 237 | + if (hasMov) { | ||
| 238 | + showDialog({ | ||
| 239 | + title: '不支持 MOV 格式', | ||
| 240 | + message: 'MOV(QuickTime)在非苹果系统/部分播放器兼容性较差,可能出现无法打开、黑屏、无声等问题。\n\n请将视频导出/转换为 MP4(更通用)后再上传。', | ||
| 241 | + confirmButtonText: '我知道了', | ||
| 242 | + }) | ||
| 243 | + return false | ||
| 244 | + } | ||
| 245 | + | ||
| 246 | + return beforeRead(file) | ||
| 247 | +} | ||
| 248 | + | ||
| 227 | /** | 249 | /** |
| 228 | * 获取指定类型的文件数量 | 250 | * 获取指定类型的文件数量 |
| 229 | * @param {string} type - 文件类型 | 251 | * @param {string} type - 文件类型 |
| ... | @@ -685,7 +707,7 @@ const getFileIcon = () => { | ... | @@ -685,7 +707,7 @@ const getFileIcon = () => { |
| 685 | const getAcceptType = () => { | 707 | const getAcceptType = () => { |
| 686 | const acceptMap = { | 708 | const acceptMap = { |
| 687 | 'image': 'image/*', | 709 | 'image': 'image/*', |
| 688 | - 'video': 'video/*', | 710 | + 'video': '.mp4,video/mp4', |
| 689 | 'audio': '.mp3,.wav,.aac,.flac,.ogg,.wma,.m4a' | 711 | 'audio': '.mp3,.wav,.aac,.flac,.ogg,.wma,.m4a' |
| 690 | } | 712 | } |
| 691 | return acceptMap[activeType.value] || '*' | 713 | return acceptMap[activeType.value] || '*' |
| ... | @@ -698,7 +720,7 @@ const getAcceptType = () => { | ... | @@ -698,7 +720,7 @@ const getAcceptType = () => { |
| 698 | const getUploadTips = () => { | 720 | const getUploadTips = () => { |
| 699 | const tipsMap = { | 721 | const tipsMap = { |
| 700 | 'image': '支持格式:.jpg/.jpeg/.png', | 722 | 'image': '支持格式:.jpg/.jpeg/.png', |
| 701 | - 'video': '支持格式:视频文件', | 723 | + 'video': '支持格式:.mp4(不支持 .mov)', |
| 702 | 'audio': '支持格式:.mp3/.wav/.aac/.flac/.ogg/.wma/.m4a' | 724 | 'audio': '支持格式:.mp3/.wav/.aac/.flac/.ogg/.wma/.m4a' |
| 703 | } | 725 | } |
| 704 | return tipsMap[activeType.value] || '' | 726 | return tipsMap[activeType.value] || '' | ... | ... |
-
Please register or login to post a comment