| | |
| | | </view> |
| | | </template> |
| | | |
| | | <!-- 视频预览 --> |
| | | <template v-else-if="isVideoType(item.url)"> |
| | | <video |
| | | v-if="!item.loadError" |
| | | :src="getFullUrl(item.url)" |
| | | class="media-preview" |
| | | :controls="false" |
| | | :show-center-play-btn="false" |
| | | @error="onVideoError(item)" |
| | | /> |
| | | <!-- 视频加载失败显示默认图标 --> |
| | | <view v-else class="file-icon-wrapper"> |
| | | <wd-icon name="video" size="48px" color="#ccc" /> |
| | | <text class="file-name error-text">加载失败</text> |
| | | </view> |
| | | </template> |
| | | |
| | | <!-- 其他文件类型显示图标 --> |
| | | <view v-else class="file-icon-wrapper"> |
| | | <wd-icon name="file-outline" size="48px" color="#999" /> |
| | |
| | | |
| | | const detailData = ref<any>({}); |
| | | |
| | | // 获取完整的图片/视频 URL |
| | | // 获取完整的图片 URL |
| | | const getFullUrl = (url: string) => { |
| | | if (!url) return ""; |
| | | // 如果已经是完整的 URL(http 或 https 开头),直接返回 |
| | |
| | | return ["jpg", "jpeg", "png", "gif", "bmp", "webp"].includes(extension); |
| | | }; |
| | | |
| | | // 判断是否为视频类型 |
| | | const isVideoType = (urlOrFileName: string) => { |
| | | const extension = getExtension(urlOrFileName); |
| | | return ["mp4", "mov", "avi", "wmv", "flv", "mkv", "webm"].includes(extension); |
| | | }; |
| | | |
| | | // 图片加载成功 |
| | | const onImageLoad = (item: any) => { |
| | | item.loadError = false; |
| | |
| | | // 图片加载失败 |
| | | const onImageError = (item: any) => { |
| | | console.error("图片加载失败:", item.url); |
| | | item.loadError = true; |
| | | }; |
| | | |
| | | // 视频加载失败 |
| | | const onVideoError = (item: any) => { |
| | | console.error("视频加载失败:", item.url); |
| | | item.loadError = true; |
| | | }; |
| | | |
| | |
| | | const addAttachment = () => { |
| | | // 显示选择文件类型的弹窗 |
| | | uni.showActionSheet({ |
| | | itemList: ["选择图片", "选择视频", "拍照", "录像"], |
| | | itemList: ["选择图片", "拍照"], |
| | | success: (res) => { |
| | | switch (res.tapIndex) { |
| | | case 0: // 选择图片 |
| | | chooseImages(); |
| | | break; |
| | | case 1: // 选择视频 |
| | | chooseVideos(); |
| | | break; |
| | | case 2: // 拍照 |
| | | case 1: // 拍照 |
| | | takePhoto(); |
| | | break; |
| | | case 3: // 录像 |
| | | recordVideo(); |
| | | break; |
| | | } |
| | | }, |
| | |
| | | }); |
| | | }; |
| | | |
| | | // 选择视频 |
| | | const chooseVideos = () => { |
| | | uni.chooseVideo({ |
| | | sourceType: ["album"], |
| | | maxDuration: 60, |
| | | camera: "back", |
| | | success: async (res) => { |
| | | await handleFileUpload([res.tempFilePath]); |
| | | }, |
| | | fail: (error) => { |
| | | console.error("选择视频失败:", error); |
| | | toast.show("选择视频失败"); |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | | // 拍照 |
| | | const takePhoto = () => { |
| | | uni.chooseImage({ |
| | |
| | | fail: (error) => { |
| | | console.error("拍照失败:", error); |
| | | toast.show("拍照失败"); |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | | // 录像 |
| | | const recordVideo = () => { |
| | | uni.chooseVideo({ |
| | | sourceType: ["camera"], |
| | | maxDuration: 60, |
| | | camera: "back", |
| | | success: async (res) => { |
| | | await handleFileUpload([res.tempFilePath]); |
| | | }, |
| | | fail: (error) => { |
| | | console.error("录像失败:", error); |
| | | toast.show("录像失败"); |
| | | }, |
| | | }); |
| | | }; |
| | |
| | | case "bmp": |
| | | case "webp": |
| | | return "image"; |
| | | case "mp4": |
| | | case "mov": |
| | | case "avi": |
| | | case "wmv": |
| | | case "flv": |
| | | case "mkv": |
| | | case "webm": |
| | | return "video"; |
| | | case "pdf": |
| | | return "pdf"; |
| | | case "doc": |