| | |
| | | <!-- 页面头部 --> |
| | | <PageHeader title="巡检上传" @back="goBack" /> |
| | | |
| | | <!-- 搜索区域 --> |
| | | <view class="search-section"> |
| | | <up-input |
| | | v-model="searchAll" |
| | | placeholder="请输入设备名称" |
| | | prefixIcon="search" |
| | | border="surround" |
| | | :clearable="true" |
| | | @change="handleSearch" |
| | | @clear="handleClear" |
| | | ></up-input> |
| | | </view> |
| | | |
| | | <!-- 数据列表 --> |
| | | <view class="table-section"> |
| | | <!-- 生产巡检列表 --> |
| | |
| | | <view class="detail-item"> |
| | | <text class="detail-label">巡检状态</text> |
| | | <view class="detail-value"> |
| | | <uni-tag v-if="item.fileStatus==2" text="已完成" size="small" type="success" inverted></uni-tag> |
| | | <uni-tag v-else-if="item.fileStatus==1" text="巡检中" size="small" type="primary" inverted></uni-tag> |
| | | <uni-tag v-if="item.status=='已巡检'" text="已巡检" size="small" type="success" inverted></uni-tag> |
| | | <uni-tag v-else="" text="未巡检" size="small" type="warning" inverted></uni-tag> |
| | | </view> |
| | | </view> |
| | |
| | | <view v-for="(file, index) in getCurrentViewAttachments()" :key="index" class="attachment-item" |
| | | @click="previewAttachment(file)"> |
| | | <view class="attachment-preview-container"> |
| | | <image v-if="file.type === 'image' || isImageFile(file)" :src="file.url || file.downloadUrl" |
| | | <image v-if="file.type === 'image' || isImageFile(file)" :src="getAttachmentImageUrl(file)" |
| | | class="attachment-preview" mode="aspectFill" /> |
| | | <view v-else class="attachment-video-preview"> |
| | | <u-icon name="video" size="24" color="#409eff"></u-icon> |
| | |
| | | // 异常状态 |
| | | const hasException = ref(null) // null: 未选择, true: 存在异常, false: 正常 |
| | | |
| | | // 搜索相关 |
| | | const searchAll = ref('') |
| | | |
| | | const handleSearch = () => { |
| | | pagesPames.current = 1 |
| | | taskTableData.value = [] |
| | | getList() |
| | | } |
| | | |
| | | const handleClear = () => { |
| | | searchAll.value = '' |
| | | pagesPames.current = 1 |
| | | taskTableData.value = [] |
| | | getList() |
| | | } |
| | | |
| | | // 上传配置 |
| | | const uploadConfig = { |
| | | action: "/file/upload", |
| | |
| | | |
| | | // 计算上传URL |
| | | const uploadFileUrl = computed(() => { |
| | | const baseUrl = 'https://1181ybjh99334.vicp.fun'; |
| | | |
| | | return baseUrl + uploadConfig.action; |
| | | return config.baseUrl + uploadConfig.action; |
| | | }) |
| | | |
| | | // 计算请求头 |
| | |
| | | // 设置取消标志 |
| | | isRequestCancelled = false |
| | | loading.value = true |
| | | inspectionTaskList({...pagesPames}).then(res => { |
| | | |
| | | // 构建查询参数 |
| | | const params = { ...pagesPames } |
| | | if (searchAll.value) { |
| | | params.searchAll = searchAll.value |
| | | } |
| | | |
| | | inspectionTaskList(params).then(res => { |
| | | // 检查组件是否还存在且请求未被取消 |
| | | if (!isRequestCancelled) { |
| | | // 处理不同的数据结构 |
| | |
| | | // 提交上传 |
| | | const submitUpload = async () => { |
| | | try { |
| | | // 检查网络连接 |
| | | const hasNetwork = await checkNetworkConnection(); |
| | | if (!hasNetwork) { |
| | | uni.showModal({ |
| | | title: '网络错误', |
| | | content: '网络连接不可用,请检查网络设置后重试', |
| | | showCancel: false, |
| | | confirmText: '知道了' |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // 检查是否选择了异常状态 |
| | | if (hasException.value === null) { |
| | | uni.showToast({ |
| | |
| | | // 添加异常状态信息 |
| | | infoData.value.hasException = hasException.value; |
| | | infoData.value.tempFileIds = tempFileIds; |
| | | |
| | | const result = await uploadInspectionTask({ ...infoData.value }); |
| | | |
| | | // 检查提交结果 |
| | |
| | | } else { |
| | | // 提交失败 |
| | | closeToast(); |
| | | uni.showToast({ |
| | | title: result?.msg || result?.message || '提交失败', |
| | | icon: 'error' |
| | | }) |
| | | const failMsg = result?.msg || result?.message || '服务器返回错误'; |
| | | uni.showModal({ |
| | | title: '提交失败', |
| | | content: failMsg, |
| | | showCancel: false, |
| | | confirmText: '知道了' |
| | | }); |
| | | } |
| | | |
| | | } catch (error) { |
| | |
| | | errorMessage = error; |
| | | } |
| | | |
| | | uni.showToast({ |
| | | title: errorMessage, |
| | | icon: 'error' |
| | | }) |
| | | // 使用弹窗显示详细错误信息 |
| | | uni.showModal({ |
| | | title: '提交失败', |
| | | content: errorMessage, |
| | | showCancel: false, |
| | | confirmText: '知道了' |
| | | }); |
| | | } |
| | | } |
| | | |
| | |
| | | return ['jpg', 'jpeg', 'png', 'gif', 'webp'].includes(ext) |
| | | } |
| | | |
| | | // 获取查看附件图片的完整URL(javaApi + url) |
| | | const getAttachmentImageUrl = (file) => { |
| | | return file.url |
| | | } |
| | | |
| | | // 文件访问基础域(后端要求前缀) |
| | | const filePreviewBase = 'http://1181ybjh99334.vicp.fun' |
| | | const filePreviewBase = config.javaApi |
| | | |
| | | // 将后端返回的文件地址规范成可访问URL |
| | | // 兼容场景: |
| | |
| | | // 拍照/拍视频(真机优先用 chooseMedia;不支持则降级) |
| | | const chooseMedia = (type) => { |
| | | if (getCurrentFiles().length >= uploadConfig.limit) { |
| | | uni.showToast({ title: `最多只能选择${uploadConfig.limit}个文件`, icon: 'none' }) |
| | | return |
| | | uni.showModal({ |
| | | title: '数量限制', |
| | | content: `最多只能上传 ${uploadConfig.limit} 个文件,请先删除部分文件后再上传`, |
| | | showCancel: false, |
| | | confirmText: '知道了' |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | const remaining = uploadConfig.limit - getCurrentFiles().length |
| | |
| | | handleBeforeUpload(file) |
| | | }) |
| | | } catch (e) { |
| | | console.error('处理拍摄结果失败:', e) |
| | | uni.showToast({ title: '处理文件失败', icon: 'error' }) |
| | | console.error('处理拍摄结果失败:', e); |
| | | uni.showModal({ |
| | | title: '处理失败', |
| | | content: '文件处理失败:' + (e.message || '未知错误'), |
| | | showCancel: false, |
| | | confirmText: '知道了' |
| | | }); |
| | | } |
| | | }, |
| | | fail: (err) => { |
| | | console.error('拍摄失败:', err) |
| | | uni.showToast({ title: '拍摄失败', icon: 'error' }) |
| | | console.error('拍摄失败:', err); |
| | | const msg = err.errMsg || '未知错误'; |
| | | if (msg.includes('cancel')) { |
| | | // 用户取消,不提示 |
| | | return; |
| | | } |
| | | uni.showModal({ |
| | | title: '拍摄失败', |
| | | content: '错误信息:' + msg, |
| | | showCancel: false, |
| | | confirmText: '知道了' |
| | | }); |
| | | } |
| | | }) |
| | | return |
| | | return; |
| | | } |
| | | |
| | | // 降级:chooseImage / chooseVideo |
| | |
| | | ); |
| | | |
| | | if (!isAllowed) { |
| | | uni.showToast({ |
| | | title: `文件格式不支持,请拍摄 ${expectedTypes.join('/')} 格式的文件`, |
| | | icon: 'none' |
| | | uni.showModal({ |
| | | title: '格式不支持', |
| | | content: `当前格式为 .${fileExtension},请拍摄 ${expectedTypes.join('/')} 格式的文件`, |
| | | showCancel: false, |
| | | confirmText: '知道了' |
| | | }); |
| | | return false; |
| | | } |
| | |
| | | // 确保token存在 |
| | | const token = getToken(); |
| | | if (!token) { |
| | | handleUploadError('用户未登录'); |
| | | handleUploadError('用户未登录,请重新登录后再试'); |
| | | return; |
| | | } |
| | | |
| | |
| | | // 使用uni.uploadFile上传(非H5环境或H5回退方案) |
| | | const uploadWithUniUploadFile = (file, filePath, typeValue, token) => { |
| | | if (!filePath) { |
| | | handleUploadError('文件路径不存在'); |
| | | handleUploadError('文件路径不存在,请重新拍摄'); |
| | | return; |
| | | } |
| | | |
| | |
| | | icon: 'success' |
| | | }); |
| | | } else { |
| | | handleUploadError(response.msg || '服务器返回错误'); |
| | | handleUploadError(response.msg || `服务器返回错误 (code: ${response.code})`); |
| | | } |
| | | } else { |
| | | handleUploadError(`服务器错误,状态码: ${res.statusCode}`); |
| | | handleUploadError(`服务器错误,状态码: ${res.statusCode},请稍后重试或联系管理员`); |
| | | } |
| | | } catch (e) { |
| | | console.error('解析响应失败:', e); |
| | | console.error('原始响应数据:', res.data); |
| | | handleUploadError('响应数据解析失败: ' + e.message); |
| | | handleUploadError('服务器响应解析失败,请联系管理员'); |
| | | } |
| | | }, |
| | | fail: (err) => { |
| | | console.error('上传失败:', err.errMsg || err); |
| | | console.error('上传失败:', err); |
| | | number.value--; // 上传失败时减少计数 |
| | | |
| | | let errorMessage = '上传失败'; |
| | | if (err.errMsg) { |
| | | if (err.errMsg.includes('statusCode: null')) { |
| | | errorMessage = '网络连接失败,请检查网络设置'; |
| | | if (err.errMsg.includes('statusCode: null') || err.errMsg.includes('fail')) { |
| | | errorMessage = '网络连接失败,请检查网络设置后重试'; |
| | | } else if (err.errMsg.includes('timeout')) { |
| | | errorMessage = '上传超时,请重试'; |
| | | } else if (err.errMsg.includes('fail')) { |
| | | errorMessage = '上传失败,请检查网络连接'; |
| | | errorMessage = '上传超时,请检查网络后重试'; |
| | | } else { |
| | | errorMessage = err.errMsg; |
| | | errorMessage = '上传失败:' + err.errMsg; |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | // 上传失败处理 |
| | | const handleUploadError = (message = '上传文件失败', showRetry = false) => { |
| | | const handleUploadError = (message = '上传文件失败') => { |
| | | uploading.value = false; |
| | | uploadProgress.value = 0; |
| | | |
| | | if (showRetry) { |
| | | uni.showModal({ |
| | | title: '上传失败', |
| | | content: message + ',是否重试?', |
| | | success: (res) => { |
| | | if (res.confirm) { |
| | | // 用户选择重试,这里可以重新触发上传 |
| | | } |
| | | } |
| | | }); |
| | | } else { |
| | | uni.showToast({ |
| | | title: message, |
| | | icon: 'error' |
| | | }); |
| | | } |
| | | |
| | | uni.showModal({ |
| | | title: '上传失败', |
| | | content: message, |
| | | showCancel: false, |
| | | confirmText: '知道了' |
| | | }); |
| | | } |
| | | |
| | | // 上传成功回调 |
| | |
| | | if (!uploadedFile) { |
| | | console.error('无法解析上传响应数据:', res); |
| | | number.value--; // 上传失败时减少计数 |
| | | handleUploadError('上传响应数据格式错误', false); |
| | | handleUploadError('上传响应数据格式错误'); |
| | | return; |
| | | } |
| | | |
| | |
| | | max-height: 60vh; |
| | | display: block; |
| | | } |
| | | |
| | | /* 搜索区域样式 */ |
| | | .search-section { |
| | | padding: 15px 20px; |
| | | background: #fff; |
| | | border-bottom: 1px solid #f0f0f0; |
| | | } |
| | | |
| | | :deep(.u-input) { |
| | | width: 100%; |
| | | } |
| | | |
| | | :deep(.u-input__content) { |
| | | border-radius: 8px; |
| | | } |
| | | |
| | | :deep(.u-input__content__field) { |
| | | font-size: 14px; |
| | | } |
| | | </style> |