| | |
| | | |
| | | <!-- 视频 --> |
| | | <div v-else-if="mediaType === 'video'" style="position: relative;"> |
| | | <Video |
| | | <video |
| | | :src="mediaList[currentMediaIndex]" |
| | | autoplay |
| | | controls |
| | |
| | | <script setup> |
| | | import { ref } from 'vue'; |
| | | import VueEasyLightbox from 'vue-easy-lightbox'; |
| | | const { proxy } = getCurrentInstance(); |
| | | |
| | | // 控制弹窗显示 |
| | | const dialogVisitable = ref(false); |
| | |
| | | const currentMediaIndex = ref(0); |
| | | const mediaList = ref([]); // 存储当前要查看的媒体列表(含图片和视频对象) |
| | | const mediaType = ref('image'); // image | video |
| | | const javaApi = proxy.javaApi; |
| | | |
| | | // 处理 URL:将 Windows 路径转换为可访问的 URL |
| | | function processFileUrl(fileUrl) { |
| | | if (!fileUrl) return ''; |
| | | |
| | | // 如果 URL 是 Windows 路径格式(包含反斜杠),需要转换 |
| | | if (fileUrl && fileUrl.indexOf('\\') > -1) { |
| | | // 查找 uploads 关键字的位置,从那里开始提取相对路径 |
| | | const uploadsIndex = fileUrl.toLowerCase().indexOf('uploads'); |
| | | if (uploadsIndex > -1) { |
| | | // 从 uploads 开始提取路径,并将反斜杠替换为正斜杠 |
| | | const relativePath = fileUrl.substring(uploadsIndex).replace(/\\/g, '/'); |
| | | fileUrl = '/' + relativePath; |
| | | } else { |
| | | // 如果没有找到 uploads,提取最后一个目录和文件名 |
| | | const parts = fileUrl.split('\\'); |
| | | const fileName = parts[parts.length - 1]; |
| | | fileUrl = '/uploads/' + fileName; |
| | | } |
| | | } |
| | | |
| | | // 确保所有非 http 开头的 URL 都拼接 baseUrl |
| | | if (fileUrl && !fileUrl.startsWith('http')) { |
| | | // 确保路径以 / 开头 |
| | | if (!fileUrl.startsWith('/')) { |
| | | fileUrl = '/' + fileUrl; |
| | | } |
| | | // 拼接 baseUrl |
| | | fileUrl = javaApi + fileUrl; |
| | | } |
| | | |
| | | return fileUrl; |
| | | } |
| | | |
| | | // 处理每一类数据:分离图片和视频 |
| | | function processItems(items) { |
| | | const images = []; |
| | | const videos = []; |
| | | |
| | | // 检查 items 是否存在且为数组 |
| | | if (!items || !Array.isArray(items)) { |
| | | return { images, videos }; |
| | | } |
| | | |
| | | items.forEach(item => { |
| | | if (item.contentType?.startsWith('image/')) { |
| | | images.push(item.url); |
| | | } else if (item.contentType?.startsWith('video/')) { |
| | | videos.push(item.url); |
| | | if (!item || !item.url) return; |
| | | |
| | | // 处理文件 URL |
| | | const fileUrl = processFileUrl(item.url); |
| | | |
| | | // 根据文件扩展名判断是图片还是视频 |
| | | const urlLower = fileUrl.toLowerCase(); |
| | | if (urlLower.match(/\.(jpg|jpeg|png|gif|bmp|webp)$/)) { |
| | | images.push(fileUrl); |
| | | } else if (urlLower.match(/\.(mp4|avi|mov|wmv|flv|mkv|webm)$/)) { |
| | | videos.push(fileUrl); |
| | | } else if (item.contentType) { |
| | | // 如果有 contentType,使用 contentType 判断 |
| | | if (item.contentType.startsWith('image/')) { |
| | | images.push(fileUrl); |
| | | } else if (item.contentType.startsWith('video/')) { |
| | | videos.push(fileUrl); |
| | | } |
| | | } |
| | | }); |
| | | |
| | | return { images, videos }; |
| | | } |
| | | |
| | | // 打开弹窗并加载数据 |
| | | const openDialog = async (row) => { |
| | | const { images: beforeImgs, videos: beforeVids } = processItems(row.beforeProduction); |
| | | const { images: afterImgs, videos: afterVids } = processItems(row.afterProduction); |
| | | const { images: issueImgs, videos: issueVids } = processItems(row.productionIssues); |
| | | // 使用正确的字段名:commonFileListBefore, commonFileListAfter |
| | | // productionIssues 可能不存在,使用空数组 |
| | | const { images: beforeImgs, videos: beforeVids } = processItems(row.commonFileListBefore || []); |
| | | const { images: afterImgs, videos: afterVids } = processItems(row.commonFileListAfter || []); |
| | | const { images: issueImgs, videos: issueVids } = processItems(row.productionIssues || []); |
| | | |
| | | beforeProductionImgs.value = beforeImgs; |
| | | beforeProductionVideos.value = beforeVids; |