From 552ec6b7d8ccc56c379da195fc6c9c74312b1070 Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期五, 22 五月 2026 17:57:46 +0800
Subject: [PATCH] OA部分查询条件变更

---
 src/pages/inspectionUpload/index.vue | 1214 ++++++++++++++++++++++++++++++++-------------------------
 1 files changed, 684 insertions(+), 530 deletions(-)

diff --git a/src/pages/inspectionUpload/index.vue b/src/pages/inspectionUpload/index.vue
index 3b9e0d7..bedc38f 100644
--- a/src/pages/inspectionUpload/index.vue
+++ b/src/pages/inspectionUpload/index.vue
@@ -1,51 +1,64 @@
 <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"
-          @click="handleAdd(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="handleAdd(item)"
-                :customStyle="{
-                  borderRadius: '15px',
-                  height: '30px',
-                  fontSize: '12px'
-                }"
-              >
-                涓婁紶
+              <!-- <u-button type="primary"
+                        size="small"
+                        @click.stop="startScanForTask(item)"
+                        :customStyle="{
+                borderRadius: '15px',
+                height: '30px',
+                fontSize: '12px',
+                marginRight: '8px'
+              }">
+                鎵爜涓婁紶
+              </u-button> -->
+              <u-button type="primary"
+                        size="small"
+                        @click.stop="startUploadForTask(item)"
+                        :customStyle="{
+                borderRadius: '15px',
+                height: '30px',
+                fontSize: '12px',
+                marginRight: '8px'
+              }">
+                鍥剧墖涓婁紶
               </u-button>
-              <u-button 
-                type="info" 
-                size="small"
-                @click.stop="startScanForTask(item)"
-                :customStyle="{
-                  borderRadius: '15px',
-                  height: '30px',
-                  fontSize: '12px'
-                }"
-              >
-                鎵爜
+              <u-button type="success"
+                        size="small"
+                        @click.stop="viewAttachments(item)"
+                        :customStyle="{
+                borderRadius: '15px',
+                height: '30px',
+                fontSize: '12px'
+              }">
+                鏌ョ湅闄勪欢
               </u-button>
             </view>
           </view>
           <view class="task-details">
+            <view class="detail-item">
+              <text class="detail-label">浠诲姟ID</text>
+              <text class="detail-value">{{ item.taskId || item.id }}</text>
+            </view>
+            <view class="detail-item">
+              <text class="detail-label">宸℃椤圭洰</text>
+              <text class="detail-value">{{ item.inspectionProject || '鏃�' }}</text>
+            </view>
             <view class="detail-item">
               <text class="detail-label">澶囨敞</text>
               <text class="detail-value">{{ item.remarks || '鏃�' }}</text>
@@ -54,557 +67,698 @@
               <text class="detail-label">鎵ц浜�</text>
               <text class="detail-value">{{ item.inspector }}</text>
             </view>
+            <view class="detail-item">
+              <text class="detail-label">浠诲姟涓嬪彂鏃ユ湡</text>
+              <text class="detail-value">{{ item.dateStr }}</text>
+            </view>
+            <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>
+              </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="isScanning" class="qr-scan-overlay">
-      <view class="qr-scan-container">
-        <view class="scan-header">
-          <text class="scan-title">鎵弿浜岀淮鐮�</text>
-          <u-button 
-            type="error" 
-            size="small"
-            @click.stop="stopScan"
-            :customStyle="{
-              borderRadius: '15px',
-              height: '30px',
-              fontSize: '12px'
-            }"
-          >
-            鍏抽棴
-          </u-button>
+    <!-- 瑙嗛棰勮寮圭獥 -->
+    <view 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>
         </view>
-        <camera 
-          class="qr-camera"
-          device-position="back"
-          flash="off"
-          @scancode="handleScanCode"
-          @error="handleCameraError"
-        ></camera>
-        <view class="scan-frame-wrapper">
-          <view class="scan-frame"></view>
-          <view class="scan-tip">璇峰皢浜岀淮鐮佹斁鍏ユ鍐�</view>
+        <view class="video-modal-body">
+          <video v-if="currentVideoFile"
+                 :src="currentVideoFile.url || currentVideoFile.downloadUrl"
+                 class="video-player"
+                 controls
+                 autoplay
+                 @error="handleVideoError"></video>
         </view>
-        <u-alert 
-          v-if="cameraError"
-          :title="cameraError"
-          type="error"
-          :showIcon="true"
-          :closable="true"
-          @close="cameraError = ''"
-          :customStyle="{
-            margin: '10px 0'
-          }"
-        ></u-alert>
       </view>
     </view>
-    
-    <!-- 寮圭獥缁勪欢 -->
-    <form-dia ref="formDia" @closeDia="handleQuery"></form-dia>
   </view>
 </template>
 
 <script setup>
-import { onMounted, onUnmounted, ref, nextTick } from 'vue'
-import { onShow } from '@dcloudio/uni-app'
-import PageHeader from '@/components/PageHeader.vue'
-import FormDia from './components/formDia.vue'
-import { getLedgerById } from '@/api/equipmentManagement/ledger.js'
-import {inspectionTaskList} from "@/api/inspectionManagement";
+  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 formDia = ref()
+  // 缁勪欢寮曠敤宸茬Щ闄�
 
-// 鍔犺浇鎻愮ず鏂规硶
-const showLoadingToast = (message) => {
-  uni.showLoading({
-    title: message,
-    mask: true
-  })
-}
-const closeToast = () => {
-  uni.hideLoading()
-}
+  // 鍔犺浇鎻愮ず鏂规硶
+  const showLoadingToast = message => {
+    uni.showLoading({
+      title: message,
+      mask: true,
+    });
+  };
+  const closeToast = () => {
+    uni.hideLoading();
+  };
 
-// 琛ㄦ牸鏁版嵁
-const taskTableData = ref([]) // 鐢熶骇宸℃鏁版嵁
+  // 琛ㄦ牸鏁版嵁
+  const taskTableData = ref([]); // 鐢熶骇宸℃鏁版嵁
 
-// 褰撳墠鎵弿鐨勪换鍔�
-const currentScanningTask = ref(null)
+  // 褰撳墠鎵弿鐨勪换鍔�
+  const currentScanningTask = ref(null);
+  const infoData = ref(null);
 
-// 璇锋眰鍙栨秷鏍囧織锛岀敤浜庡彇娑堟鍦ㄨ繘琛岀殑璇锋眰
-let isRequestCancelled = false
+  // 瑙嗛棰勮鐩稿叧鐘舵��
+  const showVideoDialog = ref(false);
+  const currentVideoFile = ref(null);
 
-// 鎵爜鐩稿叧鐘舵��
-const isScanning = ref(false)
-const cameraError = ref('')
+  // 璇锋眰鍙栨秷鏍囧織锛岀敤浜庡彇娑堟鍦ㄨ繘琛岀殑璇锋眰
+  let isRequestCancelled = false;
 
-// 鐢熷懡鍛ㄦ湡
-onMounted(() => {
-  // 寤惰繜鍒濆鍖栵紝纭繚DOM宸叉覆鏌�
-  nextTick(() => {
-    getList()
-  })
-})
+  const pagesPames = reactive({
+    size: 10,
+    current: 1,
+  });
 
-onShow(() => {
-  // 椤甸潰鏄剧ず鏃跺埛鏂版暟鎹�
-  getList()
-})
-
-// 缁勪欢閿�姣佹椂鐨勬竻鐞�
-onUnmounted(() => {
-  // 璁剧疆鍙栨秷鏍囧織锛岄樆姝㈠悗缁殑寮傛鎿嶄綔
-  isRequestCancelled = true
-  
-  // 鍋滄鎵爜
-  if (isScanning.value) {
-    isScanning.value = false
-  }
-})
-
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
-  uni.navigateBack()
-}
-
-// 鏌ヨ鏁版嵁
-const handleQuery = () => {
-  getList()
-}
-
-// 鑾峰彇鍒楄〃鏁版嵁
-const getList = () => {
-  // 鏄剧ず鍔犺浇鎻愮ず
-  showLoadingToast('鍔犺浇涓�...')
-  
-  // 璁剧疆鍙栨秷鏍囧織
-  isRequestCancelled = false
-  
-  inspectionTaskList({}).then(res => {
-    // 妫�鏌ョ粍浠舵槸鍚﹁繕瀛樺湪涓旇姹傛湭琚彇娑�
-    if (!isRequestCancelled) {
-      console.log('鐢熶骇宸℃API杩斿洖鏁版嵁:', res);
-      
-      // 澶勭悊涓嶅悓鐨勬暟鎹粨鏋�
-      let records = [];
-      if (res && res.data) {
-        // 灏濊瘯澶氱鍙兘鐨勬暟鎹粨鏋�
-        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 = records;
-        console.log('鐢熶骇宸℃鏁版嵁璁剧疆鎴愬姛锛岃褰曟暟:', records.length);
-      } else {
-        console.warn('鐢熶骇宸℃鏁版嵁涓虹┖鎴栨牸寮忎笉姝g‘:', res);
-        taskTableData.value = [];
-        uni.showToast({
-          title: '鏆傛棤宸℃浠诲姟鏁版嵁',
-          icon: 'none'
-        });
-      }
+  const loadMoreStatus = computed(() => {
+    if (loading.value) {
+      return "loading";
     }
-    // 鍏抽棴鍔犺浇鎻愮ず
-    closeToast()
-  }).catch(err => {
-    // 妫�鏌ョ粍浠舵槸鍚﹁繕瀛樺湪涓旇姹傛湭琚彇娑�
-    if (!isRequestCancelled) {
-      console.error('鑾峰彇鐢熶骇宸℃鏁版嵁澶辫触:', err);
-      taskTableData.value = [];
-      // 娣诲姞閿欒鎻愮ず
-      uni.showToast({
-        title: '鑾峰彇鏁版嵁澶辫触',
-        icon: 'error'
+    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;
+  });
+
+  // 杩斿洖涓婁竴椤�
+  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()
       })
-    }
-    // 鍏抽棴鍔犺浇鎻愮ず
-    closeToast()
-  })
-}
-
-
-// 涓婁紶
-const handleAdd = (row) => {
-  nextTick(() => {
-    // 妫�鏌ョ粍浠舵槸鍚﹁繕瀛樺湪
-    if (formDia.value && formDia.value.openDialog) {
-      formDia.value.openDialog(row)
-    } else {
-      console.error('涓婁紶缁勪欢寮曠敤涓嶅瓨鍦�')
-      uni.showToast({
-        title: '缁勪欢鏈噯澶囧ソ',
-        icon: 'error'
-      })
-    }
-  })
-}
-
-// 涓烘寚瀹氫换鍔″紑濮嬫壂鐮�
-const startScanForTask = async (task) => {
-  try {
-    // 璁板綍褰撳墠鎵弿鐨勪换鍔�
-    currentScanningTask.value = task
-    console.log('涓轰换鍔″紑濮嬫壂鐮�:', task.taskName)
-    
-    // 鏄剧ず鎵弿鐣岄潰
-    isScanning.value = true
-    
-    // 浣跨敤uniapp鐨勬壂鐮丄PI
-    uni.scanCode({
-      success: (res) => {
-        console.log('鎵爜鎴愬姛:', res)
-        handleScanSuccess(res)
-      },
-      fail: (err) => {
-        console.error('鎵爜澶辫触:', err)
-        uni.showToast({
-          title: '鎵爜澶辫触',
-          icon: 'error'
-        })
-        // 鍏抽棴鎵弿鐣岄潰
-        isScanning.value = false
-      },
-      complete: () => {
-        // 鎵爜瀹屾垚鍚庡叧闂壂鎻忕晫闈�
-        setTimeout(() => {
-          isScanning.value = false
-        }, 1000)
-      }
-    })
-  } catch (e) {
-    console.error('鍚姩鎵爜澶辫触:', e)
-    uni.showToast({
-      title: '鍚姩鎵爜澶辫触',
-      icon: 'error'
-    })
-    isScanning.value = false
-  }
-}
-
-// 鍋滄鎵爜
-const stopScan = () => {
-  isScanning.value = false
-  currentScanningTask.value = null
-}
-
-// 鎵爜鎴愬姛澶勭悊
-const handleScanSuccess = async (result) => {
-  try {
-    console.log('澶勭悊鎵爜缁撴灉:', result)
-    console.log('褰撳墠鍏宠仈浠诲姟:', currentScanningTask.value?.taskName)
-    
-    uni.showToast({
-      title: '璇嗗埆鎴愬姛',
-      icon: 'success'
-    })
-    
-    // 瑙f瀽浜岀淮鐮佹暟鎹�
-    let qrData
-    let deviceId = ''
-    
-    try {
-      qrData = JSON.parse(result.result)
-      console.log('瑙f瀽鐨勪簩缁寸爜鏁版嵁:', qrData)
-      deviceId = qrData.deviceId || qrData.qrCodeId
-    } catch (e) {
-      // 濡傛灉涓嶆槸JSON鏍煎紡锛屽皾璇曚粠URL涓彁鍙杁eviceId
-      const url = result.result
-      
-      if (url.includes('deviceId=')) {
-        // 浠嶶RL涓彁鍙杁eviceId
-        const match = url.match(/deviceId=(\d+)/)
-        if (match && match[1]) {
-          deviceId = match[1]
-        }
-      }
-      
-      qrData = { 
-        deviceName: deviceId ? `璁惧${deviceId}` : result.result, 
-        location: '',
-        qrCodeId: deviceId // 浣跨敤鎻愬彇鐨刣eviceId鎴栧師濮嬬粨鏋�
-      }
-    }
-    
-    // 濡傛灉鏈夎澶嘔D锛屽皾璇曚粠API鑾峰彇鐪熷疄鐨勮澶囧悕绉�
-    if (deviceId) {
-      try {
-        console.log('姝e湪鏌ヨ璁惧淇℃伅锛岃澶嘔D:', deviceId)
-        const response = await getLedgerById(deviceId)
-        console.log('璁惧淇℃伅鏌ヨ缁撴灉:', response)
-        
-        if (response.code === 200 && response.data) {
-          qrData.deviceName = response.data.deviceName || `璁惧${deviceId}`
-          qrData.location = response.data.storageLocation || ''
-          console.log('鑾峰彇鍒拌澶囧悕绉�:', qrData.deviceName)
-        } else {
-          console.warn('璁惧淇℃伅鏌ヨ澶辫触锛屼娇鐢ㄩ粯璁ゅ悕绉�')
-          qrData.deviceName = qrData.deviceName || `璁惧${deviceId}`
-        }
-      } catch (apiError) {
-        console.error('鏌ヨ璁惧淇℃伅澶辫触:', apiError)
-        // API璋冪敤澶辫触鏃朵娇鐢ㄩ粯璁ゅ悕绉�
-        qrData.deviceName = qrData.deviceName || `璁惧${deviceId}`
-      }
-    }
-    
-    // 纭繚鏁版嵁瀹屾暣鎬�
-    if (!qrData.deviceName) {
-      qrData.deviceName = result.result
-    }
-    if (!qrData.qrCodeId) {
-      qrData.qrCodeId = deviceId || result.result
-    }
-    
-    // 灏嗘壂鐮佹暟鎹笌浠诲姟鍏宠仈
-    if (currentScanningTask.value) {
-      // 鍏宠仈浠诲姟淇℃伅
-      const taskData = {
-        ...currentScanningTask.value,
-        qrCodeData: qrData
-      }
-      
-      // 鎵撳紑涓婁紶寮圭獥锛屼紶閫掑叧鑱斿悗鐨勪换鍔℃暟鎹�
-      nextTick(() => {
-        if (formDia.value && formDia.value.openDialog) {
-          formDia.value.openDialog(taskData)
-        } else {
-          console.error('涓婁紶缁勪欢寮曠敤涓嶅瓨鍦�')
+      .catch(err => {
+        // 妫�鏌ョ粍浠舵槸鍚﹁繕瀛樺湪涓旇姹傛湭琚彇娑�
+        if (!isRequestCancelled) {
+          taskTableData.value = [];
+          // 娣诲姞閿欒鎻愮ず
           uni.showToast({
-            title: '缁勪欢鏈噯澶囧ソ',
-            icon: 'error'
-          })
+            title: "鑾峰彇鏁版嵁澶辫触",
+            icon: "error",
+          });
         }
-      })
-    }
-  } catch (error) {
-    console.error('澶勭悊鎵爜缁撴灉澶辫触:', error)
-    uni.showToast({
-      title: error.message || '鏁版嵁瑙f瀽澶辫触',
-      icon: 'error'
-    })
-  } finally {
-    // 鍏抽棴鎵弿鐣岄潰
-    isScanning.value = false
-  }
-}
+        loading.value = false;
+        // 鍏抽棴鍔犺浇鎻愮ず
+        // closeToast()
+      });
+  };
 
-// 鎽勫儚澶撮敊璇鐞�
-const handleCameraError = (error) => {
-  console.error('鎽勫儚澶撮敊璇�:', error)
-  cameraError.value = '鎽勫儚澶磋闂け璐ワ紝璇锋鏌ユ潈闄愯缃�'
-}
+  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 => {
+    // 灏嗕换鍔′俊鎭紶閫掑埌涓婁紶椤甸潰
+    const taskData = encodeURIComponent(JSON.stringify(task));
+    uni.navigateTo({
+      url: `/pages/inspectionUpload/upload?taskInfo=${taskData}`,
+    });
+  };
+
+  // 鍥剧墖涓婁紶(鍙�夋嫨鍥剧墖涓婁紶鎴栬�呮槸鐩告満鎷嶇収)
+  const startUploadForTask = async (task, type) => {
+    // 鎵撳紑涓婁紶椤甸潰
+    openUploadDialog(task);
+  };
+
+  // 鏌ョ湅闄勪欢 - 璺宠浆鍒伴檮浠堕〉闈�
+  const viewAttachments = async task => {
+    const taskData = encodeURIComponent(JSON.stringify(task));
+    uni.navigateTo({
+      url: `/pages/inspectionUpload/attachment?taskInfo=${taskData}`,
+    });
+  };
+
+  // 鍒ゆ柇鏄惁涓哄浘鐗囨枃浠�
+  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 = config.fileUrl;
+
+  // 灏嗗悗绔繑鍥炵殑鏂囦欢鍦板潃瑙勮寖鎴愬彲璁块棶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",
+    });
+  };
 </script>
 
-<style scoped lang="scss">
-// 瀵煎叆閿�鍞ā鍧楀叕鍏辨牱寮�
-@import '@/styles/sales-common.scss';
-
-// 椤甸潰瀹瑰櫒鏍峰紡
-.inspection-upload-page {
-  min-height: 100vh;
-  background: #f8f9fa;
-  position: relative;
-}
-
-// 鍒楄〃瀹瑰櫒鏍峰紡
-.table-section {
-  padding: 20px;
-}
-
-// 浠诲姟鍒楄〃鏍峰紡 - 浣跨敤閿�鍞彴璐︾殑鏍峰紡瑙勮寖
-.task-list {
-  .task-item {
-    background: #ffffff;
-    border-radius: 12px;
-    margin-bottom: 16px;
-    overflow: hidden;
-    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
-    padding: 0 16px;
-    
-    &:active {
-      transform: scale(0.98);
-      box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
-    }
+<style scoped>
+  .inspection-upload-page {
+    min-height: 100vh;
+    background-color: #f5f5f5;
   }
-}
 
-// 椤圭洰澶撮儴鏍峰紡
-.task-header {
-  padding: 16px 0;
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  margin-bottom: 0;
-}
+  .table-section {
+    padding: 15px;
+  }
 
-.task-info {
-  flex: 1;
-}
+  .task-list {
+    display: flex;
+    flex-direction: column;
+    gap: 12px;
+  }
 
-.task-name {
-  font-size: 14px;
-  color: #333;
-  font-weight: 500;
-  margin-bottom: 0;
-  line-height: 1.4;
-}
+  .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-location {
-  font-size: 12px;
-  color: #666;
-  margin-top: 4px;
-}
+  .task-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: flex-start;
+    margin-bottom: 12px;
+  }
 
-// 浠诲姟鎿嶄綔鎸夐挳鏍峰紡
-.task-actions {
-  display: flex;
-  align-items: center;
-  gap: 8px;
-  margin-left: 0;
-}
+  .task-info {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    gap: 4px;
+  }
 
-// 浠诲姟璇︽儏鏍峰紡 - 浣跨敤閿�鍞彴璐︾殑璇︽儏琛屾牱寮�
-.task-details {
-  padding: 16px 0;
-  
+  .task-name {
+    font-size: 16px;
+    font-weight: 600;
+    color: #333;
+  }
+
+  .task-location {
+    font-size: 14px;
+    color: #666;
+  }
+
+  .task-actions {
+    display: flex;
+    gap: 8px;
+  }
+
+  .task-details {
+    display: flex;
+    flex-direction: column;
+    gap: 6px;
+  }
+
   .detail-item {
     display: flex;
-    align-items: flex-end;
     justify-content: space-between;
-    margin-bottom: 8px;
-    
-    &:last-child {
-      margin-bottom: 0;
-    }
-    
-    .detail-label {
-      font-size: 12px;
-      color: #777777;
-      min-width: 60px;
-      flex-shrink: 0;
-    }
-    
-    .detail-value {
-      font-size: 12px;
-      color: #000000;
-      text-align: right;
-      flex: 1;
-      margin-left: 16px;
-      line-height: 1.4;
-    }
+    align-items: center;
   }
-}
 
-// 鏃犳暟鎹彁绀烘牱寮� - 浣跨敤閿�鍞彴璐︾殑鏍峰紡
-.no-data {
-  padding: 40px 0;
-  text-align: center;
-  color: #999;
-  background: none;
-  margin: 0;
-}
+  .detail-label {
+    font-size: 12px;
+    color: #999;
+  }
 
-.no-data text {
-  font-size: 14px;
-  color: #999;
-}
+  .detail-value {
+    font-size: 12px;
+    color: #666;
+    font-weight: 500;
+  }
 
-/* 鎵爜寮圭獥鏍峰紡 */
-.qr-scan-overlay {
-  position: fixed;
-  top: 0;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background-color: rgba(0, 0, 0, 0.8);
-  z-index: 9999;
-  display: flex;
-  flex-direction: column;
-  justify-content: center;
-  align-items: center;
-  padding: 20px;
-}
+  .no-data {
+    text-align: center;
+    padding: 40px 20px;
+    color: #999;
+    font-size: 14px;
+  }
 
-.qr-scan-container {
-  width: 100%;
-  max-width: 400px;
-  background-color: #000;
-  border-radius: 12px;
-  overflow: hidden;
-}
+  /* 鎵爜寮圭獥鏍峰紡 */
+  .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;
+  }
 
-.scan-header {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  padding: 15px;
-  background-color: rgba(0, 0, 0, 0.7);
-}
+  .qr-scan-container {
+    width: 90vw;
+    max-width: 400px;
+    background: #fff;
+    border-radius: 12px;
+    padding: 20px;
+    position: relative;
+  }
 
-.scan-title {
-  font-size: 18px;
-  font-weight: 600;
-  color: #fff;
-}
+  .scan-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 15px;
+  }
 
-.qr-camera {
-  width: 100%;
-  height: 400px;
-}
+  .scan-title {
+    font-size: 18px;
+    font-weight: 600;
+    color: #333;
+  }
 
-.scan-frame-wrapper {
-  position: relative;
-  width: 100%;
-  height: 300px;
-}
+  .qr-camera {
+    width: 100%;
+    height: 300px;
+    border-radius: 8px;
+    overflow: hidden;
+    margin-bottom: 15px;
+  }
 
-.scan-frame {
-  position: absolute;
-  top: 50%;
-  left: 50%;
-  transform: translate(-50%, -50%);
-  width: 80%;
-  height: 80%;
-  border: 3px solid #1890ff;
-  border-radius: 8px;
-  box-shadow: 0 0 20px rgba(24, 144, 255, 0.3);
-  animation: pulse 2s infinite;
-}
+  .scan-frame-wrapper {
+    position: relative;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+  }
 
-.scan-tip {
-  position: absolute;
-  bottom: 10px;
-  left: 50%;
-  transform: translateX(-50%);
-  color: #fff;
-  font-size: 14px;
-  text-align: center;
-  background-color: rgba(0, 0, 0, 0.6);
-  padding: 5px 15px;
-  border-radius: 20px;
-}
+  .scan-frame {
+    width: 200px;
+    height: 200px;
+    border: 2px solid #409eff;
+    border-radius: 8px;
+    position: relative;
+  }
 
-@keyframes pulse {
-  0% { opacity: 0.8; }
-  50% { opacity: 0.4; }
-  100% { opacity: 0.8; }
-}
+  .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::after {
+    bottom: -2px;
+    right: -2px;
+    border-left: none;
+    border-top: none;
+  }
+
+  .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-container {
+    width: 100%;
+    max-width: 500px;
+    max-height: 80vh;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+
+  /* 瑙嗛棰勮寮圭獥鏍峰紡 */
+  .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-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;
+  }
+
+  .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);
+  }
+
+  .video-modal-body {
+    position: relative;
+    background: #000;
+  }
+
+  .video-player {
+    width: 100%;
+    height: auto;
+    max-height: 60vh;
+    display: block;
+  }
 </style>
\ No newline at end of file

--
Gitblit v1.9.3