| | |
| | | |
| | | </view> |
| | | |
| | | <!-- 扫码区域 - 全局弹窗 --> |
| | | <view v-if="isScanning" class="qr-scan-overlay"> |
| | | <view class="qr-scan-container"> |
| | | <view class="scan-header"> |
| | | <text class="scan-title">扫描二维码</text> |
| | | <u-button type="error" size="small" @click.stop="stopScan" :customStyle="{ |
| | | borderRadius: '15px', |
| | | height: '30px', |
| | | fontSize: '12px' |
| | | }"> |
| | | 关闭 |
| | | </u-button> |
| | | </view> |
| | | <camera class="qr-camera" device-position="back" flash="off" @scancode="handleScanCode" |
| | | @error="handleCameraError"></camera> |
| | | <view class="scan-frame-wrapper"> |
| | | <view class="scan-frame"></view> |
| | | <view class="scan-tip">请将二维码放入框内</view> |
| | | </view> |
| | | <u-alert v-if="cameraError" :title="cameraError" type="error" :showIcon="true" :closable="true" |
| | | @close="cameraError = ''" :customStyle="{ |
| | | margin: '10px 0' |
| | | }"></u-alert> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 图片上传弹窗 - 原生实现 --> |
| | | <view v-if="showUploadDialog" class="custom-modal-overlay" @click="closeUploadDialog"> |
| | | <view class="custom-modal-container" @click.stop> |
| | |
| | | <view v-if="getCurrentFiles().length > 0" class="file-list"> |
| | | <view v-for="(file, index) in getCurrentFiles()" :key="index" class="file-item"> |
| | | <view class="file-preview-container"> |
| | | <image v-if="file?.path?.fileType === 'image'" |
| | | :src="file?.url || file?.tempFilePath?.tempFilePath || file?.path?.tempFilePath" |
| | | <image v-if="file.type === 'image' || (file.type !== 'video' && !file.type)" |
| | | :src="file.url || file.tempFilePath || file.path || file.downloadUrl" |
| | | class="file-preview" mode="aspectFill" /> |
| | | <view v-else class="video-preview"> |
| | | <view v-else-if="file.type === 'video'" class="video-preview"> |
| | | <uni-icons type="videocam" name="videocam" size="18" color="#fff" |
| | | style="margin-right: 5px;"></uni-icons> |
| | | <text class="video-text">视频</text> |
| | |
| | | import { getLedgerById } from '@/api/equipmentManagement/ledger.js' |
| | | import { inspectionTaskList, uploadInspectionTask } from "@/api/inspectionManagement"; |
| | | import { getToken } from "@/utils/auth"; |
| | | import config from '@/config' |
| | | |
| | | // 组件引用已移除 |
| | | |
| | |
| | | |
| | | // 上传配置 |
| | | const uploadConfig = { |
| | | action: "/common/minioUploads", |
| | | action: "/file/upload", |
| | | limit: 10, |
| | | fileSize: 50, // MB |
| | | fileType: ['jpg', 'jpeg', 'png', 'mp4', 'mov'], |
| | |
| | | if (process.env.VUE_APP_BASE_API) { |
| | | baseUrl = process.env.VUE_APP_BASE_API; |
| | | } else if (process.env.NODE_ENV === 'development') { |
| | | baseUrl = 'http://114.132.189.42:9068'; |
| | | baseUrl = 'http://192.168.1.147:7003'; |
| | | } else { |
| | | baseUrl = 'http://114.132.189.42:9068'; |
| | | baseUrl = 'http://192.168.1.147:7003'; |
| | | } |
| | | |
| | | return baseUrl + uploadConfig.action; |
| | |
| | | |
| | | // 请求取消标志,用于取消正在进行的请求 |
| | | let isRequestCancelled = false |
| | | |
| | | // 扫码相关状态 |
| | | const isScanning = ref(false) |
| | | const cameraError = ref('') |
| | | |
| | | const pagesPames = reactive({ |
| | | size: 10, |
| | |
| | | onUnmounted(() => { |
| | | // 设置取消标志,阻止后续的异步操作 |
| | | isRequestCancelled = true |
| | | |
| | | // 停止扫码 |
| | | if (isScanning.value) { |
| | | isScanning.value = false |
| | | } |
| | | |
| | | // 关闭上传弹窗 |
| | | if (showUploadDialog.value) { |
| | |
| | | } |
| | | } |
| | | |
| | | // 为指定任务开始扫码 |
| | | // 为指定任务开始扫码(真机) |
| | | const startScanForTask = async (task) => { |
| | | try { |
| | | // 记录当前扫描的任务 |
| | | currentScanningTask.value = task |
| | | |
| | | // 显示扫描界面 |
| | | isScanning.value = true |
| | | |
| | | // 使用uniapp的扫码API |
| | | uni.scanCode({ |
| | | success: (res) => { |
| | | handleScanSuccess(res) |
| | | }, |
| | | fail: (err) => { |
| | | console.error('扫码失败:', err) |
| | | uni.showToast({ |
| | | title: '扫码失败', |
| | | icon: 'error' |
| | | }) |
| | | // 关闭扫描界面 |
| | | isScanning.value = false |
| | | } |
| | | }) |
| | | } catch (e) { |
| | | console.error('启动扫码失败:', e) |
| | | uni.showToast({ |
| | | title: '启动扫码失败', |
| | | icon: 'error' |
| | | }) |
| | | isScanning.value = false |
| | | } |
| | | } |
| | | |
| | | // 停止扫码 |
| | | const stopScan = () => { |
| | | isScanning.value = false |
| | | currentScanningTask.value = null |
| | | } |
| | | |
| | | // 扫码成功处理 |
| | | const handleScanSuccess = async (result) => { |
| | | // 扫码成功处理:校验后打开上传弹窗 |
| | | const handleScanSuccess = (result) => { |
| | | try { |
| | | // 解析二维码数据,提取deviceId |
| | | let deviceId = '' |
| | | |
| | | // 检查是否是URL格式 |
| | | if (result?.result && typeof result.result === 'string') { |
| | | if (result.result.includes('deviceId=')) { |
| | | // 从URL中提取deviceId |
| | | const url = result.result |
| | | const match = url.match(/deviceId=(\d+)/) |
| | | if (match && match[1]) { |
| | | deviceId = match[1] |
| | | } |
| | | const match = result.result.match(/deviceId=(\d+)/) |
| | | if (match && match[1]) deviceId = match[1] |
| | | } else { |
| | | // 尝试解析JSON格式 |
| | | try { |
| | | const qrData = JSON.parse(result.result) |
| | | deviceId = qrData.deviceId || qrData.qrCodeId || '' |
| | | } catch (e) { |
| | | // 如果不是JSON格式,直接使用结果 |
| | | deviceId = result.result |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (!deviceId) { |
| | | uni.showToast({ |
| | | title: '未识别到设备ID', |
| | | icon: 'error' |
| | | }) |
| | | isScanning.value = false |
| | | uni.showToast({ title: '未识别到设备ID', icon: 'error' }) |
| | | return |
| | | } |
| | | |
| | | // 获取当前任务的taskId |
| | | const currentTaskId = currentScanningTask.value?.taskId || currentScanningTask.value?.id |
| | | if (!currentTaskId) { |
| | | uni.showToast({ title: '任务信息缺失', icon: 'error' }) |
| | | return |
| | | } |
| | | |
| | | // 对比deviceId和taskId |
| | | if (deviceId === currentTaskId.toString()) { |
| | | uni.showToast({ |
| | | title: '识别成功', |
| | | icon: 'success' |
| | | }) |
| | | |
| | | // 先关闭扫描界面 |
| | | isScanning.value = false |
| | | |
| | | // 延迟打开上传弹窗,确保扫描界面完全关闭 |
| | | setTimeout(() => { |
| | | uni.showToast({ title: '识别成功', icon: 'success' }) |
| | | openUploadDialog(currentScanningTask.value) |
| | | }, 300) |
| | | } else { |
| | | uni.showToast({ |
| | | title: '请扫描正确的设备', |
| | | icon: 'error' |
| | | }) |
| | | |
| | | // 关闭扫描界面 |
| | | isScanning.value = false |
| | | uni.showToast({ title: '请扫描正确的设备', icon: 'error' }) |
| | | } |
| | | |
| | | } catch (error) { |
| | | console.error('扫码结果处理失败:', error) |
| | | uni.showToast({ |
| | | title: error.message || '数据解析失败', |
| | | title: error?.message || '数据解析失败', |
| | | icon: 'error' |
| | | }) |
| | | // 关闭扫描界面 |
| | | isScanning.value = false |
| | | } |
| | | } |
| | | |
| | | |
| | | // 打开上传弹窗 |
| | | const openUploadDialog = (task) => { |
| | |
| | | arr.push(...issueModelValue.value); |
| | | } |
| | | |
| | | // 传给后端的临时文件ID列表(tempFileIds) |
| | | // 兼容:有些接口可能返回 tempId / tempFileId / id |
| | | let tempFileIds = [] |
| | | if (arr !== null && arr.length > 0) { |
| | | tempFileIds = arr |
| | | .map((item) => item?.tempId ?? item?.tempFileId ?? item?.id) |
| | | .filter((v) => v !== undefined && v !== null && v !== '') |
| | | } |
| | | |
| | | // 提交数据 |
| | | infoData.value.storageBlobDTO = arr; |
| | | // 添加异常状态信息 |
| | | infoData.value.hasException = hasException.value; |
| | | infoData.value.tempFileIds = tempFileIds; |
| | | const result = await uploadInspectionTask({ ...infoData.value }); |
| | | |
| | | // 检查提交结果 |
| | |
| | | } |
| | | } |
| | | |
| | | // 摄像头错误处理 |
| | | const handleCameraError = (error) => { |
| | | cameraError.value = '摄像头访问失败,请检查权限设置' |
| | | } |
| | | |
| | | // 扫码事件处理 |
| | | const handleScanCode = (result) => { |
| | | handleScanSuccess(result) |
| | | } |
| | | |
| | | // 查看附件 |
| | | const viewAttachments = async (task) => { |
| | | try { |
| | |
| | | // 解析新的数据结构 |
| | | attachmentList.value = [] |
| | | |
| | | // 生产前附件 (type=0) |
| | | if (task.beforeProduction && Array.isArray(task.beforeProduction)) { |
| | | const beforeFiles = task.beforeProduction.map(file => ({ |
| | | // 后端反显字段(你提供的数据结构): |
| | | // - commonFileListBefore:生产前(通常 type=10) |
| | | // - commonFileListAfter:生产中(通常 type=11) |
| | | // - commonFileList:可能是全部/兜底(若包含生产后,一般 type=12) |
| | | const allList = Array.isArray(task?.commonFileList) ? task.commonFileList : [] |
| | | const beforeList = Array.isArray(task?.commonFileListBefore) |
| | | ? task.commonFileListBefore |
| | | : allList.filter(f => f?.type === 10) |
| | | const afterList = Array.isArray(task?.commonFileListAfter) |
| | | ? task.commonFileListAfter |
| | | : allList.filter(f => f?.type === 11) |
| | | // 如果后端后续补了 commonFileListIssue,则优先用;否则从 commonFileList 里按 type=12 兜底 |
| | | const issueList = Array.isArray(task?.commonFileListIssue) |
| | | ? task.commonFileListIssue |
| | | : allList.filter(f => f?.type === 12) |
| | | |
| | | const mapToViewFile = (file, viewType) => { |
| | | const u = normalizeFileUrl(file?.url || file?.downloadUrl || '') |
| | | return { |
| | | ...file, |
| | | type: 0 // 确保type为0 |
| | | })) |
| | | attachmentList.value.push(...beforeFiles) |
| | | // 用于三标签页分组:0=生产前 1=生产中 2=生产后 |
| | | type: viewType, |
| | | name: file?.name || file?.originalFilename || file?.bucketFilename, |
| | | bucketFilename: file?.bucketFilename || file?.name, |
| | | originalFilename: file?.originalFilename || file?.name, |
| | | url: u, |
| | | downloadUrl: u, |
| | | size: file?.size || file?.byteSize, |
| | | } |
| | | } |
| | | |
| | | // 生产中附件 (type=1) |
| | | if (task.afterProduction && Array.isArray(task.afterProduction)) { |
| | | const afterFiles = task.afterProduction.map(file => ({ |
| | | ...file, |
| | | type: 1 // 确保type为1 |
| | | })) |
| | | attachmentList.value.push(...afterFiles) |
| | | } |
| | | |
| | | // 生产后附件 (type=2) |
| | | if (task.productionIssues && Array.isArray(task.productionIssues)) { |
| | | const issueFiles = task.productionIssues.map(file => ({ |
| | | ...file, |
| | | type: 2 // 确保type为2 |
| | | })) |
| | | attachmentList.value.push(...issueFiles) |
| | | } |
| | | attachmentList.value.push(...beforeList.map(f => mapToViewFile(f, 0))) |
| | | attachmentList.value.push(...afterList.map(f => mapToViewFile(f, 1))) |
| | | attachmentList.value.push(...issueList.map(f => mapToViewFile(f, 2))) |
| | | |
| | | showAttachmentDialog.value = true |
| | | |
| | |
| | | const getTabType = () => { |
| | | switch (currentUploadType.value) { |
| | | case 'before': |
| | | return 0 |
| | | return 10 |
| | | case 'after': |
| | | return 1 |
| | | return 11 |
| | | case 'issue': |
| | | return 2 |
| | | return 12 |
| | | default: |
| | | return 0 |
| | | return 10 |
| | | } |
| | | } |
| | | // 获取当前查看类型的附件 |
| | |
| | | const name = file.bucketFilename || file.originalFilename || file.name || '' |
| | | const ext = name.split('.').pop()?.toLowerCase() |
| | | return ['jpg', 'jpeg', 'png', 'gif', 'webp'].includes(ext) |
| | | } |
| | | |
| | | // 文件访问基础域(后端要求前缀) |
| | | const filePreviewBase = 'http://114.132.189.42:9098' |
| | | |
| | | // 将后端返回的文件地址规范成可访问URL |
| | | // 兼容场景: |
| | | // - 已经是 http/https:直接返回 |
| | | // - 以 / 开头:拼接 filePreviewBase |
| | | // - Windows 本地路径(如 D:\ruoyi\prod\uploads...\xx.jpg):尝试截取 prod 之后的相对路径并拼接 filePreviewBase |
| | | const normalizeFileUrl = (rawUrl) => { |
| | | try { |
| | | if (!rawUrl || typeof rawUrl !== 'string') return '' |
| | | const url = rawUrl.trim() |
| | | if (!url) return '' |
| | | if (/^https?:\/\//i.test(url)) return url |
| | | if (url.startsWith('/')) return `${filePreviewBase}${url}` |
| | | |
| | | // Windows path -> web path |
| | | if (/^[a-zA-Z]:\\/.test(url)) { |
| | | const normalized = url.replace(/\\/g, '/') |
| | | const idx = normalized.indexOf('/prod/') |
| | | if (idx >= 0) { |
| | | const relative = normalized.slice(idx + '/prod/'.length) |
| | | return `${filePreviewBase}/${relative}` |
| | | } |
| | | // 兜底:无法推断映射规则时,至少把反斜杠变成正斜杠 |
| | | return normalized |
| | | } |
| | | |
| | | // 其他相对路径:直接用 baseUrl 拼一下 |
| | | return `${filePreviewBase}/${url.replace(/^\//, '')}` |
| | | } catch (e) { |
| | | return rawUrl || '' |
| | | } |
| | | } |
| | | |
| | | // 预览附件 |
| | |
| | | }) |
| | | } |
| | | |
| | | // 使用相机 |
| | | // 拍照/拍视频(真机优先用 chooseMedia;不支持则降级) |
| | | const chooseMedia = (type) => { |
| | | let mediaPamaes = { |
| | | count: 1, |
| | | if (getCurrentFiles().length >= uploadConfig.limit) { |
| | | uni.showToast({ title: `最多只能选择${uploadConfig.limit}个文件`, icon: 'none' }) |
| | | return |
| | | } |
| | | |
| | | const remaining = uploadConfig.limit - getCurrentFiles().length |
| | | |
| | | // 优先:chooseMedia(支持 image/video) |
| | | if (typeof uni.chooseMedia === 'function') { |
| | | uni.chooseMedia({ |
| | | count: Math.min(remaining, 1), |
| | | mediaType: [type || 'image'], |
| | | sizeType: ['compressed', 'original'], |
| | | sourceType: ['camera'], |
| | | } |
| | | uni.chooseMedia({ |
| | | ...mediaPamaes, |
| | | success: (res) => { |
| | | try { |
| | | if (!res.tempFiles || res.tempFiles.length === 0) { |
| | | throw new Error('未获取到图片文件'); |
| | | } |
| | | const files = res?.tempFiles || [] |
| | | if (!files.length) throw new Error('未获取到文件') |
| | | |
| | | const tempFilePath = res.tempFiles[0]; |
| | | const tempFile = res.tempFiles && res.tempFiles[0] ? res.tempFiles[0] : {}; |
| | | |
| | | files.forEach((tf, idx) => { |
| | | const filePath = tf.tempFilePath || tf.path || '' |
| | | const fileType = tf.fileType || type || 'image' |
| | | const ext = fileType === 'video' ? 'mp4' : 'jpg' |
| | | const file = { |
| | | tempFilePath: tempFilePath, |
| | | path: tempFilePath, // 保持兼容性 |
| | | type: 'image', |
| | | name: `photo_${Date.now()}.jpg`, |
| | | size: tempFile.size || 0, |
| | | createTime: new Date().getTime(), |
| | | uid: Date.now() + Math.random() |
| | | }; |
| | | |
| | | handleBeforeUpload(file); |
| | | } catch (error) { |
| | | console.error('处理拍照结果失败:', error); |
| | | uni.showToast({ |
| | | title: '处理图片失败', |
| | | icon: 'error' |
| | | }); |
| | | tempFilePath: filePath, |
| | | path: filePath, |
| | | type: fileType, |
| | | name: `${fileType}_${Date.now()}_${idx}.${ext}`, |
| | | size: tf.size || 0, |
| | | duration: tf.duration || 0, |
| | | createTime: Date.now(), |
| | | uid: Date.now() + Math.random() + idx |
| | | } |
| | | handleBeforeUpload(file) |
| | | }) |
| | | } catch (e) { |
| | | console.error('处理拍摄结果失败:', e) |
| | | uni.showToast({ title: '处理文件失败', icon: 'error' }) |
| | | } |
| | | }, |
| | | fail: (err) => { |
| | | console.error('拍照失败:', err); |
| | | uni.showToast({ |
| | | title: '拍照失败: ' + (err.errMsg || '未知错误'), |
| | | icon: 'error' |
| | | }); |
| | | console.error('拍摄失败:', err) |
| | | uni.showToast({ title: '拍摄失败', icon: 'error' }) |
| | | } |
| | | }) |
| | | return |
| | | } |
| | | |
| | | // 降级:chooseImage / chooseVideo |
| | | if (type === 'video') { |
| | | chooseVideo() |
| | | } else { |
| | | uni.chooseImage({ |
| | | count: 1, |
| | | sizeType: ['compressed', 'original'], |
| | | sourceType: ['camera'], |
| | | success: (res) => { |
| | | const tempFilePath = res?.tempFilePaths?.[0] |
| | | const tempFile = res?.tempFiles?.[0] || {} |
| | | if (!tempFilePath) return |
| | | handleBeforeUpload({ |
| | | tempFilePath, |
| | | path: tempFilePath, |
| | | type: 'image', |
| | | name: `photo_${Date.now()}.jpg`, |
| | | size: tempFile.size || 0, |
| | | createTime: Date.now(), |
| | | uid: Date.now() + Math.random() |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | |
| | | // 拍照 |
| | |
| | | |
| | | // 上传前校验 |
| | | const handleBeforeUpload = async (file) => { |
| | | // 检查网络连接 |
| | | const hasNetwork = await checkNetworkConnection(); |
| | | if (!hasNetwork) { |
| | | uni.showToast({ |
| | | title: '网络连接不可用,请检查网络设置', |
| | | icon: 'none' |
| | | }); |
| | | return false; |
| | | } |
| | | |
| | | // 校验文件大小 |
| | | if (uploadConfig.fileSize && file.size) { |
| | | const isLt = file.size / 1024 / 1024 < uploadConfig.fileSize; |
| | | if (!isLt) { |
| | | uni.showToast({ |
| | | title: `文件大小不能超过 ${uploadConfig.fileSize} MB!`, |
| | | icon: 'none' |
| | | }); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | // 校验视频时长 |
| | | if (file.type === 'video' && file.duration && file.duration > uploadConfig.maxVideoDuration) { |
| | | uni.showToast({ |
| | | title: `视频时长不能超过 ${uploadConfig.maxVideoDuration} 秒!`, |
| | | icon: 'none' |
| | | }); |
| | | return false; |
| | | } |
| | | |
| | | // 校验文件类型 |
| | | if (uploadConfig.fileType && Array.isArray(uploadConfig.fileType) && uploadConfig.fileType.length > 0) { |
| | |
| | | return true; |
| | | } |
| | | |
| | | // 文件上传处理 |
| | | const uploadFile = (file) => { |
| | | // 文件上传处理(真机走 uni.uploadFile) |
| | | const uploadFile = async (file) => { |
| | | uploading.value = true; |
| | | uploadProgress.value = 0; |
| | | number.value++; // 增加上传计数 |
| | | |
| | | // 确保文件路径正确 |
| | | const filePath = file.tempFilePath?.tempFilePath || file.path?.tempFilePath || ''; |
| | | if (!filePath) { |
| | | handleUploadError('文件路径不存在'); |
| | | return; |
| | | } |
| | | |
| | | // 确保token存在 |
| | | const token = getToken(); |
| | |
| | | return; |
| | | } |
| | | |
| | | // 准备上传参数 |
| | | const uploadParams = { |
| | | const typeValue = getTabType(); // 生产前:10, 生产中:11, 生产后:12 |
| | | |
| | | uploadWithUniUploadFile(file, file.tempFilePath || file.path || '', typeValue, token); |
| | | } |
| | | |
| | | // 使用uni.uploadFile上传(非H5环境或H5回退方案) |
| | | const uploadWithUniUploadFile = (file, filePath, typeValue, token) => { |
| | | if (!filePath) { |
| | | handleUploadError('文件路径不存在'); |
| | | return; |
| | | } |
| | | |
| | | const uploadTask = uni.uploadFile({ |
| | | url: uploadFileUrl.value, |
| | | filePath: filePath, |
| | | name: 'files', |
| | | name: 'file', |
| | | formData: { |
| | | type: getTabType() || 0 |
| | | type: typeValue |
| | | }, |
| | | header: { |
| | | 'Authorization': `Bearer ${token}` |
| | | } |
| | | }; |
| | | const uploadTask = uni.uploadFile({ |
| | | ...uploadParams, |
| | | }, |
| | | success: (res) => { |
| | | try { |
| | | if (res.statusCode === 200) { |
| | |
| | | } |
| | | |
| | | // 上传失败处理 |
| | | const handleUploadError = (message = '上传文件失败', showRetry = true) => { |
| | | const handleUploadError = (message = '上传文件失败', showRetry = false) => { |
| | | uploading.value = false; |
| | | uploadProgress.value = 0; |
| | | |
| | | if (showRetry) { |
| | | uni.showModal({ |
| | | title: '上传失败', |
| | |
| | | |
| | | // 上传成功回调 |
| | | const handleUploadSuccess = (res, file) => { |
| | | if (res.code === 200 && res.data && Array.isArray(res.data) && res.data.length > 0) { |
| | | const uploadedFile = res.data[0]; |
| | | console.log('上传成功响应:', res); |
| | | |
| | | // 处理不同的数据结构:可能是数组,也可能是单个对象 |
| | | let uploadedFile = null; |
| | | uploadedFile = res.data; |
| | | |
| | | if (!uploadedFile) { |
| | | console.error('无法解析上传响应数据:', res); |
| | | number.value--; // 上传失败时减少计数 |
| | | handleUploadError('上传响应数据格式错误', false); |
| | | return; |
| | | } |
| | | |
| | | // 根据当前上传类型设置type字段 |
| | | let typeValue = 0; // 默认为生产前 |
| | |
| | | const fileData = { |
| | | ...file, |
| | | id: uploadedFile.id, // 添加服务器返回的id |
| | | url: uploadedFile.url || uploadedFile.downloadUrl, |
| | | bucketFilename: uploadedFile.bucketFilename || file.name, |
| | | tempId: uploadedFile.tempId ?? uploadedFile.tempFileId ?? uploadedFile.id, |
| | | url: uploadedFile.url || uploadedFile.downloadUrl || file.tempFilePath || file.path, |
| | | bucketFilename: uploadedFile.bucketFilename || uploadedFile.originalFilename || file.name, |
| | | downloadUrl: uploadedFile.downloadUrl || uploadedFile.url, |
| | | size: uploadedFile.size || file.size, |
| | | size: uploadedFile.size || uploadedFile.byteSize || file.size, |
| | | createTime: uploadedFile.createTime || new Date().getTime(), |
| | | type: typeValue // 添加类型字段:0=生产前, 1=生产中, 2=生产后 |
| | | }; |
| | | |
| | | uploadList.value.push(fileData); |
| | | uploadedSuccessfully(); |
| | | } else { |
| | | number.value--; // 上传失败时减少计数 |
| | | handleUploadError(res.msg || '上传失败'); |
| | | } |
| | | } |
| | | |
| | | // 上传结束处理 |
| | | const uploadedSuccessfully = () => { |
| | | if (number.value > 0 && uploadList.value.length === number.value) { |
| | | // 根据当前上传类型,将文件添加到对应的分类 |
| | | // 立即添加到对应的分类,不等待所有文件上传完成 |
| | | switch (currentUploadType.value) { |
| | | case 'before': |
| | | beforeModelValue.value = [...beforeModelValue.value, ...uploadList.value]; |
| | | beforeModelValue.value.push(fileData); |
| | | break; |
| | | case 'after': |
| | | afterModelValue.value = [...afterModelValue.value, ...uploadList.value]; |
| | | afterModelValue.value.push(fileData); |
| | | break; |
| | | case 'issue': |
| | | issueModelValue.value = [...issueModelValue.value, ...uploadList.value]; |
| | | issueModelValue.value.push(fileData); |
| | | break; |
| | | } |
| | | |
| | | // 重置状态 |
| | | // 重置上传列表(因为已经添加到对应分类了) |
| | | uploadList.value = []; |
| | | number.value = 0; |
| | | } |
| | | |
| | | // 上传结束处理(已废弃,现在在handleUploadSuccess中直接处理) |
| | | const uploadedSuccessfully = () => { |
| | | // 此函数已不再使用,文件上传成功后立即添加到对应分类 |
| | | } |
| | | |
| | | // 格式化文件大小 |