From 2dd434830299e781cd942ef5e6e938160dd12704 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期二, 03 三月 2026 17:15:18 +0800
Subject: [PATCH] 原材料检验功能开发
---
src/pages/inspectionUpload/index.vue | 3732 ++++++++++++++++++++++++++++++----------------------------
1 files changed, 1,918 insertions(+), 1,814 deletions(-)
diff --git a/src/pages/inspectionUpload/index.vue b/src/pages/inspectionUpload/index.vue
index 94f4b29..dd076b0 100644
--- a/src/pages/inspectionUpload/index.vue
+++ b/src/pages/inspectionUpload/index.vue
@@ -1,20 +1,25 @@
<template>
<view class="inspection-upload-page">
<!-- 椤甸潰澶撮儴 -->
- <PageHeader title="宸℃涓婁紶" @back="goBack" />
-
+ <PageHeader title="璁惧宸℃"
+ @back="goBack" />
<!-- 鏁版嵁鍒楄〃 -->
<view class="table-section">
<!-- 鐢熶骇宸℃鍒楄〃 -->
<view class="task-list">
- <view v-for="(item, index) in taskTableData" :key="index" class="task-item">
+ <view v-for="(item, index) in taskTableData"
+ :key="index"
+ class="task-item">
<view class="task-header">
<view class="task-info">
<text class="task-name">{{ item.taskName }}</text>
<text class="task-location">{{ item.inspectionLocation }}</text>
</view>
<view class="task-actions">
- <u-button type="primary" size="small" @click.stop="startScanForTask(item)" :customStyle="{
+ <u-button type="primary"
+ size="small"
+ @click.stop="startScanForTask(item)"
+ :customStyle="{
borderRadius: '15px',
height: '30px',
fontSize: '12px',
@@ -22,7 +27,10 @@
}">
鎵爜涓婁紶
</u-button>
- <u-button type="success" size="small" @click.stop="viewAttachments(item)" :customStyle="{
+ <u-button type="success"
+ size="small"
+ @click.stop="viewAttachments(item)"
+ :customStyle="{
borderRadius: '15px',
height: '30px',
fontSize: '12px'
@@ -51,106 +59,146 @@
<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-else="" text="鏈贰妫�" size="small" type="warning" inverted></uni-tag>
+ <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-else=""
+ text="鏈贰妫�"
+ size="small"
+ type="warning"
+ inverted></uni-tag>
</view>
</view>
</view>
</view>
<uni-load-more :status="loadMoreStatus"></uni-load-more>
</view>
-
<!-- 绌虹姸鎬� -->
- <view v-if="taskTableData?.length === 0" class="no-data">
+ <view v-if="taskTableData?.length === 0"
+ class="no-data">
<text>鏆傛棤鏁版嵁</text>
</view>
-
</view>
-
<!-- 鍥剧墖涓婁紶寮圭獥 - 鍘熺敓瀹炵幇 -->
- <view v-if="showUploadDialog" class="custom-modal-overlay" @click="closeUploadDialog">
- <view class="custom-modal-container" @click.stop>
+ <view v-if="showUploadDialog"
+ class="custom-modal-overlay"
+ @click="closeUploadDialog">
+ <view class="custom-modal-container"
+ @click.stop>
<view class="upload-popup-content">
<view class="upload-popup-header">
<text class="upload-popup-title">涓婁紶宸℃璁板綍</text>
</view>
-
<view class="upload-popup-body">
<!-- 鍒嗙被鏍囩椤� -->
<view class="upload-tabs">
- <view class="tab-item" :class="{ active: currentUploadType === 'before' }"
- @click="switchUploadType('before')">
+ <view class="tab-item"
+ :class="{ active: currentUploadType === 'before' }"
+ @click="switchUploadType('before')">
鐢熶骇鍓�
</view>
- <view class="tab-item" :class="{ active: currentUploadType === 'after' }"
- @click="switchUploadType('after')">
+ <view class="tab-item"
+ :class="{ active: currentUploadType === 'after' }"
+ @click="switchUploadType('after')">
鐢熶骇涓�
</view>
- <view class="tab-item" :class="{ active: currentUploadType === 'issue' }"
- @click="switchUploadType('issue')">
+ <view class="tab-item"
+ :class="{ active: currentUploadType === 'issue' }"
+ @click="switchUploadType('issue')">
鐢熶骇鍚�
</view>
</view>
-
<!-- 寮傚父鐘舵�侀�夋嫨 -->
<view class="exception-section">
<text class="section-title">鏄惁瀛樺湪寮傚父锛�</text>
<view class="exception-options">
- <view class="exception-option" :class="{ active: hasException === false }"
- @click="setExceptionStatus(false)">
- <u-icon name="checkmark-circle" size="20" color="#52c41a"></u-icon>
+ <view class="exception-option"
+ :class="{ active: hasException === false }"
+ @click="setExceptionStatus(false)">
+ <u-icon name="checkmark-circle"
+ size="20"
+ color="#52c41a"></u-icon>
<text>姝e父</text>
</view>
- <view class="exception-option" :class="{ active: hasException === true }"
- @click="setExceptionStatus(true)">
- <u-icon name="close-circle" size="20" color="#ff4d4f"></u-icon>
+ <view class="exception-option"
+ :class="{ active: hasException === true }"
+ @click="setExceptionStatus(true)">
+ <u-icon name="close-circle"
+ size="20"
+ color="#ff4d4f"></u-icon>
<text>瀛樺湪寮傚父</text>
</view>
</view>
</view>
-
<!-- 褰撳墠鍒嗙被鐨勪笂浼犲尯鍩� -->
<view class="simple-upload-area">
<view class="upload-buttons">
- <u-button type="primary" @click="chooseMedia('image')" :loading="uploading"
- :disabled="getCurrentFiles().length >= uploadConfig.limit"
- :customStyle="{ marginRight: '10px', flex: 1 }">
- <u-icon name="camera" size="18" color="#fff" style="margin-right: 5px;"></u-icon>
+ <u-button type="primary"
+ @click="chooseMedia('image')"
+ :loading="uploading"
+ :disabled="getCurrentFiles().length >= uploadConfig.limit"
+ :customStyle="{ marginRight: '10px', flex: 1 }">
+ <u-icon name="camera"
+ size="18"
+ color="#fff"
+ style="margin-right: 5px;"></u-icon>
{{ uploading ? '涓婁紶涓�...' : '鎷嶇収' }}
</u-button>
- <u-button type="success" @click="chooseMedia('video')" :loading="uploading"
- :disabled="getCurrentFiles().length >= uploadConfig.limit" :customStyle="{ flex: 1 }">
- <uni-icons type="videocam" name="videocam" size="18" color="#fff"
- style="margin-right: 5px;"></uni-icons>
+ <u-button type="success"
+ @click="chooseMedia('video')"
+ :loading="uploading"
+ :disabled="getCurrentFiles().length >= uploadConfig.limit"
+ :customStyle="{ flex: 1 }">
+ <uni-icons type="videocam"
+ name="videocam"
+ size="18"
+ color="#fff"
+ style="margin-right: 5px;"></uni-icons>
{{ uploading ? '涓婁紶涓�...' : '鎷嶈棰�' }}
</u-button>
</view>
-
<!-- 涓婁紶杩涘害 -->
- <view v-if="uploading" class="upload-progress">
- <u-line-progress :percentage="uploadProgress" :showText="true" activeColor="#409eff"></u-line-progress>
+ <view v-if="uploading"
+ class="upload-progress">
+ <u-line-progress :percentage="uploadProgress"
+ :showText="true"
+ activeColor="#409eff"></u-line-progress>
</view>
-
<!-- 褰撳墠鍒嗙被鐨勬枃浠跺垪琛� -->
- <view v-if="getCurrentFiles().length > 0" class="file-list">
- <view v-for="(file, index) in getCurrentFiles()" :key="index" class="file-item">
+ <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.type === 'image' || (file.type !== 'video' && !file.type)"
- :src="file.url || file.tempFilePath || file.path || file.downloadUrl"
- class="file-preview" mode="aspectFill" />
- <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>
+ :src="file.url || file.tempFilePath || file.path || file.downloadUrl"
+ class="file-preview"
+ mode="aspectFill" />
+ <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>
</view>
-
<!-- 鍒犻櫎鎸夐挳 -->
- <view class="delete-btn" @click="removeFile(index)">
- <u-icon name="close" size="12" color="#fff"></u-icon>
+ <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' ? '鍥剧墖' : '瑙嗛')
}}</text>
@@ -158,11 +206,10 @@
</view>
</view>
</view>
-
- <view v-if="getCurrentFiles().length === 0" class="empty-state">
+ <view v-if="getCurrentFiles().length === 0"
+ class="empty-state">
<text>璇烽�夋嫨瑕佷笂浼犵殑{{ getUploadTypeText() }}鍥剧墖鎴栬棰�</text>
</view>
-
<!-- 缁熻淇℃伅 -->
<view class="upload-summary">
<text class="summary-text">
@@ -173,59 +220,77 @@
</view>
</view>
</view>
-
<view class="upload-popup-footer">
- <u-button @click="closeUploadDialog" :customStyle="{ marginRight: '10px' }">鍙栨秷</u-button>
- <u-button v-if="hasException === true" type="warning" @click="goToRepair"
- :customStyle="{ marginRight: '10px' }">
+ <u-button @click="closeUploadDialog"
+ :customStyle="{ marginRight: '10px' }">鍙栨秷</u-button>
+ <u-button v-if="hasException === true"
+ type="warning"
+ @click="goToRepair"
+ :customStyle="{ marginRight: '10px' }">
鏂板鎶ヤ慨
</u-button>
- <u-button type="primary" @click="submitUpload">鎻愪氦</u-button>
+ <u-button type="primary"
+ @click="submitUpload">鎻愪氦</u-button>
</view>
</view>
</view>
</view>
-
<!-- 鏌ョ湅闄勪欢寮圭獥 -->
- <view v-if="showAttachmentDialog" class="custom-modal-overlay" @click="closeAttachmentDialog">
- <view class="custom-modal-container" @click.stop>
+ <view v-if="showAttachmentDialog"
+ class="custom-modal-overlay"
+ @click="closeAttachmentDialog">
+ <view class="custom-modal-container"
+ @click.stop>
<view class="attachment-popup-content">
<view class="attachment-popup-header">
<text class="attachment-popup-title">鏌ョ湅闄勪欢 - {{ currentViewTask?.taskName }}</text>
- <view class="close-btn-attachment" @click="closeAttachmentDialog">
- <u-icon name="close" size="16" color="#666"></u-icon>
+ <view class="close-btn-attachment"
+ @click="closeAttachmentDialog">
+ <u-icon name="close"
+ size="16"
+ color="#666"></u-icon>
</view>
</view>
-
<view class="attachment-popup-body">
<!-- 鍒嗙被鏍囩椤� -->
<view class="attachment-tabs">
- <view class="tab-item" :class="{ active: currentViewType === 'before' }"
- @click="switchViewType('before')">
+ <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')">
+ <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')">
+ <view class="tab-item"
+ :class="{ active: currentViewType === 'issue' }"
+ @click="switchViewType('issue')">
鐢熶骇鍚� ({{ getAttachmentsByType(2).length }})
</view>
</view>
-
<!-- 褰撳墠鍒嗙被鐨勯檮浠跺垪琛� -->
<view class="attachment-content">
- <view v-if="getCurrentViewAttachments().length > 0" class="attachment-list">
- <view v-for="(file, index) in getCurrentViewAttachments()" :key="index" class="attachment-item"
- @click="previewAttachment(file)">
+ <view v-if="getCurrentViewAttachments().length > 0"
+ class="attachment-list">
+ <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"
- class="attachment-preview" mode="aspectFill" />
- <view v-else class="attachment-video-preview">
- <u-icon name="video" size="24" color="#409eff"></u-icon>
+ <image v-if="file.type === 'image' || isImageFile(file)"
+ :src="file.url || file.downloadUrl"
+ class="attachment-preview"
+ mode="aspectFill" />
+ <view v-else
+ class="attachment-video-preview">
+ <u-icon name="video"
+ size="24"
+ color="#409eff"></u-icon>
<text class="video-text">瑙嗛</text>
</view>
</view>
-
<view class="attachment-info">
<text class="attachment-name">{{ file.originalFilename || file.bucketFilename || file.name || '闄勪欢'
}}</text>
@@ -233,8 +298,8 @@
</view>
</view>
</view>
-
- <view v-else class="attachment-empty">
+ <view v-else
+ class="attachment-empty">
<text>璇ュ垎绫绘殏鏃犻檮浠�</text>
</view>
</view>
@@ -242,19 +307,28 @@
</view>
</view>
</view>
-
<!-- 瑙嗛棰勮寮圭獥 -->
- <view v-if="showVideoDialog" class="video-modal-overlay" @click="closeVideoPreview">
- <view class="video-modal-container" @click.stop>
+ <view v-if="showVideoDialog"
+ class="video-modal-overlay"
+ @click="closeVideoPreview">
+ <view class="video-modal-container"
+ @click.stop>
<view class="video-modal-header">
<text class="video-modal-title">{{ currentVideoFile?.originalFilename || '瑙嗛棰勮' }}</text>
- <view class="close-btn-video" @click="closeVideoPreview">
- <u-icon name="close" size="16" color="#fff"></u-icon>
+ <view class="close-btn-video"
+ @click="closeVideoPreview">
+ <u-icon name="close"
+ size="16"
+ color="#fff"></u-icon>
</view>
</view>
<view class="video-modal-body">
- <video v-if="currentVideoFile" :src="currentVideoFile.url || currentVideoFile.downloadUrl"
- class="video-player" controls autoplay @error="handleVideoError"></video>
+ <video v-if="currentVideoFile"
+ :src="currentVideoFile.url || currentVideoFile.downloadUrl"
+ class="video-player"
+ controls
+ autoplay
+ @error="handleVideoError"></video>
</view>
</view>
</view>
@@ -262,1826 +336,1856 @@
</template>
<script setup>
-import { onMounted, onUnmounted, ref, nextTick, computed, reactive } from 'vue'
-import { onShow, onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app'
-import PageHeader from '@/components/PageHeader.vue'
-import { getLedgerById } from '@/api/equipmentManagement/ledger.js'
-import { inspectionTaskList, uploadInspectionTask } from "@/api/inspectionManagement";
-import { getToken } from "@/utils/auth";
-import config from '@/config'
+ import { onMounted, onUnmounted, ref, nextTick, computed, reactive } from "vue";
+ import { onShow, onReachBottom, onPullDownRefresh } from "@dcloudio/uni-app";
+ import PageHeader from "@/components/PageHeader.vue";
+ import { getLedgerById } from "@/api/equipmentManagement/ledger.js";
+ import {
+ inspectionTaskList,
+ uploadInspectionTask,
+ } from "@/api/inspectionManagement";
+ import { getToken } from "@/utils/auth";
+ import config from "@/config";
-// 缁勪欢寮曠敤宸茬Щ闄�
+ // 缁勪欢寮曠敤宸茬Щ闄�
-// 鍔犺浇鎻愮ず鏂规硶
-const showLoadingToast = (message) => {
- uni.showLoading({
- title: message,
- mask: true
- })
-}
-const closeToast = () => {
- uni.hideLoading()
-}
-
-// 琛ㄦ牸鏁版嵁
-const taskTableData = ref([]) // 鐢熶骇宸℃鏁版嵁
-
-// 褰撳墠鎵弿鐨勪换鍔�
-const currentScanningTask = ref(null)
-const infoData = ref(null);
-
-// 涓婁紶鐩稿叧鐘舵��
-const showUploadDialog = ref(false)
-const uploadFiles = ref([]) // 淇濈暀鐢ㄤ簬鍏煎鎬�
-const uploadStatusType = ref(0)
-const uploading = ref(false)
-const uploadProgress = ref(0)
-const number = ref(0)
-const uploadList = ref([])
-
-// 涓変釜鍒嗙被鐨勪笂浼犵姸鎬�
-const beforeModelValue = ref([]) // 鐢熶骇鍓�
-const afterModelValue = ref([]) // 鐢熶骇涓�
-const issueModelValue = ref([]) // 鐢熶骇鍚�
-
-// 褰撳墠婵�娲荤殑涓婁紶绫诲瀷
-const currentUploadType = ref('before') // 'before', 'after', 'issue'
-
-// 鏌ョ湅闄勪欢鐩稿叧鐘舵��
-const showAttachmentDialog = ref(false)
-const currentViewTask = ref(null)
-const currentViewType = ref('before') // 'before', 'after', 'issue'
-const attachmentList = ref([]) // 褰撳墠鏌ョ湅浠诲姟鐨勯檮浠跺垪琛�
-
-// 瑙嗛棰勮鐩稿叧鐘舵��
-const showVideoDialog = ref(false)
-const currentVideoFile = ref(null)
-
-// 寮傚父鐘舵��
-const hasException = ref(null) // null: 鏈�夋嫨, true: 瀛樺湪寮傚父, false: 姝e父
-
-// 涓婁紶閰嶇疆
-const uploadConfig = {
- action: "/file/upload",
- limit: 10,
- fileSize: 50, // MB
- fileType: ['jpg', 'jpeg', 'png', 'mp4', 'mov'],
- maxVideoDuration: 60 // 绉�
-}
-
-// 璁$畻涓婁紶URL
-const uploadFileUrl = computed(() => {
- const baseUrl = 'http://114.132.189.42:9030';
-
- return baseUrl + uploadConfig.action;
-})
-
-// 璁$畻璇锋眰澶�
-const headers = computed(() => {
- const token = getToken();
- return token ? { Authorization: "Bearer " + token } : {};
-})
-
-// 璇锋眰鍙栨秷鏍囧織锛岀敤浜庡彇娑堟鍦ㄨ繘琛岀殑璇锋眰
-let isRequestCancelled = false
-
-const pagesPames = reactive({
- size: 10,
- current:1
-})
-
-const loadMoreStatus = computed(()=>{
- if(loading.value){
- return 'loading'
- }
- if(noMore.value){
- return 'noMore'
- }
- return 'more'
-})
-const totalSize = ref(0)
-const noMore = computed(()=>{
- return taskTableData.value.length>=totalSize.value
-})
-const loading = ref(false)
-
-const reloadPage = ()=>{
- pagesPames.current = 1
- taskTableData.value = []
- getList()
-}
-const loadPage = ()=>{
- if(noMore.value||loading.value)return;
- pagesPames.current += 1
- getList()
-}
-
-// 鐢熷懡鍛ㄦ湡
-onMounted(() => {
- // 寤惰繜鍒濆鍖栵紝纭繚DOM宸叉覆鏌�
- // nextTick(() => {
- // getList()
- // })
-})
-
-onReachBottom(() => {
- loadPage()
-})
-onPullDownRefresh(() => {
- reloadPage()
- uni.stopPullDownRefresh()
-})
-
-onShow(() => {
- // 椤甸潰鏄剧ず鏃跺埛鏂版暟鎹�
- reloadPage()
-})
-
-// 缁勪欢閿�姣佹椂鐨勬竻鐞�
-onUnmounted(() => {
- // 璁剧疆鍙栨秷鏍囧織锛岄樆姝㈠悗缁殑寮傛鎿嶄綔
- isRequestCancelled = true
-
- // 鍏抽棴涓婁紶寮圭獥
- if (showUploadDialog.value) {
- showUploadDialog.value = false
- }
-})
-
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
- uni.navigateBack()
-}
-
-
-// 鑾峰彇鍒楄〃鏁版嵁
-const getList = () => {
- // 鏄剧ず鍔犺浇鎻愮ず
- // showLoadingToast('鍔犺浇涓�...')
-
- // 璁剧疆鍙栨秷鏍囧織
- isRequestCancelled = false
- loading.value = true
- inspectionTaskList({...pagesPames}).then(res => {
- // 妫�鏌ョ粍浠舵槸鍚﹁繕瀛樺湪涓旇姹傛湭琚彇娑�
- if (!isRequestCancelled) {
- // 澶勭悊涓嶅悓鐨勬暟鎹粨鏋�
- let records = [];
- if (res && res.data) {
- // 灏濊瘯澶氱鍙兘鐨勬暟鎹粨鏋�
- totalSize.value = res.data.total
- if (Array.isArray(res.data.records)) {
- records = res.data.records;
- } else if (Array.isArray(res.data.rows)) {
- records = res.data.rows;
- } else if (Array.isArray(res.data)) {
- records = res.data;
- } else if (Array.isArray(res.data.list)) {
- records = res.data.list;
- }
- }
-
- if (records.length > 0) {
- taskTableData.value = [...taskTableData.value,...records.map((record)=>{
- record.fileStatus = getFileStatus(record)
- return record
- })];
- } else {
- taskTableData.value = [];
- uni.showToast({
- title: '鏆傛棤宸℃浠诲姟鏁版嵁',
- icon: 'none'
- });
- }
- }
- loading.value =false
- // 鍏抽棴鍔犺浇鎻愮ず
- // closeToast()
- }).catch(err => {
- // 妫�鏌ョ粍浠舵槸鍚﹁繕瀛樺湪涓旇姹傛湭琚彇娑�
- if (!isRequestCancelled) {
- taskTableData.value = [];
- // 娣诲姞閿欒鎻愮ず
- uni.showToast({
- title: '鑾峰彇鏁版嵁澶辫触',
- icon: 'error'
- })
- }
- loading.value =false
- // 鍏抽棴鍔犺浇鎻愮ず
- // closeToast()
- })
-}
-
-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){
- return 2
- }else if(_beforeProduction||_afterProduction||_productionIssues){
- return 1
- }else{
- return 0
- }
-}
-
-// 涓烘寚瀹氫换鍔″紑濮嬫壂鐮侊紙鐪熸満锛�
-const startScanForTask = async (task) => {
- try {
- currentScanningTask.value = task
- uni.scanCode({
- success: (res) => {
- handleScanSuccess(res)
- },
- fail: (err) => {
- console.error('鎵爜澶辫触:', err)
- uni.showToast({
- title: '鎵爜澶辫触',
- icon: 'error'
- })
- }
- })
- } catch (e) {
- console.error('鍚姩鎵爜澶辫触:', e)
- uni.showToast({
- title: '鍚姩鎵爜澶辫触',
- icon: 'error'
- })
- }
-}
-
-// 鎵爜鎴愬姛澶勭悊锛氭牎楠屽悗鎵撳紑涓婁紶寮圭獥
-const handleScanSuccess = (result) => {
- try {
- // 瑙f瀽浜岀淮鐮佹暟鎹紝鎻愬彇deviceId
- let deviceId = ''
-
- if (result?.result && typeof result.result === 'string') {
- if (result.result.includes('deviceId=')) {
- const match = result.result.match(/deviceId=(\d+)/)
- if (match && match[1]) deviceId = match[1]
- } else {
- try {
- const qrData = JSON.parse(result.result)
- deviceId = qrData.deviceId || qrData.qrCodeId || ''
- } catch (e) {
- deviceId = result.result
- }
- }
- }
-
- if (!deviceId) {
- uni.showToast({ title: '鏈瘑鍒埌璁惧ID', icon: 'error' })
- return
- }
-
- const currentTaskId = currentScanningTask.value?.taskId || currentScanningTask.value?.id
- if (!currentTaskId) {
- uni.showToast({ title: '浠诲姟淇℃伅缂哄け', icon: 'error' })
- return
- }
-
- if (deviceId === currentTaskId.toString()) {
- uni.showToast({ title: '璇嗗埆鎴愬姛', icon: 'success' })
- openUploadDialog(currentScanningTask.value)
- } else {
- uni.showToast({ title: '璇锋壂鎻忔纭殑璁惧', icon: 'error' })
- }
- } catch (error) {
- console.error('鎵爜缁撴灉澶勭悊澶辫触:', error)
- uni.showToast({
- title: error?.message || '鏁版嵁瑙f瀽澶辫触',
- icon: 'error'
- })
- }
-}
-
-
-// 鎵撳紑涓婁紶寮圭獥
-const openUploadDialog = (task) => {
- // 璁剧疆浠诲姟淇℃伅鍒癷nfoData
- if (task) {
- infoData.value = {
- ...task,
- taskId: task.taskId || task.id,
- storageBlobDTO: [] // 鍒濆鍖栨枃浠跺垪琛�
- };
- }
-
- // 璁剧疆涓婁紶鐘舵�佺被鍨嬶紙鍙互鏍规嵁浠诲姟绫诲瀷璁剧疆涓嶅悓鐨勭姸鎬侊級
- uploadStatusType.value = 0 // 榛樿鐘舵��
-
- // 娓呯┖涔嬪墠鐨勬枃浠�
- uploadFiles.value = []
-
- // 鏄剧ず涓婁紶寮圭獥
- showUploadDialog.value = true
-}
-
-// 鍏抽棴涓婁紶寮圭獥
-const closeUploadDialog = () => {
- showUploadDialog.value = false
- uploadFiles.value = []
- // 娓呯悊涓変釜鍒嗙被鐨勬暟鎹�
- beforeModelValue.value = []
- afterModelValue.value = []
- issueModelValue.value = []
- currentUploadType.value = 'before'
- hasException.value = null // 閲嶇疆寮傚父鐘舵��
- infoData.value = null // 娓呯悊浠诲姟鏁版嵁
-}
-
-// 鍒囨崲涓婁紶绫诲瀷
-const switchUploadType = (type) => {
- currentUploadType.value = type
-}
-
-// 鑾峰彇褰撳墠鍒嗙被鐨勬枃浠跺垪琛�
-const getCurrentFiles = () => {
- switch (currentUploadType.value) {
- case 'before':
- return beforeModelValue.value||[]
- case 'after':
- return afterModelValue.value||[]
- case 'issue':
- return issueModelValue.value||[]
- default:
- return []
- }
-}
-
-// 鑾峰彇涓婁紶绫诲瀷鏂囨湰
-const getUploadTypeText = () => {
- switch (currentUploadType.value) {
- case 'before':
- return '鐢熶骇鍓�'
- case 'after':
- return '鐢熶骇涓�'
- case 'issue':
- return '鐢熶骇鍚�'
- default:
- return ''
- }
-}
-
-// 澶勭悊涓婁紶鏂囦欢鏇存柊
-const handleUploadUpdate = (files) => {
- uploadFiles.value = files
-}
-
-// 璁剧疆寮傚父鐘舵��
-const setExceptionStatus = (status) => {
- hasException.value = status
-}
-
-// 璺宠浆鍒版柊澧炴姤淇〉闈�
-const goToRepair = () => {
- try {
- // 瀛樺偍褰撳墠浠诲姟淇℃伅鍒版湰鍦板瓨鍌紝渚涙姤淇〉闈娇鐢�
- const taskInfo = {
- taskId: infoData.value?.taskId || infoData.value?.id,
- taskName: infoData.value?.taskName,
- inspectionLocation: infoData.value?.inspectionLocation,
- inspector: infoData.value?.inspector,
- // 浼犻�掑綋鍓嶄笂浼犵殑鏂囦欢淇℃伅
- uploadedFiles: {
- before: beforeModelValue.value,
- after: afterModelValue.value,
- issue: issueModelValue.value
- }
- }
-
- uni.setStorageSync('repairTaskInfo', JSON.stringify(taskInfo))
-
- // 璺宠浆鍒版柊澧炴姤淇〉闈�
- uni.navigateTo({
- url: '/pages/equipmentManagement/repair/add'
- })
-
- // 鍏抽棴涓婁紶寮圭獥
- closeUploadDialog()
-
- } catch (error) {
- console.error('璺宠浆鎶ヤ慨椤甸潰澶辫触:', error)
- uni.showToast({
- title: '璺宠浆澶辫触锛岃閲嶈瘯',
- icon: 'error'
- })
- }
-}
-
-// 鎻愪氦涓婁紶
-const submitUpload = async () => {
- try {
- // 妫�鏌ユ槸鍚﹂�夋嫨浜嗗紓甯哥姸鎬�
- if (hasException.value === null) {
- uni.showToast({
- title: '璇烽�夋嫨鏄惁瀛樺湪寮傚父',
- icon: 'none'
- })
- return
- }
-
- // 妫�鏌ユ槸鍚︽湁浠讳綍鏂囦欢涓婁紶
- const totalFiles = beforeModelValue.value.length + afterModelValue.value.length + issueModelValue.value.length;
- if (totalFiles === 0) {
- uni.showToast({
- title: '璇峰厛涓婁紶鏂囦欢',
- icon: 'none'
- })
- return
- }
-
- // 鏄剧ず鎻愪氦涓殑鍔犺浇鎻愮ず
- showLoadingToast('鎻愪氦涓�...')
-
- // 鎸夌収鎮ㄧ殑閫昏緫鍚堝苟鎵�鏈夊垎绫荤殑鏂囦欢
- let arr = [];
- if (beforeModelValue.value.length > 0) {
- arr.push(...beforeModelValue.value);
- }
- if (afterModelValue.value.length > 0) {
- arr.push(...afterModelValue.value);
- }
- if (issueModelValue.value.length > 0) {
- arr.push(...issueModelValue.value);
- }
-
- // 浼犵粰鍚庣鐨勪复鏃舵枃浠禝D鍒楄〃锛坱empFileIds锛�
- // 鍏煎锛氭湁浜涙帴鍙e彲鑳借繑鍥� 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 });
-
- // 妫�鏌ユ彁浜ょ粨鏋�
- if (result && (result.code === 200 || result.success)) {
- // 鎻愪氦鎴愬姛
- closeToast(); // 鍏抽棴鍔犺浇鎻愮ず
-
- uni.showToast({
- title: '鎻愪氦鎴愬姛',
- icon: 'success'
- })
-
- // 鍏抽棴寮圭獥
- closeUploadDialog()
-
- // 鍒锋柊鍒楄〃
- setTimeout(() => {
- reloadPage()
- }, 500)
-
- } else {
- // 鎻愪氦澶辫触
- closeToast();
- uni.showToast({
- title: result?.msg || result?.message || '鎻愪氦澶辫触',
- icon: 'error'
- })
- }
-
- } catch (error) {
- console.error('鎻愪氦涓婁紶澶辫触:', error)
- closeToast(); // 鍏抽棴鍔犺浇鎻愮ず
-
- let errorMessage = '鎻愪氦澶辫触';
- if (error.message) {
- errorMessage = error.message;
- } else if (error.msg) {
- errorMessage = error.msg;
- } else if (typeof error === 'string') {
- errorMessage = error;
- }
-
- uni.showToast({
- title: errorMessage,
- icon: 'error'
- })
- }
-}
-
-// 鏌ョ湅闄勪欢
-const viewAttachments = async (task) => {
- try {
- currentViewTask.value = task
- currentViewType.value = 'before'
-
- // 瑙f瀽鏂扮殑鏁版嵁缁撴瀯
- attachmentList.value = []
-
- // 鍚庣鍙嶆樉瀛楁锛堜綘鎻愪緵鐨勬暟鎹粨鏋勶級锛�
- // - 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,
- // 鐢ㄤ簬涓夋爣绛鹃〉鍒嗙粍锛�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,
- }
- }
-
- 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
-
- } catch (error) {
- uni.showToast({
- title: '鑾峰彇闄勪欢澶辫触',
- icon: 'error'
- })
- }
-}
-
-// 鍏抽棴闄勪欢鏌ョ湅寮圭獥
-const closeAttachmentDialog = () => {
- showAttachmentDialog.value = false
- currentViewTask.value = null
- attachmentList.value = []
- currentViewType.value = 'before'
-}
-
-// 鍒囨崲鏌ョ湅绫诲瀷
-const switchViewType = (type) => {
- currentViewType.value = type
-}
-
-// 鏍规嵁type鑾峰彇瀵瑰簲鍒嗙被鐨勯檮浠�
-const getAttachmentsByType = (typeValue) => {
- return attachmentList.value.filter(file => file.type === typeValue) || []
-}
-// 鑾峰彇type鍊�
-const getTabType = () => {
- switch (currentUploadType.value) {
- case 'before':
- return 10
- case 'after':
- return 11
- case 'issue':
- return 12
- default:
- return 10
- }
-}
-// 鑾峰彇褰撳墠鏌ョ湅绫诲瀷鐨勯檮浠�
-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) => {
- // 妫�鏌ontentType瀛楁
- if (file.contentType && file.contentType.startsWith('image/')) {
- return true
- }
-
- // 妫�鏌ュ師鏈夌殑type瀛楁
- if (file.type === 'image') return true
-
- // 妫�鏌ユ枃浠舵墿灞曞悕
- 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 || ''
- }
-}
-
-// 棰勮闄勪欢
-const previewAttachment = (file) => {
- if (isImageFile(file)) {
- // 棰勮鍥剧墖
- const imageUrls = getCurrentViewAttachments()
- .filter(f => isImageFile(f))
- .map(f => f.url || f.downloadUrl)
-
- uni.previewImage({
- urls: imageUrls,
- current: file.url || file.downloadUrl
- })
- } else {
- // 棰勮瑙嗛 - 鏄剧ず瑙嗛鎾斁寮圭獥
- showVideoPreview(file)
- }
-}
-
-// 鏄剧ず瑙嗛棰勮
-const showVideoPreview = (file) => {
- currentVideoFile.value = file
- showVideoDialog.value = true
-}
-
-// 鍏抽棴瑙嗛棰勮
-const closeVideoPreview = () => {
- showVideoDialog.value = false
- currentVideoFile.value = null
-}
-
-// 瑙嗛鎾斁閿欒澶勭悊
-const handleVideoError = (error) => {
- uni.showToast({
- title: '瑙嗛鎾斁澶辫触',
- icon: 'error'
- })
-}
-
-// 鎷嶇収/鎷嶈棰戯紙鐪熸満浼樺厛鐢� chooseMedia锛涗笉鏀寔鍒欓檷绾э級
-const chooseMedia = (type) => {
- if (getCurrentFiles().length >= uploadConfig.limit) {
- uni.showToast({ title: `鏈�澶氬彧鑳介�夋嫨${uploadConfig.limit}涓枃浠禶, icon: 'none' })
- return
- }
-
- const remaining = uploadConfig.limit - getCurrentFiles().length
-
- // 浼樺厛锛歝hooseMedia锛堟敮鎸� image/video锛�
- if (typeof uni.chooseMedia === 'function') {
- uni.chooseMedia({
- count: Math.min(remaining, 1),
- mediaType: [type || 'image'],
- sizeType: ['compressed', 'original'],
- sourceType: ['camera'],
- success: (res) => {
- try {
- const files = res?.tempFiles || []
- if (!files.length) throw new Error('鏈幏鍙栧埌鏂囦欢')
-
- 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: 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: '鎷嶆憚澶辫触', icon: 'error' })
- }
- })
- return
- }
-
- // 闄嶇骇锛歝hooseImage / 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 chooseImage = () => {
- if (uploadFiles.value.length >= uploadConfig.limit) {
- uni.showToast({
- title: `鏈�澶氬彧鑳芥媿鎽�${uploadConfig.limit}涓枃浠禶,
- icon: 'none'
- });
- return;
- }
-
- uni.chooseMedia({
- count: 1,
- mediaType: ['image', 'video'],
- sizeType: ['compressed', 'original'],
- sourceType: ['camera'],
- success: (res) => {
- try {
- if (!res.tempFiles || res.tempFiles.length === 0) {
- throw new Error('鏈幏鍙栧埌鍥剧墖鏂囦欢');
- }
-
- const tempFilePath = res.tempFiles[0];
- const tempFile = res.tempFiles && res.tempFiles[0] ? res.tempFiles[0] : {};
-
- 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'
- });
- }
- },
- fail: (err) => {
- console.error('鎷嶇収澶辫触:', err);
- uni.showToast({
- title: '鎷嶇収澶辫触: ' + (err.errMsg || '鏈煡閿欒'),
- icon: 'error'
- });
- }
- });
-}
-
-// 鎷嶈棰�
-const chooseVideo = () => {
- if (uploadFiles.value.length >= uploadConfig.limit) {
- uni.showToast({
- title: `鏈�澶氬彧鑳芥媿鎽�${uploadConfig.limit}涓枃浠禶,
- icon: 'none'
- });
- return;
- }
-
- uni.chooseVideo({
- sourceType: ['camera'],
- maxDuration: uploadConfig.maxVideoDuration,
- camera: 'back',
- success: (res) => {
- try {
- if (!res.tempFilePath) {
- throw new Error('鏈幏鍙栧埌瑙嗛鏂囦欢');
- }
-
- const file = {
- tempFilePath: res.tempFilePath,
- path: res.tempFilePath, // 淇濇寔鍏煎鎬�
- type: 'video',
- name: `video_${Date.now()}.mp4`,
- size: res.size || 0,
- duration: res.duration || 0,
- createTime: new Date().getTime(),
- uid: Date.now() + Math.random()
- };
-
- handleBeforeUpload(file);
- } catch (error) {
- console.error('澶勭悊鎷嶈棰戠粨鏋滃け璐�:', error);
- uni.showToast({
- title: '澶勭悊瑙嗛澶辫触',
- icon: 'error'
- });
- }
- },
- fail: (err) => {
- console.error('鎷嶈棰戝け璐�:', err);
- uni.showToast({
- title: '鎷嶈棰戝け璐�: ' + (err.errMsg || '鏈煡閿欒'),
- icon: 'error'
- });
- }
- });
-}
-
-// 鍒犻櫎鏂囦欢
-const removeFile = (index) => {
- uni.showModal({
- title: '纭鍒犻櫎',
- content: '纭畾瑕佸垹闄よ繖涓枃浠跺悧锛�',
- success: (res) => {
- if (res.confirm) {
- // 鏍规嵁褰撳墠涓婁紶绫诲瀷鍒犻櫎瀵瑰簲鍒嗙被鐨勬枃浠�
- switch (currentUploadType.value) {
- case 'before':
- beforeModelValue.value.splice(index, 1);
- break;
- case 'after':
- afterModelValue.value.splice(index, 1);
- break;
- case 'issue':
- issueModelValue.value.splice(index, 1);
- break;
- }
- uni.showToast({
- title: '鍒犻櫎鎴愬姛',
- icon: 'success'
- });
- }
- }
- });
-}
-
-// 妫�鏌ョ綉缁滆繛鎺�
-const checkNetworkConnection = () => {
- return new Promise((resolve) => {
- uni.getNetworkType({
- success: (res) => {
- if (res.networkType === 'none') {
- resolve(false);
- } else {
- resolve(true);
- }
- },
- fail: () => {
- resolve(false);
- }
- });
- });
-}
-
-// 涓婁紶鍓嶆牎楠�
-const handleBeforeUpload = async (file) => {
-
- // 鏍¢獙鏂囦欢绫诲瀷
- if (uploadConfig.fileType && Array.isArray(uploadConfig.fileType) && uploadConfig.fileType.length > 0) {
- const fileName = file.name || '';
- const fileExtension = fileName ? fileName.split('.').pop().toLowerCase() : '';
-
- // 鏍规嵁鏂囦欢绫诲瀷纭畾鏈熸湜鐨勬墿灞曞悕
- let expectedTypes = [];
- if (file.type === 'image') {
- expectedTypes = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
- } else if (file.type === 'video') {
- expectedTypes = ['mp4', 'mov', 'avi', 'wmv'];
- }
-
- // 妫�鏌ユ枃浠舵墿灞曞悕鏄惁鍦ㄥ厑璁哥殑绫诲瀷涓�
- if (fileExtension && expectedTypes.length > 0) {
- const isAllowed = expectedTypes.some(type =>
- uploadConfig.fileType.includes(type) && type === fileExtension
- );
-
- if (!isAllowed) {
- uni.showToast({
- title: `鏂囦欢鏍煎紡涓嶆敮鎸侊紝璇锋媿鎽� ${expectedTypes.join('/')} 鏍煎紡鐨勬枃浠禶,
- icon: 'none'
- });
- return false;
- }
- }
- }
-
- // 鏍¢獙閫氳繃锛屽紑濮嬩笂浼�
- uploadFile(file);
- return true;
-}
-
-// 鏂囦欢涓婁紶澶勭悊锛堢湡鏈鸿蛋 uni.uploadFile锛�
-const uploadFile = async (file) => {
- uploading.value = true;
- uploadProgress.value = 0;
- number.value++; // 澧炲姞涓婁紶璁℃暟
-
- // 纭繚token瀛樺湪
- const token = getToken();
- if (!token) {
- handleUploadError('鐢ㄦ埛鏈櫥褰�');
- return;
- }
-
- const typeValue = getTabType(); // 鐢熶骇鍓�:10, 鐢熶骇涓�:11, 鐢熶骇鍚�:12
-
- uploadWithUniUploadFile(file, file.tempFilePath || file.path || '', typeValue, token);
-}
-
-// 浣跨敤uni.uploadFile涓婁紶锛堥潪H5鐜鎴朒5鍥為��鏂规锛�
-const uploadWithUniUploadFile = (file, filePath, typeValue, token) => {
- if (!filePath) {
- handleUploadError('鏂囦欢璺緞涓嶅瓨鍦�');
- return;
- }
-
- const uploadTask = uni.uploadFile({
- url: uploadFileUrl.value,
- filePath: filePath,
- name: 'file',
- formData: {
- type: typeValue
- },
- header: {
- 'Authorization': `Bearer ${token}`
- },
- success: (res) => {
- try {
- if (res.statusCode === 200) {
- const response = JSON.parse(res.data);
- if (response.code === 200) {
- handleUploadSuccess(response, file);
- uni.showToast({
- title: '涓婁紶鎴愬姛',
- icon: 'success'
- });
- } else {
- handleUploadError(response.msg || '鏈嶅姟鍣ㄨ繑鍥為敊璇�');
- }
- } else {
- handleUploadError(`鏈嶅姟鍣ㄩ敊璇紝鐘舵�佺爜: ${res.statusCode}`);
- }
- } catch (e) {
- console.error('瑙f瀽鍝嶅簲澶辫触:', e);
- console.error('鍘熷鍝嶅簲鏁版嵁:', res.data);
- handleUploadError('鍝嶅簲鏁版嵁瑙f瀽澶辫触: ' + e.message);
- }
- },
- fail: (err) => {
- console.error('涓婁紶澶辫触:', err.errMsg || err);
- number.value--; // 涓婁紶澶辫触鏃跺噺灏戣鏁�
-
- let errorMessage = '涓婁紶澶辫触';
- if (err.errMsg) {
- if (err.errMsg.includes('statusCode: null')) {
- errorMessage = '缃戠粶杩炴帴澶辫触锛岃妫�鏌ョ綉缁滆缃�';
- } else if (err.errMsg.includes('timeout')) {
- errorMessage = '涓婁紶瓒呮椂锛岃閲嶈瘯';
- } else if (err.errMsg.includes('fail')) {
- errorMessage = '涓婁紶澶辫触锛岃妫�鏌ョ綉缁滆繛鎺�';
- } else {
- errorMessage = err.errMsg;
- }
- }
-
- handleUploadError(errorMessage);
- },
- complete: () => {
- uploading.value = false;
- uploadProgress.value = 0;
- }
- });
-
- // 鐩戝惉涓婁紶杩涘害
- if (uploadTask && uploadTask.onProgressUpdate) {
- uploadTask.onProgressUpdate((res) => {
- uploadProgress.value = res.progress;
- });
- }
-}
-
-// 涓婁紶澶辫触澶勭悊
-const handleUploadError = (message = '涓婁紶鏂囦欢澶辫触', showRetry = false) => {
- uploading.value = false;
- uploadProgress.value = 0;
-
- if (showRetry) {
- uni.showModal({
- title: '涓婁紶澶辫触',
- content: message + '锛屾槸鍚﹂噸璇曪紵',
- success: (res) => {
- if (res.confirm) {
- // 鐢ㄦ埛閫夋嫨閲嶈瘯锛岃繖閲屽彲浠ラ噸鏂拌Е鍙戜笂浼�
- }
- }
- });
- } else {
- uni.showToast({
+ // 鍔犺浇鎻愮ず鏂规硶
+ const showLoadingToast = message => {
+ uni.showLoading({
title: message,
- icon: 'error'
+ mask: true,
});
- }
-}
-
-// 涓婁紶鎴愬姛鍥炶皟
-const handleUploadSuccess = (res, file) => {
- console.log('涓婁紶鎴愬姛鍝嶅簲:', res);
-
- // 澶勭悊涓嶅悓鐨勬暟鎹粨鏋勶細鍙兘鏄暟缁勶紝涔熷彲鑳芥槸鍗曚釜瀵硅薄
- let uploadedFile = null;
- uploadedFile = res.data;
-
- if (!uploadedFile) {
- console.error('鏃犳硶瑙f瀽涓婁紶鍝嶅簲鏁版嵁:', res);
- number.value--; // 涓婁紶澶辫触鏃跺噺灏戣鏁�
- handleUploadError('涓婁紶鍝嶅簲鏁版嵁鏍煎紡閿欒', false);
- return;
- }
-
- // 鏍规嵁褰撳墠涓婁紶绫诲瀷璁剧疆type瀛楁
- let typeValue = 0; // 榛樿涓虹敓浜у墠
- switch (currentUploadType.value) {
- case 'before':
- typeValue = 0;
- break;
- case 'after':
- typeValue = 1;
- break;
- case 'issue':
- typeValue = 2;
- break;
- }
-
- // 纭繚涓婁紶鐨勬枃浠舵暟鎹畬鏁达紝鍖呭惈id鍜宼ype
- const fileData = {
- ...file,
- id: uploadedFile.id, // 娣诲姞鏈嶅姟鍣ㄨ繑鍥炵殑id
- 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 || uploadedFile.byteSize || file.size,
- createTime: uploadedFile.createTime || new Date().getTime(),
- type: typeValue // 娣诲姞绫诲瀷瀛楁锛�0=鐢熶骇鍓�, 1=鐢熶骇涓�, 2=鐢熶骇鍚�
+ };
+ const closeToast = () => {
+ uni.hideLoading();
};
- uploadList.value.push(fileData);
-
- // 绔嬪嵆娣诲姞鍒板搴旂殑鍒嗙被锛屼笉绛夊緟鎵�鏈夋枃浠朵笂浼犲畬鎴�
- switch (currentUploadType.value) {
- case 'before':
- beforeModelValue.value.push(fileData);
- break;
- case 'after':
- afterModelValue.value.push(fileData);
- break;
- case 'issue':
- issueModelValue.value.push(fileData);
- break;
- }
-
- // 閲嶇疆涓婁紶鍒楄〃锛堝洜涓哄凡缁忔坊鍔犲埌瀵瑰簲鍒嗙被浜嗭級
- uploadList.value = [];
- number.value = 0;
-}
+ // 琛ㄦ牸鏁版嵁
+ const taskTableData = ref([]); // 鐢熶骇宸℃鏁版嵁
-// 涓婁紶缁撴潫澶勭悊锛堝凡搴熷純锛岀幇鍦ㄥ湪handleUploadSuccess涓洿鎺ュ鐞嗭級
-const uploadedSuccessfully = () => {
- // 姝ゅ嚱鏁板凡涓嶅啀浣跨敤锛屾枃浠朵笂浼犳垚鍔熷悗绔嬪嵆娣诲姞鍒板搴斿垎绫�
-}
+ // 褰撳墠鎵弿鐨勪换鍔�
+ const currentScanningTask = ref(null);
+ const infoData = ref(null);
-// 鏍煎紡鍖栨枃浠跺ぇ灏�
-const formatFileSize = (size) => {
- if (!size) return '';
- if (size < 1024) return size + 'B';
- if (size < 1024 * 1024) return (size / 1024).toFixed(1) + 'KB';
- return (size / (1024 * 1024)).toFixed(1) + 'MB';
-}
+ // 涓婁紶鐩稿叧鐘舵��
+ const showUploadDialog = ref(false);
+ const uploadFiles = ref([]); // 淇濈暀鐢ㄤ簬鍏煎鎬�
+ const uploadStatusType = ref(0);
+ const uploading = ref(false);
+ const uploadProgress = ref(0);
+ const number = ref(0);
+ const uploadList = ref([]);
+
+ // 涓変釜鍒嗙被鐨勪笂浼犵姸鎬�
+ const beforeModelValue = ref([]); // 鐢熶骇鍓�
+ const afterModelValue = ref([]); // 鐢熶骇涓�
+ const issueModelValue = ref([]); // 鐢熶骇鍚�
+
+ // 褰撳墠婵�娲荤殑涓婁紶绫诲瀷
+ const currentUploadType = ref("before"); // 'before', 'after', 'issue'
+
+ // 鏌ョ湅闄勪欢鐩稿叧鐘舵��
+ const showAttachmentDialog = ref(false);
+ const currentViewTask = ref(null);
+ const currentViewType = ref("before"); // 'before', 'after', 'issue'
+ const attachmentList = ref([]); // 褰撳墠鏌ョ湅浠诲姟鐨勯檮浠跺垪琛�
+
+ // 瑙嗛棰勮鐩稿叧鐘舵��
+ const showVideoDialog = ref(false);
+ const currentVideoFile = ref(null);
+
+ // 寮傚父鐘舵��
+ const hasException = ref(null); // null: 鏈�夋嫨, true: 瀛樺湪寮傚父, false: 姝e父
+
+ // 涓婁紶閰嶇疆
+ const uploadConfig = {
+ action: "/file/upload",
+ limit: 10,
+ fileSize: 50, // MB
+ fileType: ["jpg", "jpeg", "png", "mp4", "mov"],
+ maxVideoDuration: 60, // 绉�
+ };
+
+ // 璁$畻涓婁紶URL
+ const uploadFileUrl = computed(() => {
+ const baseUrl = "http://114.132.189.42:9030";
+
+ return baseUrl + uploadConfig.action;
+ });
+
+ // 璁$畻璇锋眰澶�
+ const headers = computed(() => {
+ const token = getToken();
+ return token ? { Authorization: "Bearer " + token } : {};
+ });
+
+ // 璇锋眰鍙栨秷鏍囧織锛岀敤浜庡彇娑堟鍦ㄨ繘琛岀殑璇锋眰
+ let isRequestCancelled = false;
+
+ const pagesPames = reactive({
+ size: 10,
+ current: 1,
+ });
+
+ const loadMoreStatus = computed(() => {
+ if (loading.value) {
+ return "loading";
+ }
+ if (noMore.value) {
+ return "noMore";
+ }
+ return "more";
+ });
+ const totalSize = ref(0);
+ const noMore = computed(() => {
+ return taskTableData.value.length >= totalSize.value;
+ });
+ const loading = ref(false);
+
+ const reloadPage = () => {
+ pagesPames.current = 1;
+ taskTableData.value = [];
+ getList();
+ };
+ const loadPage = () => {
+ if (noMore.value || loading.value) return;
+ pagesPames.current += 1;
+ getList();
+ };
+
+ // 鐢熷懡鍛ㄦ湡
+ onMounted(() => {
+ // 寤惰繜鍒濆鍖栵紝纭繚DOM宸叉覆鏌�
+ // nextTick(() => {
+ // getList()
+ // })
+ });
+
+ onReachBottom(() => {
+ loadPage();
+ });
+ onPullDownRefresh(() => {
+ reloadPage();
+ uni.stopPullDownRefresh();
+ });
+
+ onShow(() => {
+ // 椤甸潰鏄剧ず鏃跺埛鏂版暟鎹�
+ reloadPage();
+ });
+
+ // 缁勪欢閿�姣佹椂鐨勬竻鐞�
+ onUnmounted(() => {
+ // 璁剧疆鍙栨秷鏍囧織锛岄樆姝㈠悗缁殑寮傛鎿嶄綔
+ isRequestCancelled = true;
+
+ // 鍏抽棴涓婁紶寮圭獥
+ if (showUploadDialog.value) {
+ showUploadDialog.value = false;
+ }
+ });
+
+ // 杩斿洖涓婁竴椤�
+ const goBack = () => {
+ uni.navigateBack();
+ };
+
+ // 鑾峰彇鍒楄〃鏁版嵁
+ const getList = () => {
+ // 鏄剧ず鍔犺浇鎻愮ず
+ // showLoadingToast('鍔犺浇涓�...')
+
+ // 璁剧疆鍙栨秷鏍囧織
+ isRequestCancelled = false;
+ loading.value = true;
+ inspectionTaskList({ ...pagesPames })
+ .then(res => {
+ // 妫�鏌ョ粍浠舵槸鍚﹁繕瀛樺湪涓旇姹傛湭琚彇娑�
+ if (!isRequestCancelled) {
+ // 澶勭悊涓嶅悓鐨勬暟鎹粨鏋�
+ let records = [];
+ if (res && res.data) {
+ // 灏濊瘯澶氱鍙兘鐨勬暟鎹粨鏋�
+ totalSize.value = res.data.total;
+ if (Array.isArray(res.data.records)) {
+ records = res.data.records;
+ } else if (Array.isArray(res.data.rows)) {
+ records = res.data.rows;
+ } else if (Array.isArray(res.data)) {
+ records = res.data;
+ } else if (Array.isArray(res.data.list)) {
+ records = res.data.list;
+ }
+ }
+
+ if (records.length > 0) {
+ taskTableData.value = [
+ ...taskTableData.value,
+ ...records.map(record => {
+ record.fileStatus = getFileStatus(record);
+ return record;
+ }),
+ ];
+ } else {
+ taskTableData.value = [];
+ uni.showToast({
+ title: "鏆傛棤宸℃浠诲姟鏁版嵁",
+ icon: "none",
+ });
+ }
+ }
+ loading.value = false;
+ // 鍏抽棴鍔犺浇鎻愮ず
+ // closeToast()
+ })
+ .catch(err => {
+ // 妫�鏌ョ粍浠舵槸鍚﹁繕瀛樺湪涓旇姹傛湭琚彇娑�
+ if (!isRequestCancelled) {
+ taskTableData.value = [];
+ // 娣诲姞閿欒鎻愮ず
+ uni.showToast({
+ title: "鑾峰彇鏁版嵁澶辫触",
+ icon: "error",
+ });
+ }
+ loading.value = false;
+ // 鍏抽棴鍔犺浇鎻愮ず
+ // closeToast()
+ });
+ };
+
+ 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) {
+ return 2;
+ } else if (_beforeProduction || _afterProduction || _productionIssues) {
+ return 1;
+ } else {
+ return 0;
+ }
+ };
+
+ // 涓烘寚瀹氫换鍔″紑濮嬫壂鐮侊紙鐪熸満锛�
+ const startScanForTask = async task => {
+ try {
+ currentScanningTask.value = task;
+ uni.scanCode({
+ success: res => {
+ handleScanSuccess(res);
+ },
+ fail: err => {
+ console.error("鎵爜澶辫触:", err);
+ uni.showToast({
+ title: "鎵爜澶辫触",
+ icon: "error",
+ });
+ },
+ });
+ } catch (e) {
+ console.error("鍚姩鎵爜澶辫触:", e);
+ uni.showToast({
+ title: "鍚姩鎵爜澶辫触",
+ icon: "error",
+ });
+ }
+ };
+
+ // 鎵爜鎴愬姛澶勭悊锛氭牎楠屽悗鎵撳紑涓婁紶寮圭獥
+ const handleScanSuccess = result => {
+ try {
+ // 瑙f瀽浜岀淮鐮佹暟鎹紝鎻愬彇deviceId
+ let deviceId = "";
+
+ if (result?.result && typeof result.result === "string") {
+ if (result.result.includes("deviceId=")) {
+ const match = result.result.match(/deviceId=(\d+)/);
+ if (match && match[1]) deviceId = match[1];
+ } else {
+ try {
+ const qrData = JSON.parse(result.result);
+ deviceId = qrData.deviceId || qrData.qrCodeId || "";
+ } catch (e) {
+ deviceId = result.result;
+ }
+ }
+ }
+
+ if (!deviceId) {
+ uni.showToast({ title: "鏈瘑鍒埌璁惧ID", icon: "error" });
+ return;
+ }
+
+ const currentTaskId =
+ currentScanningTask.value?.taskId || currentScanningTask.value?.id;
+ if (!currentTaskId) {
+ uni.showToast({ title: "浠诲姟淇℃伅缂哄け", icon: "error" });
+ return;
+ }
+
+ if (deviceId === currentTaskId.toString()) {
+ uni.showToast({ title: "璇嗗埆鎴愬姛", icon: "success" });
+ openUploadDialog(currentScanningTask.value);
+ } else {
+ uni.showToast({ title: "璇锋壂鎻忔纭殑璁惧", icon: "error" });
+ }
+ } catch (error) {
+ console.error("鎵爜缁撴灉澶勭悊澶辫触:", error);
+ uni.showToast({
+ title: error?.message || "鏁版嵁瑙f瀽澶辫触",
+ icon: "error",
+ });
+ }
+ };
+
+ // 鎵撳紑涓婁紶寮圭獥
+ const openUploadDialog = task => {
+ // 璁剧疆浠诲姟淇℃伅鍒癷nfoData
+ if (task) {
+ infoData.value = {
+ ...task,
+ taskId: task.taskId || task.id,
+ storageBlobDTO: [], // 鍒濆鍖栨枃浠跺垪琛�
+ };
+ }
+
+ // 璁剧疆涓婁紶鐘舵�佺被鍨嬶紙鍙互鏍规嵁浠诲姟绫诲瀷璁剧疆涓嶅悓鐨勭姸鎬侊級
+ uploadStatusType.value = 0; // 榛樿鐘舵��
+
+ // 娓呯┖涔嬪墠鐨勬枃浠�
+ uploadFiles.value = [];
+
+ // 鏄剧ず涓婁紶寮圭獥
+ showUploadDialog.value = true;
+ };
+
+ // 鍏抽棴涓婁紶寮圭獥
+ const closeUploadDialog = () => {
+ showUploadDialog.value = false;
+ uploadFiles.value = [];
+ // 娓呯悊涓変釜鍒嗙被鐨勬暟鎹�
+ beforeModelValue.value = [];
+ afterModelValue.value = [];
+ issueModelValue.value = [];
+ currentUploadType.value = "before";
+ hasException.value = null; // 閲嶇疆寮傚父鐘舵��
+ infoData.value = null; // 娓呯悊浠诲姟鏁版嵁
+ };
+
+ // 鍒囨崲涓婁紶绫诲瀷
+ const switchUploadType = type => {
+ currentUploadType.value = type;
+ };
+
+ // 鑾峰彇褰撳墠鍒嗙被鐨勬枃浠跺垪琛�
+ const getCurrentFiles = () => {
+ switch (currentUploadType.value) {
+ case "before":
+ return beforeModelValue.value || [];
+ case "after":
+ return afterModelValue.value || [];
+ case "issue":
+ return issueModelValue.value || [];
+ default:
+ return [];
+ }
+ };
+
+ // 鑾峰彇涓婁紶绫诲瀷鏂囨湰
+ const getUploadTypeText = () => {
+ switch (currentUploadType.value) {
+ case "before":
+ return "鐢熶骇鍓�";
+ case "after":
+ return "鐢熶骇涓�";
+ case "issue":
+ return "鐢熶骇鍚�";
+ default:
+ return "";
+ }
+ };
+
+ // 澶勭悊涓婁紶鏂囦欢鏇存柊
+ const handleUploadUpdate = files => {
+ uploadFiles.value = files;
+ };
+
+ // 璁剧疆寮傚父鐘舵��
+ const setExceptionStatus = status => {
+ hasException.value = status;
+ };
+
+ // 璺宠浆鍒版柊澧炴姤淇〉闈�
+ const goToRepair = () => {
+ try {
+ // 瀛樺偍褰撳墠浠诲姟淇℃伅鍒版湰鍦板瓨鍌紝渚涙姤淇〉闈娇鐢�
+ const taskInfo = {
+ taskId: infoData.value?.taskId || infoData.value?.id,
+ taskName: infoData.value?.taskName,
+ inspectionLocation: infoData.value?.inspectionLocation,
+ inspector: infoData.value?.inspector,
+ // 浼犻�掑綋鍓嶄笂浼犵殑鏂囦欢淇℃伅
+ uploadedFiles: {
+ before: beforeModelValue.value,
+ after: afterModelValue.value,
+ issue: issueModelValue.value,
+ },
+ };
+
+ uni.setStorageSync("repairTaskInfo", JSON.stringify(taskInfo));
+
+ // 璺宠浆鍒版柊澧炴姤淇〉闈�
+ uni.navigateTo({
+ url: "/pages/equipmentManagement/repair/add",
+ });
+
+ // 鍏抽棴涓婁紶寮圭獥
+ closeUploadDialog();
+ } catch (error) {
+ console.error("璺宠浆鎶ヤ慨椤甸潰澶辫触:", error);
+ uni.showToast({
+ title: "璺宠浆澶辫触锛岃閲嶈瘯",
+ icon: "error",
+ });
+ }
+ };
+
+ // 鎻愪氦涓婁紶
+ const submitUpload = async () => {
+ try {
+ // 妫�鏌ユ槸鍚﹂�夋嫨浜嗗紓甯哥姸鎬�
+ if (hasException.value === null) {
+ uni.showToast({
+ title: "璇烽�夋嫨鏄惁瀛樺湪寮傚父",
+ icon: "none",
+ });
+ return;
+ }
+
+ // 妫�鏌ユ槸鍚︽湁浠讳綍鏂囦欢涓婁紶
+ const totalFiles =
+ beforeModelValue.value.length +
+ afterModelValue.value.length +
+ issueModelValue.value.length;
+ if (totalFiles === 0) {
+ uni.showToast({
+ title: "璇峰厛涓婁紶鏂囦欢",
+ icon: "none",
+ });
+ return;
+ }
+
+ // 鏄剧ず鎻愪氦涓殑鍔犺浇鎻愮ず
+ showLoadingToast("鎻愪氦涓�...");
+
+ // 鎸夌収鎮ㄧ殑閫昏緫鍚堝苟鎵�鏈夊垎绫荤殑鏂囦欢
+ let arr = [];
+ if (beforeModelValue.value.length > 0) {
+ arr.push(...beforeModelValue.value);
+ }
+ if (afterModelValue.value.length > 0) {
+ arr.push(...afterModelValue.value);
+ }
+ if (issueModelValue.value.length > 0) {
+ arr.push(...issueModelValue.value);
+ }
+
+ // 浼犵粰鍚庣鐨勪复鏃舵枃浠禝D鍒楄〃锛坱empFileIds锛�
+ // 鍏煎锛氭湁浜涙帴鍙e彲鑳借繑鍥� 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 });
+
+ // 妫�鏌ユ彁浜ょ粨鏋�
+ if (result && (result.code === 200 || result.success)) {
+ // 鎻愪氦鎴愬姛
+ closeToast(); // 鍏抽棴鍔犺浇鎻愮ず
+
+ uni.showToast({
+ title: "鎻愪氦鎴愬姛",
+ icon: "success",
+ });
+
+ // 鍏抽棴寮圭獥
+ closeUploadDialog();
+
+ // 鍒锋柊鍒楄〃
+ setTimeout(() => {
+ reloadPage();
+ }, 500);
+ } else {
+ // 鎻愪氦澶辫触
+ closeToast();
+ uni.showToast({
+ title: result?.msg || result?.message || "鎻愪氦澶辫触",
+ icon: "error",
+ });
+ }
+ } catch (error) {
+ console.error("鎻愪氦涓婁紶澶辫触:", error);
+ closeToast(); // 鍏抽棴鍔犺浇鎻愮ず
+
+ let errorMessage = "鎻愪氦澶辫触";
+ if (error.message) {
+ errorMessage = error.message;
+ } else if (error.msg) {
+ errorMessage = error.msg;
+ } else if (typeof error === "string") {
+ errorMessage = error;
+ }
+
+ uni.showToast({
+ title: errorMessage,
+ icon: "error",
+ });
+ }
+ };
+
+ // 鏌ョ湅闄勪欢
+ const viewAttachments = async task => {
+ try {
+ currentViewTask.value = task;
+ currentViewType.value = "before";
+
+ // 瑙f瀽鏂扮殑鏁版嵁缁撴瀯
+ attachmentList.value = [];
+
+ // 鍚庣鍙嶆樉瀛楁锛堜綘鎻愪緵鐨勬暟鎹粨鏋勶級锛�
+ // - 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,
+ // 鐢ㄤ簬涓夋爣绛鹃〉鍒嗙粍锛�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,
+ };
+ };
+
+ 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;
+ } catch (error) {
+ uni.showToast({
+ title: "鑾峰彇闄勪欢澶辫触",
+ icon: "error",
+ });
+ }
+ };
+
+ // 鍏抽棴闄勪欢鏌ョ湅寮圭獥
+ const closeAttachmentDialog = () => {
+ showAttachmentDialog.value = false;
+ currentViewTask.value = null;
+ attachmentList.value = [];
+ currentViewType.value = "before";
+ };
+
+ // 鍒囨崲鏌ョ湅绫诲瀷
+ const switchViewType = type => {
+ currentViewType.value = type;
+ };
+
+ // 鏍规嵁type鑾峰彇瀵瑰簲鍒嗙被鐨勯檮浠�
+ const getAttachmentsByType = typeValue => {
+ return attachmentList.value.filter(file => file.type === typeValue) || [];
+ };
+ // 鑾峰彇type鍊�
+ const getTabType = () => {
+ switch (currentUploadType.value) {
+ case "before":
+ return 10;
+ case "after":
+ return 11;
+ case "issue":
+ return 12;
+ default:
+ return 10;
+ }
+ };
+ // 鑾峰彇褰撳墠鏌ョ湅绫诲瀷鐨勯檮浠�
+ 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 => {
+ // 妫�鏌ontentType瀛楁
+ if (file.contentType && file.contentType.startsWith("image/")) {
+ return true;
+ }
+
+ // 妫�鏌ュ師鏈夌殑type瀛楁
+ if (file.type === "image") return true;
+
+ // 妫�鏌ユ枃浠舵墿灞曞悕
+ 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 || "";
+ }
+ };
+
+ // 棰勮闄勪欢
+ const previewAttachment = file => {
+ if (isImageFile(file)) {
+ // 棰勮鍥剧墖
+ const imageUrls = getCurrentViewAttachments()
+ .filter(f => isImageFile(f))
+ .map(f => f.url || f.downloadUrl);
+
+ uni.previewImage({
+ urls: imageUrls,
+ current: file.url || file.downloadUrl,
+ });
+ } else {
+ // 棰勮瑙嗛 - 鏄剧ず瑙嗛鎾斁寮圭獥
+ showVideoPreview(file);
+ }
+ };
+
+ // 鏄剧ず瑙嗛棰勮
+ const showVideoPreview = file => {
+ currentVideoFile.value = file;
+ showVideoDialog.value = true;
+ };
+
+ // 鍏抽棴瑙嗛棰勮
+ const closeVideoPreview = () => {
+ showVideoDialog.value = false;
+ currentVideoFile.value = null;
+ };
+
+ // 瑙嗛鎾斁閿欒澶勭悊
+ const handleVideoError = error => {
+ uni.showToast({
+ title: "瑙嗛鎾斁澶辫触",
+ icon: "error",
+ });
+ };
+
+ // 鎷嶇収/鎷嶈棰戯紙鐪熸満浼樺厛鐢� chooseMedia锛涗笉鏀寔鍒欓檷绾э級
+ const chooseMedia = type => {
+ if (getCurrentFiles().length >= uploadConfig.limit) {
+ uni.showToast({
+ title: `鏈�澶氬彧鑳介�夋嫨${uploadConfig.limit}涓枃浠禶,
+ icon: "none",
+ });
+ return;
+ }
+
+ const remaining = uploadConfig.limit - getCurrentFiles().length;
+
+ // 浼樺厛锛歝hooseMedia锛堟敮鎸� image/video锛�
+ if (typeof uni.chooseMedia === "function") {
+ uni.chooseMedia({
+ count: Math.min(remaining, 1),
+ mediaType: [type || "image"],
+ sizeType: ["compressed", "original"],
+ sourceType: ["camera"],
+ success: res => {
+ try {
+ const files = res?.tempFiles || [];
+ if (!files.length) throw new Error("鏈幏鍙栧埌鏂囦欢");
+
+ 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: 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: "鎷嶆憚澶辫触", icon: "error" });
+ },
+ });
+ return;
+ }
+
+ // 闄嶇骇锛歝hooseImage / 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 chooseImage = () => {
+ if (uploadFiles.value.length >= uploadConfig.limit) {
+ uni.showToast({
+ title: `鏈�澶氬彧鑳芥媿鎽�${uploadConfig.limit}涓枃浠禶,
+ icon: "none",
+ });
+ return;
+ }
+
+ uni.chooseMedia({
+ count: 1,
+ mediaType: ["image", "video"],
+ sizeType: ["compressed", "original"],
+ sourceType: ["camera"],
+ success: res => {
+ try {
+ if (!res.tempFiles || res.tempFiles.length === 0) {
+ throw new Error("鏈幏鍙栧埌鍥剧墖鏂囦欢");
+ }
+
+ const tempFilePath = res.tempFiles[0];
+ const tempFile =
+ res.tempFiles && res.tempFiles[0] ? res.tempFiles[0] : {};
+
+ 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",
+ });
+ }
+ },
+ fail: err => {
+ console.error("鎷嶇収澶辫触:", err);
+ uni.showToast({
+ title: "鎷嶇収澶辫触: " + (err.errMsg || "鏈煡閿欒"),
+ icon: "error",
+ });
+ },
+ });
+ };
+
+ // 鎷嶈棰�
+ const chooseVideo = () => {
+ if (uploadFiles.value.length >= uploadConfig.limit) {
+ uni.showToast({
+ title: `鏈�澶氬彧鑳芥媿鎽�${uploadConfig.limit}涓枃浠禶,
+ icon: "none",
+ });
+ return;
+ }
+
+ uni.chooseVideo({
+ sourceType: ["camera"],
+ maxDuration: uploadConfig.maxVideoDuration,
+ camera: "back",
+ success: res => {
+ try {
+ if (!res.tempFilePath) {
+ throw new Error("鏈幏鍙栧埌瑙嗛鏂囦欢");
+ }
+
+ const file = {
+ tempFilePath: res.tempFilePath,
+ path: res.tempFilePath, // 淇濇寔鍏煎鎬�
+ type: "video",
+ name: `video_${Date.now()}.mp4`,
+ size: res.size || 0,
+ duration: res.duration || 0,
+ createTime: new Date().getTime(),
+ uid: Date.now() + Math.random(),
+ };
+
+ handleBeforeUpload(file);
+ } catch (error) {
+ console.error("澶勭悊鎷嶈棰戠粨鏋滃け璐�:", error);
+ uni.showToast({
+ title: "澶勭悊瑙嗛澶辫触",
+ icon: "error",
+ });
+ }
+ },
+ fail: err => {
+ console.error("鎷嶈棰戝け璐�:", err);
+ uni.showToast({
+ title: "鎷嶈棰戝け璐�: " + (err.errMsg || "鏈煡閿欒"),
+ icon: "error",
+ });
+ },
+ });
+ };
+
+ // 鍒犻櫎鏂囦欢
+ const removeFile = index => {
+ uni.showModal({
+ title: "纭鍒犻櫎",
+ content: "纭畾瑕佸垹闄よ繖涓枃浠跺悧锛�",
+ success: res => {
+ if (res.confirm) {
+ // 鏍规嵁褰撳墠涓婁紶绫诲瀷鍒犻櫎瀵瑰簲鍒嗙被鐨勬枃浠�
+ switch (currentUploadType.value) {
+ case "before":
+ beforeModelValue.value.splice(index, 1);
+ break;
+ case "after":
+ afterModelValue.value.splice(index, 1);
+ break;
+ case "issue":
+ issueModelValue.value.splice(index, 1);
+ break;
+ }
+ uni.showToast({
+ title: "鍒犻櫎鎴愬姛",
+ icon: "success",
+ });
+ }
+ },
+ });
+ };
+
+ // 妫�鏌ョ綉缁滆繛鎺�
+ const checkNetworkConnection = () => {
+ return new Promise(resolve => {
+ uni.getNetworkType({
+ success: res => {
+ if (res.networkType === "none") {
+ resolve(false);
+ } else {
+ resolve(true);
+ }
+ },
+ fail: () => {
+ resolve(false);
+ },
+ });
+ });
+ };
+
+ // 涓婁紶鍓嶆牎楠�
+ const handleBeforeUpload = async file => {
+ // 鏍¢獙鏂囦欢绫诲瀷
+ if (
+ uploadConfig.fileType &&
+ Array.isArray(uploadConfig.fileType) &&
+ uploadConfig.fileType.length > 0
+ ) {
+ const fileName = file.name || "";
+ const fileExtension = fileName
+ ? fileName.split(".").pop().toLowerCase()
+ : "";
+
+ // 鏍规嵁鏂囦欢绫诲瀷纭畾鏈熸湜鐨勬墿灞曞悕
+ let expectedTypes = [];
+ if (file.type === "image") {
+ expectedTypes = ["jpg", "jpeg", "png", "gif", "webp"];
+ } else if (file.type === "video") {
+ expectedTypes = ["mp4", "mov", "avi", "wmv"];
+ }
+
+ // 妫�鏌ユ枃浠舵墿灞曞悕鏄惁鍦ㄥ厑璁哥殑绫诲瀷涓�
+ if (fileExtension && expectedTypes.length > 0) {
+ const isAllowed = expectedTypes.some(
+ type => uploadConfig.fileType.includes(type) && type === fileExtension
+ );
+
+ if (!isAllowed) {
+ uni.showToast({
+ title: `鏂囦欢鏍煎紡涓嶆敮鎸侊紝璇锋媿鎽� ${expectedTypes.join("/")} 鏍煎紡鐨勬枃浠禶,
+ icon: "none",
+ });
+ return false;
+ }
+ }
+ }
+
+ // 鏍¢獙閫氳繃锛屽紑濮嬩笂浼�
+ uploadFile(file);
+ return true;
+ };
+
+ // 鏂囦欢涓婁紶澶勭悊锛堢湡鏈鸿蛋 uni.uploadFile锛�
+ const uploadFile = async file => {
+ uploading.value = true;
+ uploadProgress.value = 0;
+ number.value++; // 澧炲姞涓婁紶璁℃暟
+
+ // 纭繚token瀛樺湪
+ const token = getToken();
+ if (!token) {
+ handleUploadError("鐢ㄦ埛鏈櫥褰�");
+ return;
+ }
+
+ const typeValue = getTabType(); // 鐢熶骇鍓�:10, 鐢熶骇涓�:11, 鐢熶骇鍚�:12
+
+ uploadWithUniUploadFile(
+ file,
+ file.tempFilePath || file.path || "",
+ typeValue,
+ token
+ );
+ };
+
+ // 浣跨敤uni.uploadFile涓婁紶锛堥潪H5鐜鎴朒5鍥為��鏂规锛�
+ const uploadWithUniUploadFile = (file, filePath, typeValue, token) => {
+ if (!filePath) {
+ handleUploadError("鏂囦欢璺緞涓嶅瓨鍦�");
+ return;
+ }
+
+ const uploadTask = uni.uploadFile({
+ url: uploadFileUrl.value,
+ filePath: filePath,
+ name: "file",
+ formData: {
+ type: typeValue,
+ },
+ header: {
+ Authorization: `Bearer ${token}`,
+ },
+ success: res => {
+ try {
+ if (res.statusCode === 200) {
+ const response = JSON.parse(res.data);
+ if (response.code === 200) {
+ handleUploadSuccess(response, file);
+ uni.showToast({
+ title: "涓婁紶鎴愬姛",
+ icon: "success",
+ });
+ } else {
+ handleUploadError(response.msg || "鏈嶅姟鍣ㄨ繑鍥為敊璇�");
+ }
+ } else {
+ handleUploadError(`鏈嶅姟鍣ㄩ敊璇紝鐘舵�佺爜: ${res.statusCode}`);
+ }
+ } catch (e) {
+ console.error("瑙f瀽鍝嶅簲澶辫触:", e);
+ console.error("鍘熷鍝嶅簲鏁版嵁:", res.data);
+ handleUploadError("鍝嶅簲鏁版嵁瑙f瀽澶辫触: " + e.message);
+ }
+ },
+ fail: err => {
+ console.error("涓婁紶澶辫触:", err.errMsg || err);
+ number.value--; // 涓婁紶澶辫触鏃跺噺灏戣鏁�
+
+ let errorMessage = "涓婁紶澶辫触";
+ if (err.errMsg) {
+ if (err.errMsg.includes("statusCode: null")) {
+ errorMessage = "缃戠粶杩炴帴澶辫触锛岃妫�鏌ョ綉缁滆缃�";
+ } else if (err.errMsg.includes("timeout")) {
+ errorMessage = "涓婁紶瓒呮椂锛岃閲嶈瘯";
+ } else if (err.errMsg.includes("fail")) {
+ errorMessage = "涓婁紶澶辫触锛岃妫�鏌ョ綉缁滆繛鎺�";
+ } else {
+ errorMessage = err.errMsg;
+ }
+ }
+
+ handleUploadError(errorMessage);
+ },
+ complete: () => {
+ uploading.value = false;
+ uploadProgress.value = 0;
+ },
+ });
+
+ // 鐩戝惉涓婁紶杩涘害
+ if (uploadTask && uploadTask.onProgressUpdate) {
+ uploadTask.onProgressUpdate(res => {
+ uploadProgress.value = res.progress;
+ });
+ }
+ };
+
+ // 涓婁紶澶辫触澶勭悊
+ const handleUploadError = (message = "涓婁紶鏂囦欢澶辫触", showRetry = false) => {
+ 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",
+ });
+ }
+ };
+
+ // 涓婁紶鎴愬姛鍥炶皟
+ const handleUploadSuccess = (res, file) => {
+ console.log("涓婁紶鎴愬姛鍝嶅簲:", res);
+
+ // 澶勭悊涓嶅悓鐨勬暟鎹粨鏋勶細鍙兘鏄暟缁勶紝涔熷彲鑳芥槸鍗曚釜瀵硅薄
+ let uploadedFile = null;
+ uploadedFile = res.data;
+
+ if (!uploadedFile) {
+ console.error("鏃犳硶瑙f瀽涓婁紶鍝嶅簲鏁版嵁:", res);
+ number.value--; // 涓婁紶澶辫触鏃跺噺灏戣鏁�
+ handleUploadError("涓婁紶鍝嶅簲鏁版嵁鏍煎紡閿欒", false);
+ return;
+ }
+
+ // 鏍规嵁褰撳墠涓婁紶绫诲瀷璁剧疆type瀛楁
+ let typeValue = 0; // 榛樿涓虹敓浜у墠
+ switch (currentUploadType.value) {
+ case "before":
+ typeValue = 0;
+ break;
+ case "after":
+ typeValue = 1;
+ break;
+ case "issue":
+ typeValue = 2;
+ break;
+ }
+
+ // 纭繚涓婁紶鐨勬枃浠舵暟鎹畬鏁达紝鍖呭惈id鍜宼ype
+ const fileData = {
+ ...file,
+ id: uploadedFile.id, // 娣诲姞鏈嶅姟鍣ㄨ繑鍥炵殑id
+ 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 || uploadedFile.byteSize || file.size,
+ createTime: uploadedFile.createTime || new Date().getTime(),
+ type: typeValue, // 娣诲姞绫诲瀷瀛楁锛�0=鐢熶骇鍓�, 1=鐢熶骇涓�, 2=鐢熶骇鍚�
+ };
+
+ uploadList.value.push(fileData);
+
+ // 绔嬪嵆娣诲姞鍒板搴旂殑鍒嗙被锛屼笉绛夊緟鎵�鏈夋枃浠朵笂浼犲畬鎴�
+ switch (currentUploadType.value) {
+ case "before":
+ beforeModelValue.value.push(fileData);
+ break;
+ case "after":
+ afterModelValue.value.push(fileData);
+ break;
+ case "issue":
+ issueModelValue.value.push(fileData);
+ break;
+ }
+
+ // 閲嶇疆涓婁紶鍒楄〃锛堝洜涓哄凡缁忔坊鍔犲埌瀵瑰簲鍒嗙被浜嗭級
+ uploadList.value = [];
+ number.value = 0;
+ };
+
+ // 涓婁紶缁撴潫澶勭悊锛堝凡搴熷純锛岀幇鍦ㄥ湪handleUploadSuccess涓洿鎺ュ鐞嗭級
+ const uploadedSuccessfully = () => {
+ // 姝ゅ嚱鏁板凡涓嶅啀浣跨敤锛屾枃浠朵笂浼犳垚鍔熷悗绔嬪嵆娣诲姞鍒板搴斿垎绫�
+ };
+
+ // 鏍煎紡鍖栨枃浠跺ぇ灏�
+ const formatFileSize = size => {
+ if (!size) return "";
+ if (size < 1024) return size + "B";
+ if (size < 1024 * 1024) return (size / 1024).toFixed(1) + "KB";
+ return (size / (1024 * 1024)).toFixed(1) + "MB";
+ };
</script>
<style scoped>
-.inspection-upload-page {
- min-height: 100vh;
- background-color: #f5f5f5;
-}
+ .inspection-upload-page {
+ min-height: 100vh;
+ background-color: #f5f5f5;
+ }
-.table-section {
- padding: 15px;
-}
+ .table-section {
+ padding: 15px;
+ }
-.task-list {
- display: flex;
- flex-direction: column;
- gap: 12px;
-}
+ .task-list {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ }
-.task-item {
- background: #fff;
- border-radius: 12px;
- padding: 15px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- transition: all 0.3s ease;
-}
+ .task-item {
+ background: #fff;
+ border-radius: 12px;
+ padding: 15px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+ transition: all 0.3s ease;
+ }
-.task-header {
- display: flex;
- justify-content: space-between;
- align-items: flex-start;
- margin-bottom: 12px;
-}
+ .task-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ margin-bottom: 12px;
+ }
-.task-info {
- flex: 1;
- display: flex;
- flex-direction: column;
- gap: 4px;
-}
+ .task-info {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ }
-.task-name {
- font-size: 16px;
- font-weight: 600;
- color: #333;
-}
+ .task-name {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ }
-.task-location {
- font-size: 14px;
- color: #666;
-}
+ .task-location {
+ font-size: 14px;
+ color: #666;
+ }
-.task-actions {
- display: flex;
- gap: 8px;
-}
+ .task-actions {
+ display: flex;
+ gap: 8px;
+ }
-.task-details {
- display: flex;
- flex-direction: column;
- gap: 6px;
-}
+ .task-details {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+ }
-.detail-item {
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
+ .detail-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ }
-.detail-label {
- font-size: 12px;
- color: #999;
-}
+ .detail-label {
+ font-size: 12px;
+ color: #999;
+ }
-.detail-value {
- font-size: 12px;
- color: #666;
- font-weight: 500;
-}
+ .detail-value {
+ font-size: 12px;
+ color: #666;
+ font-weight: 500;
+ }
-.no-data {
- text-align: center;
- padding: 40px 20px;
- color: #999;
- font-size: 14px;
-}
+ .no-data {
+ text-align: center;
+ padding: 40px 20px;
+ color: #999;
+ font-size: 14px;
+ }
-/* 鎵爜寮圭獥鏍峰紡 */
-.qr-scan-overlay {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0, 0, 0, 0.8);
- z-index: 9999;
- display: flex;
- align-items: center;
- justify-content: center;
-}
+ /* 鎵爜寮圭獥鏍峰紡 */
+ .qr-scan-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgba(0, 0, 0, 0.8);
+ z-index: 9999;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
-.qr-scan-container {
- width: 90vw;
- max-width: 400px;
- background: #fff;
- border-radius: 12px;
- padding: 20px;
- position: relative;
-}
+ .qr-scan-container {
+ width: 90vw;
+ max-width: 400px;
+ background: #fff;
+ border-radius: 12px;
+ padding: 20px;
+ position: relative;
+ }
-.scan-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 15px;
-}
+ .scan-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 15px;
+ }
-.scan-title {
- font-size: 18px;
- font-weight: 600;
- color: #333;
-}
+ .scan-title {
+ font-size: 18px;
+ font-weight: 600;
+ color: #333;
+ }
-.qr-camera {
- width: 100%;
- height: 300px;
- border-radius: 8px;
- overflow: hidden;
- margin-bottom: 15px;
-}
+ .qr-camera {
+ width: 100%;
+ height: 300px;
+ border-radius: 8px;
+ overflow: hidden;
+ margin-bottom: 15px;
+ }
-.scan-frame-wrapper {
- position: relative;
- display: flex;
- flex-direction: column;
- align-items: center;
-}
+ .scan-frame-wrapper {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ }
-.scan-frame {
- width: 200px;
- height: 200px;
- border: 2px solid #409eff;
- border-radius: 8px;
- position: relative;
-}
+ .scan-frame {
+ width: 200px;
+ height: 200px;
+ border: 2px solid #409eff;
+ border-radius: 8px;
+ position: relative;
+ }
-.scan-frame::before,
-.scan-frame::after {
- content: '';
- position: absolute;
- width: 20px;
- height: 20px;
- border: 2px solid #409eff;
-}
+ .scan-frame::before,
+ .scan-frame::after {
+ content: "";
+ position: absolute;
+ width: 20px;
+ height: 20px;
+ border: 2px solid #409eff;
+ }
-.scan-frame::before {
- top: -2px;
- left: -2px;
- border-right: none;
- border-bottom: none;
-}
+ .scan-frame::before {
+ top: -2px;
+ left: -2px;
+ border-right: none;
+ border-bottom: none;
+ }
-.scan-frame::after {
- bottom: -2px;
- right: -2px;
- border-left: none;
- border-top: none;
-}
+ .scan-frame::after {
+ bottom: -2px;
+ right: -2px;
+ border-left: none;
+ border-top: none;
+ }
-.scan-tip {
- margin-top: 10px;
- font-size: 14px;
- color: #666;
- text-align: center;
-}
+ .scan-tip {
+ margin-top: 10px;
+ font-size: 14px;
+ color: #666;
+ text-align: center;
+ }
-/* 鑷畾涔夋ā鎬佹鏍峰紡 */
-.custom-modal-overlay {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0, 0, 0, 0.5);
- z-index: 10000;
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 20px;
-}
+ /* 鑷畾涔夋ā鎬佹鏍峰紡 */
+ .custom-modal-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgba(0, 0, 0, 0.5);
+ z-index: 10000;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 20px;
+ }
-.custom-modal-container {
- width: 100%;
- max-width: 500px;
- max-height: 80vh;
- display: flex;
- align-items: center;
- justify-content: center;
-}
+ .custom-modal-container {
+ width: 100%;
+ max-width: 500px;
+ max-height: 80vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
-/* 涓婁紶寮圭獥鏍峰紡 */
-.upload-popup-content {
- background: #fff;
- border-radius: 12px;
- width: 100%;
- min-height: 300px;
- max-height: 70vh;
- overflow: hidden;
- display: flex;
- flex-direction: column;
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
-}
+ /* 涓婁紶寮圭獥鏍峰紡 */
+ .upload-popup-content {
+ background: #fff;
+ border-radius: 12px;
+ width: 100%;
+ min-height: 300px;
+ max-height: 70vh;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
+ }
-.upload-popup-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 15px 20px;
- border-bottom: 1px solid #eee;
-}
+ .upload-popup-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 15px 20px;
+ border-bottom: 1px solid #eee;
+ }
-.upload-popup-title {
- font-size: 16px;
- font-weight: 600;
- color: #333;
-}
+ .upload-popup-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ }
-.upload-popup-body {
- flex: 1;
- padding: 20px;
- overflow-y: auto;
-}
+ .upload-popup-body {
+ flex: 1;
+ padding: 20px;
+ overflow-y: auto;
+ }
-.upload-popup-footer {
- display: flex;
- justify-content: flex-end;
- padding: 15px 20px;
- border-top: 1px solid #eee;
- gap: 10px;
-}
+ .upload-popup-footer {
+ display: flex;
+ justify-content: flex-end;
+ padding: 15px 20px;
+ border-top: 1px solid #eee;
+ gap: 10px;
+ }
-/* 绠�鍖栦笂浼犵粍浠舵牱寮� */
-.simple-upload-area {
- padding: 15px;
-}
+ /* 绠�鍖栦笂浼犵粍浠舵牱寮� */
+ .simple-upload-area {
+ padding: 15px;
+ }
-.upload-buttons {
- display: flex;
- gap: 10px;
- margin-bottom: 15px;
-}
+ .upload-buttons {
+ display: flex;
+ gap: 10px;
+ margin-bottom: 15px;
+ }
-.file-list {
- margin-top: 15px;
- display: flex;
- flex-wrap: wrap;
- gap: 12px;
-}
+ .file-list {
+ margin-top: 15px;
+ display: flex;
+ flex-wrap: wrap;
+ gap: 12px;
+ }
-.file-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- background: #fff;
- border-radius: 12px;
- padding: 8px;
- border: 1px solid #e9ecef;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
- transition: all 0.3s ease;
- width: calc(50% - 6px);
- min-width: 120px;
-}
+ .file-item {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ background: #fff;
+ border-radius: 12px;
+ padding: 8px;
+ border: 1px solid #e9ecef;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
+ transition: all 0.3s ease;
+ width: calc(50% - 6px);
+ min-width: 120px;
+ }
-.file-item:hover {
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
- transform: translateY(-2px);
-}
+ .file-item:hover {
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+ transform: translateY(-2px);
+ }
-.file-preview-container {
- position: relative;
- margin-bottom: 8px;
-}
+ .file-preview-container {
+ position: relative;
+ margin-bottom: 8px;
+ }
-.file-preview {
- width: 80px;
- height: 80px;
- border-radius: 8px;
- object-fit: cover;
- border: 2px solid #f0f0f0;
-}
+ .file-preview {
+ width: 80px;
+ height: 80px;
+ border-radius: 8px;
+ object-fit: cover;
+ border: 2px solid #f0f0f0;
+ }
-.video-preview {
- width: 80px;
- height: 80px;
- background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
- border-radius: 8px;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- border: 2px solid #f0f0f0;
-}
+ .video-preview {
+ width: 80px;
+ height: 80px;
+ background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
+ border-radius: 8px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ border: 2px solid #f0f0f0;
+ }
-.video-text {
- font-size: 12px;
- color: #666;
- margin-top: 4px;
-}
+ .video-text {
+ font-size: 12px;
+ color: #666;
+ margin-top: 4px;
+ }
-.delete-btn {
- position: absolute;
- top: -6px;
- right: -6px;
- width: 20px;
- height: 20px;
- background: #ff4757;
- border-radius: 50%;
- 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;
-}
+ .delete-btn {
+ position: absolute;
+ top: -6px;
+ right: -6px;
+ width: 20px;
+ height: 20px;
+ background: #ff4757;
+ border-radius: 50%;
+ 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;
+ }
-.delete-btn:hover {
- background: #ff3742;
- transform: scale(1.1);
-}
+ .delete-btn:hover {
+ background: #ff3742;
+ transform: scale(1.1);
+ }
-.file-info {
- text-align: center;
- width: 100%;
-}
+ .file-info {
+ text-align: center;
+ width: 100%;
+ }
-.file-name {
- font-size: 12px;
- color: #333;
- font-weight: 500;
- display: block;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- max-width: 100px;
-}
+ .file-name {
+ font-size: 12px;
+ color: #333;
+ font-weight: 500;
+ display: block;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 100px;
+ }
-.file-size {
- font-size: 10px;
- color: #999;
- margin-top: 2px;
- display: block;
-}
+ .file-size {
+ font-size: 10px;
+ color: #999;
+ margin-top: 2px;
+ display: block;
+ }
-.empty-state {
- text-align: center;
- padding: 40px 20px;
- color: #999;
- font-size: 14px;
- background: #f8f9fa;
- border-radius: 8px;
- border: 2px dashed #ddd;
-}
+ .empty-state {
+ text-align: center;
+ padding: 40px 20px;
+ color: #999;
+ font-size: 14px;
+ background: #f8f9fa;
+ border-radius: 8px;
+ border: 2px dashed #ddd;
+ }
-.upload-progress {
- margin: 15px 0;
- padding: 0 10px;
-}
+ .upload-progress {
+ margin: 15px 0;
+ padding: 0 10px;
+ }
-/* 涓婁紶鏍囩椤垫牱寮� */
-.upload-tabs {
- display: flex;
- background: #f8f9fa;
- border-radius: 8px;
- margin-bottom: 15px;
- padding: 4px;
-}
+ /* 涓婁紶鏍囩椤垫牱寮� */
+ .upload-tabs {
+ display: flex;
+ background: #f8f9fa;
+ border-radius: 8px;
+ margin-bottom: 15px;
+ padding: 4px;
+ }
-.tab-item {
- flex: 1;
- text-align: center;
- padding: 8px 12px;
- font-size: 14px;
- color: #666;
- border-radius: 6px;
- transition: all 0.3s ease;
- cursor: pointer;
-}
+ .tab-item {
+ flex: 1;
+ text-align: center;
+ padding: 8px 12px;
+ font-size: 14px;
+ color: #666;
+ border-radius: 6px;
+ transition: all 0.3s ease;
+ cursor: pointer;
+ }
-.tab-item.active {
- background: #409eff;
- color: #fff;
- font-weight: 500;
-}
+ .tab-item.active {
+ background: #409eff;
+ color: #fff;
+ font-weight: 500;
+ }
-.tab-item:hover:not(.active) {
- background: #e9ecef;
- color: #333;
-}
+ .tab-item:hover:not(.active) {
+ background: #e9ecef;
+ color: #333;
+ }
-/* 寮傚父鐘舵�侀�夋嫨鏍峰紡 */
-.exception-section {
- margin-bottom: 20px;
- padding: 15px;
- background: #f8f9fa;
- border-radius: 8px;
- border: 1px solid #e9ecef;
-}
+ /* 寮傚父鐘舵�侀�夋嫨鏍峰紡 */
+ .exception-section {
+ margin-bottom: 20px;
+ padding: 15px;
+ background: #f8f9fa;
+ border-radius: 8px;
+ border: 1px solid #e9ecef;
+ }
-.section-title {
- display: block;
- font-size: 14px;
- font-weight: 600;
- color: #333;
- margin-bottom: 12px;
-}
+ .section-title {
+ display: block;
+ font-size: 14px;
+ font-weight: 600;
+ color: #333;
+ margin-bottom: 12px;
+ }
-.exception-options {
- display: flex;
- gap: 12px;
-}
+ .exception-options {
+ display: flex;
+ gap: 12px;
+ }
-.exception-option {
- flex: 1;
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 8px;
- padding: 12px 16px;
- background: #fff;
- border: 2px solid #e9ecef;
- border-radius: 8px;
- cursor: pointer;
- transition: all 0.3s ease;
- font-size: 14px;
- color: #666;
-}
+ .exception-option {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ padding: 12px 16px;
+ background: #fff;
+ border: 2px solid #e9ecef;
+ border-radius: 8px;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ font-size: 14px;
+ color: #666;
+ }
-.exception-option.active {
- border-color: #409eff;
- background: #f0f8ff;
- color: #409eff;
- font-weight: 500;
-}
+ .exception-option.active {
+ border-color: #409eff;
+ background: #f0f8ff;
+ color: #409eff;
+ font-weight: 500;
+ }
-.exception-option:hover:not(.active) {
- border-color: #d9d9d9;
- background: #fafafa;
-}
+ .exception-option:hover:not(.active) {
+ border-color: #d9d9d9;
+ background: #fafafa;
+ }
-/* 缁熻淇℃伅鏍峰紡 */
-.upload-summary {
- margin-top: 15px;
- padding: 10px;
- background: #f8f9fa;
- border-radius: 6px;
- border-left: 3px solid #409eff;
-}
+ /* 缁熻淇℃伅鏍峰紡 */
+ .upload-summary {
+ margin-top: 15px;
+ padding: 10px;
+ background: #f8f9fa;
+ border-radius: 6px;
+ border-left: 3px solid #409eff;
+ }
-.summary-text {
- font-size: 12px;
- color: #666;
- line-height: 1.4;
-}
+ .summary-text {
+ font-size: 12px;
+ color: #666;
+ line-height: 1.4;
+ }
-/* 鏌ョ湅闄勪欢寮圭獥鏍峰紡 */
-.attachment-popup-content {
- background: #fff;
- border-radius: 12px;
- width: 100%;
- min-height: 400px;
- max-height: 70vh;
- overflow: hidden;
- display: flex;
- flex-direction: column;
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
-}
+ /* 鏌ョ湅闄勪欢寮圭獥鏍峰紡 */
+ .attachment-popup-content {
+ background: #fff;
+ border-radius: 12px;
+ width: 100%;
+ min-height: 400px;
+ max-height: 70vh;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
+ }
-.attachment-popup-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 15px 20px;
- border-bottom: 1px solid #eee;
- background: #f8f9fa;
-}
+ .attachment-popup-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 15px 20px;
+ border-bottom: 1px solid #eee;
+ background: #f8f9fa;
+ }
-.attachment-popup-title {
- font-size: 16px;
- font-weight: 600;
- color: #333;
-}
+ .attachment-popup-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+ }
-.close-btn-attachment {
- width: 28px;
- height: 28px;
- border-radius: 50%;
- background: #f5f5f5;
- display: flex;
- align-items: center;
- justify-content: center;
- cursor: pointer;
- transition: all 0.3s ease;
-}
+ .close-btn-attachment {
+ width: 28px;
+ height: 28px;
+ border-radius: 50%;
+ background: #f5f5f5;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ }
-.close-btn-attachment:hover {
- background: #e9ecef;
- transform: scale(1.1);
-}
+ .close-btn-attachment:hover {
+ background: #e9ecef;
+ transform: scale(1.1);
+ }
-.attachment-popup-body {
- flex: 1;
- padding: 15px 20px;
- overflow-y: auto;
-}
+ .attachment-popup-body {
+ flex: 1;
+ padding: 15px 20px;
+ overflow-y: auto;
+ }
-.attachment-tabs {
- display: flex;
- background: #f8f9fa;
- border-radius: 8px;
- margin-bottom: 15px;
- padding: 4px;
-}
+ .attachment-tabs {
+ display: flex;
+ background: #f8f9fa;
+ border-radius: 8px;
+ margin-bottom: 15px;
+ padding: 4px;
+ }
-.attachment-content {
- min-height: 200px;
-}
+ .attachment-content {
+ min-height: 200px;
+ }
-.attachment-list {
- display: flex;
- flex-wrap: wrap;
- gap: 12px;
-}
+ .attachment-list {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 12px;
+ }
-.attachment-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- background: #fff;
- border-radius: 12px;
- padding: 8px;
- border: 1px solid #e9ecef;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
- transition: all 0.3s ease;
- width: calc(33.33% - 8px);
- min-width: 100px;
- cursor: pointer;
-}
+ .attachment-item {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ background: #fff;
+ border-radius: 12px;
+ padding: 8px;
+ border: 1px solid #e9ecef;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
+ transition: all 0.3s ease;
+ width: calc(33.33% - 8px);
+ min-width: 100px;
+ cursor: pointer;
+ }
-.attachment-item:hover {
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
- transform: translateY(-2px);
-}
+ .attachment-item:hover {
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+ transform: translateY(-2px);
+ }
-.attachment-preview-container {
- margin-bottom: 8px;
-}
+ .attachment-preview-container {
+ margin-bottom: 8px;
+ }
-.attachment-preview {
- width: 80px;
- height: 80px;
- border-radius: 8px;
- object-fit: cover;
- border: 2px solid #f0f0f0;
-}
+ .attachment-preview {
+ width: 80px;
+ height: 80px;
+ border-radius: 8px;
+ object-fit: cover;
+ border: 2px solid #f0f0f0;
+ }
-.attachment-video-preview {
- width: 80px;
- height: 80px;
- background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
- border-radius: 8px;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- border: 2px solid #f0f0f0;
-}
+ .attachment-video-preview {
+ width: 80px;
+ height: 80px;
+ background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
+ border-radius: 8px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ border: 2px solid #f0f0f0;
+ }
-.attachment-info {
- text-align: center;
- width: 100%;
-}
+ .attachment-info {
+ text-align: center;
+ width: 100%;
+ }
-.attachment-name {
- font-size: 12px;
- color: #333;
- font-weight: 500;
- display: block;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- max-width: 80px;
-}
+ .attachment-name {
+ font-size: 12px;
+ color: #333;
+ font-weight: 500;
+ display: block;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 80px;
+ }
-.attachment-size {
- font-size: 10px;
- color: #999;
- margin-top: 2px;
- display: block;
-}
+ .attachment-size {
+ font-size: 10px;
+ color: #999;
+ margin-top: 2px;
+ display: block;
+ }
-.attachment-empty {
- text-align: center;
- padding: 60px 20px;
- color: #999;
- font-size: 14px;
- background: #f8f9fa;
- border-radius: 8px;
- border: 2px dashed #ddd;
-}
+ .attachment-empty {
+ text-align: center;
+ padding: 60px 20px;
+ color: #999;
+ font-size: 14px;
+ background: #f8f9fa;
+ border-radius: 8px;
+ border: 2px dashed #ddd;
+ }
-/* 瑙嗛棰勮寮圭獥鏍峰紡 */
-.video-modal-overlay {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0, 0, 0, 0.8);
- z-index: 10001;
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 20px;
-}
+ /* 瑙嗛棰勮寮圭獥鏍峰紡 */
+ .video-modal-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: rgba(0, 0, 0, 0.8);
+ z-index: 10001;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 20px;
+ }
-.video-modal-container {
- width: 90%;
- max-width: 800px;
- max-height: 80vh;
- background: #000;
- border-radius: 12px;
- overflow: hidden;
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
-}
+ .video-modal-container {
+ width: 90%;
+ max-width: 800px;
+ max-height: 80vh;
+ background: #000;
+ border-radius: 12px;
+ overflow: hidden;
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
+ }
-.video-modal-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 15px 20px;
- background: rgba(0, 0, 0, 0.7);
- color: #fff;
-}
+ .video-modal-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 15px 20px;
+ background: rgba(0, 0, 0, 0.7);
+ color: #fff;
+ }
-.video-modal-title {
- font-size: 16px;
- font-weight: 500;
- color: #fff;
-}
+ .video-modal-title {
+ font-size: 16px;
+ font-weight: 500;
+ color: #fff;
+ }
-.close-btn-video {
- width: 28px;
- height: 28px;
- border-radius: 50%;
- background: rgba(255, 255, 255, 0.2);
- display: flex;
- align-items: center;
- justify-content: center;
- cursor: pointer;
- transition: all 0.3s ease;
-}
+ .close-btn-video {
+ width: 28px;
+ height: 28px;
+ border-radius: 50%;
+ background: rgba(255, 255, 255, 0.2);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ }
-.close-btn-video:hover {
- background: rgba(255, 255, 255, 0.3);
- transform: scale(1.1);
-}
+ .close-btn-video:hover {
+ background: rgba(255, 255, 255, 0.3);
+ transform: scale(1.1);
+ }
-.video-modal-body {
- position: relative;
- background: #000;
-}
+ .video-modal-body {
+ position: relative;
+ background: #000;
+ }
-.video-player {
- width: 100%;
- height: auto;
- max-height: 60vh;
- display: block;
-}
+ .video-player {
+ width: 100%;
+ height: auto;
+ max-height: 60vh;
+ display: block;
+ }
</style>
\ No newline at end of file
--
Gitblit v1.9.3