| | |
| | | @back="goBack" /> |
| | | <!-- 页面内容 --> |
| | | <view class="attachment-content"> |
| | | <!-- 分类标签页 --> |
| | | <view class="attachment-tabs"> |
| | | <view class="tab-item" |
| | | :class="{ active: currentViewType === 'before' }" |
| | | @click="switchViewType('before')"> |
| | | 生产前 ({{ getAttachmentsByType(0).length }}) |
| | | </view> |
| | | <view class="tab-item" |
| | | :class="{ active: currentViewType === 'after' }" |
| | | @click="switchViewType('after')"> |
| | | 生产中 ({{ getAttachmentsByType(1).length }}) |
| | | </view> |
| | | <view class="tab-item" |
| | | :class="{ active: currentViewType === 'issue' }" |
| | | @click="switchViewType('issue')"> |
| | | 生产后 ({{ getAttachmentsByType(2).length }}) |
| | | </view> |
| | | </view> |
| | | <!-- 当前分类的附件列表 --> |
| | | <!-- 附件列表 --> |
| | | <view class="attachment-list-container"> |
| | | <view v-if="getCurrentViewAttachments().length > 0" |
| | | <view v-if="attachmentList.length > 0" |
| | | class="attachment-list"> |
| | | <view v-for="(file, index) in getCurrentViewAttachments()" |
| | | <view v-for="(file, index) in attachmentList" |
| | | :key="index" |
| | | class="attachment-item" |
| | | @click="previewAttachment(file)"> |
| | |
| | | </view> |
| | | <view v-else |
| | | class="attachment-empty"> |
| | | <text class="empty-text">该分类暂无附件</text> |
| | | <text class="empty-text">暂无附件</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | |
| | | // 附件列表 |
| | | const attachmentList = ref([]); |
| | | |
| | | // 当前查看类型 |
| | | const currentViewType = ref("before"); // 'before', 'after', 'issue' |
| | | |
| | | // 视频预览相关状态 |
| | | const showVideoDialog = ref(false); |
| | | const currentVideoFile = ref(null); |
| | |
| | | } |
| | | }); |
| | | |
| | | // 加载附件数据 |
| | | // 加载附件数据(统一使用 commonFileListVO) |
| | | const loadAttachments = () => { |
| | | const task = taskInfo.value; |
| | | if (!task) return; |
| | | |
| | | attachmentList.value = []; |
| | | |
| | | // 后端反显字段 (VO优先) |
| | | const beforeList = Array.isArray(task?.commonFileListBeforeVO) |
| | | ? task.commonFileListBeforeVO |
| | | : Array.isArray(task?.commonFileListBefore) |
| | | ? task.commonFileListBefore |
| | | : []; |
| | | |
| | | const duringList = Array.isArray(task?.commonFileListVO) |
| | | const fileList = Array.isArray(task?.commonFileListVO) |
| | | ? task.commonFileListVO |
| | | : Array.isArray(task?.commonFileListAfter) |
| | | ? task.commonFileListAfter |
| | | : []; // 兼容旧逻辑或命名不一致 |
| | | |
| | | const afterList = Array.isArray(task?.commonFileListAfterVO) |
| | | ? task.commonFileListAfterVO |
| | | : Array.isArray(task?.commonFileListIssue) |
| | | ? task.commonFileListIssue |
| | | : []; |
| | | |
| | | // 如果 VO 都没有,尝试从 commonFileList 过滤 |
| | | const allList = Array.isArray(task?.commonFileList) |
| | | ? task.commonFileList |
| | | : []; |
| | | |
| | | const finalBefore = |
| | | beforeList.length > 0 ? beforeList : allList.filter(f => f?.type === 10); |
| | | const finalDuring = |
| | | duringList.length > 0 ? duringList : allList.filter(f => f?.type === 11); |
| | | const finalAfter = |
| | | afterList.length > 0 ? afterList : allList.filter(f => f?.type === 12); |
| | | |
| | | const mapToViewFile = (file, viewType) => { |
| | | // 兼容 previewURL, previewUrl, url, downloadURL, downloadUrl |
| | | attachmentList.value = fileList.map(file => { |
| | | const rawUrl = |
| | | file?.previewURL || |
| | | file?.previewUrl || |
| | |
| | | |
| | | return { |
| | | ...file, |
| | | type: viewType, |
| | | name: |
| | | file?.originalFilename || file?.bucketFilename || file?.name || "附件", |
| | | name: file?.originalFilename || file?.bucketFilename || file?.name || "附件", |
| | | bucketFilename: file?.bucketFilename || file?.name, |
| | | originalFilename: file?.originalFilename || file?.name, |
| | | url: u, |
| | | downloadUrl: u, |
| | | size: file?.byteSize || file?.size || 0, |
| | | }; |
| | | }; |
| | | |
| | | attachmentList.value.push(...finalBefore.map(f => mapToViewFile(f, 0))); |
| | | attachmentList.value.push(...finalDuring.map(f => mapToViewFile(f, 1))); |
| | | attachmentList.value.push(...finalAfter.map(f => mapToViewFile(f, 2))); |
| | | }); |
| | | }; |
| | | |
| | | // 将后端返回的文件地址规范成可访问URL |
| | |
| | | uni.navigateBack(); |
| | | }; |
| | | |
| | | // 切换查看类型 |
| | | const switchViewType = type => { |
| | | currentViewType.value = type; |
| | | }; |
| | | |
| | | // 根据type获取对应分类的附件 |
| | | const getAttachmentsByType = typeValue => { |
| | | return attachmentList.value.filter(file => file.type === typeValue) || []; |
| | | }; |
| | | |
| | | // 获取当前查看类型的附件 |
| | | const getCurrentViewAttachments = () => { |
| | | switch (currentViewType.value) { |
| | | case "before": |
| | | return getAttachmentsByType(0); |
| | | case "after": |
| | | return getAttachmentsByType(1); |
| | | case "issue": |
| | | return getAttachmentsByType(2); |
| | | default: |
| | | return []; |
| | | } |
| | | }; |
| | | |
| | | // 判断是否为图片文件 |
| | | const isImageFile = file => { |
| | | if (file.contentType && file.contentType.startsWith("image/")) { |
| | |
| | | // 预览附件 |
| | | const previewAttachment = file => { |
| | | if (isImageFile(file)) { |
| | | const imageUrls = getCurrentViewAttachments() |
| | | const imageUrls = attachmentList.value |
| | | .filter(f => isImageFile(f)) |
| | | .map(f => f.url || f.downloadUrl); |
| | | |
| | |
| | | |
| | | .attachment-content { |
| | | padding: 15px; |
| | | } |
| | | |
| | | /* 标签页样式 */ |
| | | .attachment-tabs { |
| | | display: flex; |
| | | background: #fff; |
| | | border-radius: 12px; |
| | | margin-bottom: 15px; |
| | | padding: 4px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); |
| | | } |
| | | |
| | | .tab-item { |
| | | flex: 1; |
| | | text-align: center; |
| | | padding: 12px 8px; |
| | | font-size: 14px; |
| | | color: #666; |
| | | border-radius: 8px; |
| | | transition: all 0.3s ease; |
| | | } |
| | | |
| | | .tab-item.active { |
| | | background: #409eff; |
| | | color: #fff; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | /* 附件列表样式 */ |