diff --git a/pages/task/detail/index.vue b/pages/task/detail/index.vue index 2810f66..d292223 100644 --- a/pages/task/detail/index.vue +++ b/pages/task/detail/index.vue @@ -88,6 +88,21 @@ /> + + + + {{ getFileIcon(file.name) }} + + {{ file.name }} + {{ formatFileSize(file.size) }} + + + 申请延期 @@ -325,6 +340,32 @@ const isImageUrl = (url) => { return /\.(jpg|jpeg|png|gif|bmp|webp)(\?|$)/i.test(url); }; +// 解析任务附件(区分图片和文件) +const parseTaskAttachments = (attachStr) => { + if (!attachStr) return { pictures: [], files: [] }; + if (typeof attachStr !== 'string') return { pictures: [], files: [] }; + + const urls = parseAttachUrls(attachStr); + const pictures = []; + const files = []; + + urls.forEach(url => { + if (isImageUrl(url)) { + pictures.push(url); + } else { + // 从URL中提取文件名 + const fileName = url.split('/').pop().split('?')[0] || '文件'; + files.push({ + name: fileName, + path: url, + size: 0 // 如果API没有返回文件大小,默认为0 + }); + } + }); + + return { pictures, files }; +}; + // 转换提交记录数据 const transformSubmitRecords = (submitList) => { if (!Array.isArray(submitList) || submitList.length === 0) { @@ -488,6 +529,73 @@ const previewTaskImages = (imageUrls, index) => { } }; +// 预览/下载任务文件 +const previewTaskFile = (file) => { + if (!file.path) { + uni.showToast({ + title: '文件路径不存在', + icon: 'none' + }); + return; + } + + // 如果是图片,使用预览图片功能 + const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'webp']; + const ext = file.name ? file.name.split('.').pop().toLowerCase() : ''; + + if (imageExts.includes(ext)) { + uni.previewImage({ + urls: [file.path], + current: file.path + }); + } else { + // 其他文件类型,尝试打开或下载 + // #ifdef H5 + window.open(file.path, '_blank'); + // #endif + + // #ifdef APP-PLUS + plus.runtime.openURL(file.path); + // #endif + + // #ifndef H5 || APP-PLUS + uni.showToast({ + title: '正在下载文件...', + icon: 'loading', + duration: 2000 + }); + // 下载并打开文档 + uni.downloadFile({ + url: file.path, + success: (res) => { + if (res.statusCode === 200) { + uni.openDocument({ + filePath: res.tempFilePath, + success: () => { + console.log('打开文档成功'); + }, + fail: (err) => { + console.error('打开文档失败:', err); + uni.showToast({ + title: '无法打开此文件', + icon: 'none' + }); + } + }); + } + }, + fail: (err) => { + console.error('下载文件失败:', err); + uni.showToast({ + title: '下载文件失败', + icon: 'none' + }); + } + }); + // #endif + } +}; + // 预览提交记录图片 const previewRecordImages = (imageUrls, index) => { if (imageUrls && imageUrls.length > 0) { @@ -679,8 +787,16 @@ const loadTaskData = async (taskId) => { // 转换提交记录 const submitRecords = transformSubmitRecords(res.submitList || []); - // 解析任务图片(逗号分隔的URL字符串) - const taskPictures = res.picture ? parseAttachUrls(res.picture) : []; + // 解析任务附件(图片和文件) + // 优先使用 file 字段,如果没有则使用 picture 字段(可能包含图片和文件) + let taskAttachments = { pictures: [], files: [] }; + if (res.file) { + // 如果 API 返回了 file 字段,解析它 + taskAttachments = parseTaskAttachments(res.file); + } else if (res.picture) { + // 如果只有 picture 字段,也解析它(可能包含图片和文件) + taskAttachments = parseTaskAttachments(res.picture); + } // 更新任务数据 task.value = { @@ -694,7 +810,8 @@ const loadTaskData = async (taskId) => { responsible: getOwnerNames(res.memberList || []), publishTime: res.createTime ? formatTimeToChinese(res.createTime) : '', content: res.description || '', - pictures: taskPictures, // 任务图片数组 + pictures: taskAttachments.pictures, // 任务图片数组 + files: taskAttachments.files, // 任务文件数组 submitRecords: submitRecords, // 保存原始数据,供其他功能使用 rawData: res @@ -1185,6 +1302,14 @@ onShow(() => { object-fit: cover; } +/* 任务文件展示 */ +.task-files-wrapper { + display: flex; + flex-direction: column; + gap: 8px; + margin-bottom: 16px; +} + /* 提交记录图片展示(一行三个) */ .record-images-wrapper { display: flex;