| | |
| | | <view class="task-list"> |
| | | <view v-for="(item, index) in taskTableData" |
| | | :key="index" |
| | | class="task-item"> |
| | | class="task-item" |
| | | :class="{ 'uninspected': item.fileStatus == 1 }"> |
| | | <view class="task-header"> |
| | | <view class="task-info"> |
| | | <text class="task-name">{{ item.taskName }}</text> |
| | |
| | | <view class="task-actions"> |
| | | <u-button type="primary" |
| | | size="small" |
| | | @click.stop="startScanForTask(item)" |
| | | v-if="item.fileStatus!=2" |
| | | @click.stop="startScanForTask1(item)" |
| | | :customStyle="{ |
| | | borderRadius: '15px', |
| | | height: '30px', |
| | | fontSize: '12px', |
| | | marginRight: '8px' |
| | | }"> |
| | | 扫码上传 |
| | | 巡检上传 |
| | | </u-button> |
| | | <u-button type="success" |
| | | size="small" |
| | |
| | | <view class="task-details"> |
| | | <view class="detail-item"> |
| | | <text class="detail-label">任务ID</text> |
| | | <text class="detail-value">{{ item.taskId || item.id }}</text> |
| | | <text class="detail-value">{{ item.id }}</text> |
| | | </view> |
| | | <view class="detail-item"> |
| | | <text class="detail-label">备注</text> |
| | |
| | | type="success" |
| | | inverted></uni-tag> |
| | | <uni-tag v-else-if="item.fileStatus==1" |
| | | text="巡检中" |
| | | text="超期" |
| | | size="small" |
| | | type="primary" |
| | | type="error" |
| | | inverted></uni-tag> |
| | | <uni-tag v-else="" |
| | | <uni-tag v-else |
| | | text="未巡检" |
| | | size="small" |
| | | type="warning" |
| | |
| | | </view> |
| | | <view class="upload-popup-body"> |
| | | <!-- 分类标签页 --> |
| | | <view class="upload-tabs"> |
| | | <!-- <view class="upload-tabs"> |
| | | <view class="tab-item" |
| | | :class="{ active: currentUploadType === 'before' }" |
| | | @click="switchUploadType('before')"> |
| | |
| | | @click="switchUploadType('issue')"> |
| | | 生产后 |
| | | </view> |
| | | </view> |
| | | </view> --> |
| | | <!-- 异常状态选择 --> |
| | | <view class="exception-section"> |
| | | <text class="section-title">是否存在异常?</text> |
| | |
| | | style="margin-right: 5px;"></u-icon> |
| | | {{ uploading ? '上传中...' : '拍照' }} |
| | | </u-button> |
| | | <u-button type="success" |
| | | <!-- <u-button type="success" |
| | | @click="chooseMedia('video')" |
| | | :loading="uploading" |
| | | :disabled="getCurrentFiles().length >= uploadConfig.limit" |
| | |
| | | color="#fff" |
| | | style="margin-right: 5px;"></uni-icons> |
| | | {{ uploading ? '上传中...' : '拍视频' }} |
| | | </u-button> |
| | | </u-button> --> |
| | | </view> |
| | | <!-- 上传进度 --> |
| | | <view v-if="uploading" |
| | |
| | | :key="index" |
| | | class="file-item"> |
| | | <view class="file-preview-container"> |
| | | <!-- 删除按钮 --> |
| | | <view class="delete-btn" |
| | | @click="removeFile(index)"> |
| | | <u-icon name="close" |
| | | size="12" |
| | | color="#fff"></u-icon> |
| | | </view> |
| | | <image v-if="file.type === 'image' || (file.type !== 'video' && !file.type)" |
| | | :src="file.url || file.tempFilePath || file.path || file.downloadUrl" |
| | | class="file-preview" |
| | |
| | | style="margin-right: 5px;"></uni-icons> |
| | | <text class="video-text">视频</text> |
| | | </view> |
| | | <!-- 删除按钮 --> |
| | | <view class="delete-btn" |
| | | @click="removeFile(index)"> |
| | | <u-icon name="close" |
| | | size="12" |
| | | color="#fff"></u-icon> |
| | | </view> |
| | | </view> |
| | | <view class="file-info"> |
| | | <text class="file-name">{{ file.bucketFilename || file.name || (file.type === 'image' ? '图片' : '视频') |
| | |
| | | </view> |
| | | <view v-if="getCurrentFiles().length === 0" |
| | | class="empty-state"> |
| | | <text>请选择要上传的{{ getUploadTypeText() }}图片或视频</text> |
| | | <text>请选择要上传的{{ getUploadTypeText() }}图片</text> |
| | | </view> |
| | | <!-- 统计信息 --> |
| | | <view class="upload-summary"> |
| | | <!-- <view class="upload-summary"> |
| | | <text class="summary-text"> |
| | | 生产前: {{ beforeModelValue.length }}个文件 | |
| | | 生产中: {{ afterModelValue.length }}个文件 | |
| | | 生产后: {{ issueModelValue.length }}个文件 |
| | | </text> |
| | | </view> |
| | | </view> --> |
| | | </view> |
| | | </view> |
| | | <view class="upload-popup-footer"> |
| | |
| | | </view> |
| | | <view class="attachment-popup-body"> |
| | | <!-- 分类标签页 --> |
| | | <view class="attachment-tabs"> |
| | | <!-- <view class="attachment-tabs"> |
| | | <view class="tab-item" |
| | | :class="{ active: currentViewType === 'before' }" |
| | | @click="switchViewType('before')"> |
| | |
| | | @click="switchViewType('issue')"> |
| | | 生产后 ({{ getAttachmentsByType(2).length }}) |
| | | </view> |
| | | </view> |
| | | </view> --> |
| | | <!-- 当前分类的附件列表 --> |
| | | <view class="attachment-content"> |
| | | <view v-if="getCurrentViewAttachments().length > 0" |
| | |
| | | class="attachment-item" |
| | | @click="previewAttachment(file)"> |
| | | <view class="attachment-preview-container"> |
| | | <!-- {{formatFileUrl(file.url || file.downloadUrl)}} --> |
| | | <image v-if="file.type === 'image' || isImageFile(file)" |
| | | :src="file.url || file.downloadUrl" |
| | | :src="formatFileUrl(file.url || file.downloadUrl)" |
| | | class="attachment-preview" |
| | | mode="aspectFill" /> |
| | | <view v-else |
| | |
| | | |
| | | // 计算上传URL |
| | | const uploadFileUrl = computed(() => { |
| | | const baseUrl = "http://114.132.189.42:9030"; |
| | | const baseUrl = config.baseUrl; |
| | | |
| | | return baseUrl + uploadConfig.action; |
| | | }); |
| | |
| | | }; |
| | | |
| | | const getFileStatus = record => { |
| | | let _beforeProduction = |
| | | record.beforeProduction && record.beforeProduction.length; |
| | | let _afterProduction = |
| | | record.afterProduction && record.afterProduction.length; |
| | | let _productionIssues = |
| | | record.productionIssues && record.productionIssues.length; |
| | | if (_beforeProduction && _afterProduction && _productionIssues) { |
| | | // let _beforeProduction = |
| | | // record.beforeProduction && record.beforeProduction.length; |
| | | // let _afterProduction = |
| | | // record.afterProduction && record.afterProduction.length; |
| | | // let _productionIssues = |
| | | // record.productionIssues && record.productionIssues.length; |
| | | // if (_beforeProduction && _afterProduction && _productionIssues) { |
| | | // return 2; |
| | | // } else if (_beforeProduction || _afterProduction || _productionIssues) { |
| | | // return 1; |
| | | // } else { |
| | | // return 0; |
| | | // } |
| | | // let _beforeProduction = |
| | | // record.beforeProduction && record.beforeProduction.length; |
| | | if (record.takePhone) { |
| | | if (record.commonFileListBefore && record.commonFileListBefore.length) { |
| | | return 2; |
| | | } |
| | | if (record.frequencyType == "DAILY") { |
| | | if (Number(record.inspectionDeadline) && record.createTime) { |
| | | // 计算时间差(小时) |
| | | const now = new Date().getTime(); |
| | | const createTime = new Date(record.createTime).getTime(); |
| | | const hoursDiff = (now - createTime) / (1000 * 60 * 60); |
| | | if (hoursDiff > Number(record.inspectionDeadline)) { |
| | | return 1; |
| | | } |
| | | } |
| | | } else { |
| | | if (Number(record.inspectionDeadline) && record.createTime) { |
| | | // 计算时间差(天) |
| | | const now = new Date().getTime(); |
| | | const createTime = new Date(record.createTime).getTime(); |
| | | const daysDiff = (now - createTime) / (1000 * 60 * 60 * 24); |
| | | if (daysDiff > Number(record.inspectionDeadline)) { |
| | | return 1; |
| | | } |
| | | } |
| | | } |
| | | return 0; |
| | | } else if (record.inspectionSubmitted) { |
| | | return 2; |
| | | } else if (_beforeProduction || _afterProduction || _productionIssues) { |
| | | return 1; |
| | | } else { |
| | | if (record.frequencyType == "DAILY") { |
| | | if (Number(record.inspectionDeadline) && record.createTime) { |
| | | // 计算时间差(小时) |
| | | const now = new Date().getTime(); |
| | | const createTime = new Date(record.createTime).getTime(); |
| | | const hoursDiff = (now - createTime) / (1000 * 60 * 60); |
| | | if (hoursDiff > Number(record.inspectionDeadline)) { |
| | | return 1; |
| | | } |
| | | } |
| | | } else { |
| | | if (Number(record.inspectionDeadline) && record.createTime) { |
| | | // 计算时间差(天) |
| | | const now = new Date().getTime(); |
| | | const createTime = new Date(record.createTime).getTime(); |
| | | const daysDiff = (now - createTime) / (1000 * 60 * 60 * 24); |
| | | if (daysDiff > Number(record.inspectionDeadline)) { |
| | | return 1; |
| | | } |
| | | } |
| | | } |
| | | return 0; |
| | | } |
| | | }; |
| | |
| | | return; |
| | | } |
| | | |
| | | const currentTaskId = |
| | | currentScanningTask.value?.taskId || currentScanningTask.value?.id; |
| | | const currentTaskId = currentScanningTask.value?.id; |
| | | if (!currentTaskId) { |
| | | uni.showToast({ title: "任务信息缺失", icon: "error" }); |
| | | return; |
| | |
| | | if (task) { |
| | | infoData.value = { |
| | | ...task, |
| | | taskId: task.taskId || task.id, |
| | | storageBlobDTO: [], // 初始化文件列表 |
| | | }; |
| | | } |
| | |
| | | // 显示上传弹窗 |
| | | showUploadDialog.value = true; |
| | | }; |
| | | const startScanForTask1 = async task => { |
| | | currentScanningTask.value = task; |
| | | if (task) { |
| | | infoData.value = { |
| | | ...task, |
| | | storageBlobDTO: [], // 初始化文件列表 |
| | | }; |
| | | } |
| | | |
| | | // 设置上传状态类型(可以根据任务类型设置不同的状态) |
| | | uploadStatusType.value = 0; // 默认状态 |
| | | |
| | | // 清空之前的文件 |
| | | uploadFiles.value = []; |
| | | showUploadDialog.value = true; |
| | | }; |
| | | // 关闭上传弹窗 |
| | | const closeUploadDialog = () => { |
| | | showUploadDialog.value = false; |
| | |
| | | try { |
| | | // 存储当前任务信息到本地存储,供报修页面使用 |
| | | const taskInfo = { |
| | | taskId: infoData.value?.taskId || infoData.value?.id, |
| | | id: infoData.value?.id, |
| | | taskName: infoData.value?.taskName, |
| | | inspectionLocation: infoData.value?.inspectionLocation, |
| | | inspector: infoData.value?.inspector, |
| | |
| | | |
| | | // 提交上传 |
| | | const submitUpload = async () => { |
| | | // console.log("提交上传数据:", { |
| | | // before: beforeModelValue.value, |
| | | // after: afterModelValue.value, |
| | | // issue: issueModelValue.value, |
| | | // }); |
| | | try { |
| | | // 检查是否选择了异常状态 |
| | | if (hasException.value === null) { |
| | |
| | | beforeModelValue.value.length + |
| | | afterModelValue.value.length + |
| | | issueModelValue.value.length; |
| | | if (totalFiles === 0) { |
| | | uni.showToast({ |
| | | title: "请先上传文件", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | if (currentScanningTask.value.takePhone) { |
| | | if (totalFiles === 0) { |
| | | uni.showToast({ |
| | | title: "请先上传文件", |
| | | icon: "none", |
| | | }); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | // 显示提交中的加载提示 |
| | |
| | | let arr = []; |
| | | if (beforeModelValue.value.length > 0) { |
| | | arr.push(...beforeModelValue.value); |
| | | infoData.value.beforeModelValue = beforeModelValue.value; |
| | | } |
| | | if (afterModelValue.value.length > 0) { |
| | | arr.push(...afterModelValue.value); |
| | | infoData.value.afterModelValue = afterModelValue.value; |
| | | } |
| | | if (issueModelValue.value.length > 0) { |
| | | arr.push(...issueModelValue.value); |
| | | infoData.value.issueModelValue = issueModelValue.value; |
| | | } |
| | | |
| | | // 传给后端的临时文件ID列表(tempFileIds) |
| | |
| | | // 添加异常状态信息 |
| | | infoData.value.hasException = hasException.value; |
| | | infoData.value.tempFileIds = tempFileIds; |
| | | const result = await uploadInspectionTask({ ...infoData.value }); |
| | | const result = await uploadInspectionTask({ |
| | | ...infoData.value, |
| | | inspectionSubmitted: true, |
| | | }); |
| | | |
| | | // 检查提交结果 |
| | | if (result && (result.code === 200 || result.success)) { |
| | |
| | | }; |
| | | |
| | | // 文件访问基础域(后端要求前缀) |
| | | const filePreviewBase = "http://114.132.189.42:9098"; |
| | | const filePreviewBase = config.fileUrl; |
| | | |
| | | // 将后端返回的文件地址规范成可访问URL |
| | | // 兼容场景: |
| | |
| | | count: Math.min(remaining, 1), |
| | | mediaType: [type || "image"], |
| | | sizeType: ["compressed", "original"], |
| | | sourceType: ["camera"], |
| | | sourceType: currentScanningTask.value?.takeAlbum |
| | | ? ["camera", "album"] |
| | | : ["camera"], // 是否允许相册上传 |
| | | success: res => { |
| | | try { |
| | | const files = res?.tempFiles || []; |
| | |
| | | createTime: Date.now(), |
| | | uid: Date.now() + Math.random() + idx, |
| | | }; |
| | | |
| | | console.log("chooseMedia 成功获取文件:", file); |
| | | handleBeforeUpload(file); |
| | | }); |
| | | } catch (e) { |
| | |
| | | uni.chooseImage({ |
| | | count: 1, |
| | | sizeType: ["compressed", "original"], |
| | | sourceType: ["camera"], |
| | | sourceType: ["camera", "album"], |
| | | success: res => { |
| | | const tempFilePath = res?.tempFilePaths?.[0]; |
| | | const tempFile = res?.tempFiles?.[0] || {}; |
| | |
| | | count: 1, |
| | | mediaType: ["image", "video"], |
| | | sizeType: ["compressed", "original"], |
| | | sourceType: ["camera"], |
| | | sourceType: ["camera", "album"], |
| | | success: res => { |
| | | try { |
| | | if (!res.tempFiles || res.tempFiles.length === 0) { |
| | |
| | | }; |
| | | |
| | | uploadList.value.push(fileData); |
| | | |
| | | console.log("添加到分类前:", fileData); |
| | | // 立即添加到对应的分类,不等待所有文件上传完成 |
| | | switch (currentUploadType.value) { |
| | | case "before": |
| | |
| | | const uploadedSuccessfully = () => { |
| | | // 此函数已不再使用,文件上传成功后立即添加到对应分类 |
| | | }; |
| | | |
| | | // 格式化文件URL |
| | | const formatFileUrl = url => { |
| | | if (!url) return ""; |
| | | if (url.startsWith("http://") || url.startsWith("https://")) { |
| | | return url; |
| | | } |
| | | // const uploadsIndex = url.indexOf("uploads"); |
| | | // if (uploadsIndex !== -1) { |
| | | // const relativePath = url.substring(uploadsIndex); |
| | | // return `${config.fileUrl}/${relativePath}`; |
| | | // } |
| | | return `${config.fileUrl}/${url}`; |
| | | }; |
| | | // 格式化文件大小 |
| | | const formatFileSize = size => { |
| | | if (!size) return ""; |
| | |
| | | padding: 15px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
| | | transition: all 0.3s ease; |
| | | } |
| | | |
| | | .task-item.uninspected { |
| | | border: 1px solid #f56c6cb3; |
| | | background-color: #fef2f2; |
| | | } |
| | | |
| | | .task-item.uninspected .task-name, |
| | | .task-item.uninspected .task-location, |
| | | .task-item.uninspected .detail-value { |
| | | color: #000000; |
| | | } |
| | | |
| | | .task-header { |
| | |
| | | right: 0; |
| | | bottom: 0; |
| | | background: rgba(0, 0, 0, 0.5); |
| | | z-index: 10000; |
| | | z-index: 100; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | |
| | | cursor: pointer; |
| | | box-shadow: 0 2px 4px rgba(255, 71, 87, 0.3); |
| | | transition: all 0.3s ease; |
| | | z-index: 1000; |
| | | } |
| | | |
| | | .delete-btn:hover { |