From 47bae1f938f915206e3934ea960aff975e5738c9 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期五, 12 六月 2026 16:09:49 +0800
Subject: [PATCH] feat(teachingDemo): 新增工艺路线与BOM教学演示模块

---
 src/views/collaborativeApproval/sealManagement/index.vue |  174 +++++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 135 insertions(+), 39 deletions(-)

diff --git a/src/views/collaborativeApproval/sealManagement/index.vue b/src/views/collaborativeApproval/sealManagement/index.vue
index c0d13f2..a06f6d5 100644
--- a/src/views/collaborativeApproval/sealManagement/index.vue
+++ b/src/views/collaborativeApproval/sealManagement/index.vue
@@ -7,7 +7,6 @@
         </div>
       </template>
 
-      
    <!-- 鐢ㄥ嵃鐢宠绠$悊 -->
         <div class="tab-content">
             <el-row :gutter="20" class="mb-20 ">
@@ -45,7 +44,7 @@
               :isShowPagination="true"
               @pagination="paginationChange"
             />
-        </div> 
+        </div>
     </el-card>
 
     <!-- 鐢ㄥ嵃鐢宠瀵硅瘽妗� -->
@@ -87,10 +86,18 @@
         </el-form-item>
         <el-form-item label="绱ф�ョ▼搴�" prop="urgency">
           <el-radio-group v-model="sealForm.urgency">
-            <el-radio label="normal">鏅��</el-radio>
-            <el-radio label="urgent">绱ф��</el-radio>
-            <el-radio label="very-urgent">鐗规��</el-radio>
+            <el-radio value="normal">鏅��</el-radio>
+            <el-radio value="urgent">绱ф��</el-radio>
+            <el-radio value="very-urgent">鐗规��</el-radio>
           </el-radio-group>
+        </el-form-item>
+        <el-form-item label="闄勪欢涓婁紶">
+          <AttachmentUploadFile
+            v-model:fileList="sealForm.storageBlobDTOs"
+            :limit="10"
+            :fileSize="50"
+            buttonText="鐐瑰嚮涓婁紶闄勪欢"
+          />
         </el-form-item>
       </el-form>
     </FormDialog>
@@ -119,8 +126,27 @@
           </el-descriptions-item>
           <el-descriptions-item label="鐢宠鍘熷洜" :span="2">{{ currentSealDetail.reason }}</el-descriptions-item>
         </el-descriptions>
+        <!-- 闄勪欢鍒楄〃 -->
+        <div v-if="currentSealDetail.storageBlobVOList?.length || currentSealDetail.storageBlobDTOs?.length" class="attachment-section">
+          <div class="attachment-title">闄勪欢鍒楄〃锛�</div>
+          <el-table :data="currentSealDetail.storageBlobVOList || currentSealDetail.storageBlobDTOs" border class="attachment-table">
+            <el-table-column label="闄勪欢鍚嶇О" show-overflow-tooltip>
+              <template #default="scope">
+                {{ scope.row.originalFilename || scope.row.name || scope.row.fileName || '鏈懡鍚嶆枃浠�' }}
+              </template>
+            </el-table-column>
+            <el-table-column fixed="right" label="鎿嶄綔" width="150" align="center">
+              <template #default="scope">
+                <el-button link type="primary" size="small" @click="previewFile(scope.row)">棰勮</el-button>
+                <el-button link type="primary" size="small" @click="downloadFile(scope.row)">涓嬭浇</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
       </div>
     </FormDialog>
+    <!-- 鏂囦欢棰勮缁勪欢 -->
+    <FilePreview ref="filePreviewRef" />
 
   </div>
 </template>
@@ -134,6 +160,9 @@
 import useUserStore from '@/store/modules/user'
 import FormDialog from '@/components/Dialog/FormDialog.vue'
 import PIMTable from '@/components/PIMTable/PIMTable.vue'
+import AttachmentUploadFile from '@/components/AttachmentUpload/file/index.vue'
+import FilePreview from '@/components/filePreview/index.vue'
+import download from '@/plugins/download.js'
 
 // 鍝嶅簲寮忔暟鎹�
 // 鐢ㄥ嵃鐢宠鐩稿叧
@@ -143,16 +172,19 @@
 const tableLoading = ref(false)
 const showSealDetailDialog = ref(false)
 const currentSealDetail = ref(null)
+const filePreviewRef = ref(null)
 const sealFormRef = ref()
 const userList = ref([])
 const sealForm = reactive({
+  id: null,
   applicationNum: '',
   title: '',
   sealType: '',
   reason: '',
   approveUserId: '',
   urgency: 'normal',
-  status: 'pending'
+  status: 'pending',
+  storageBlobDTOs: []
 })
 
 const sealRules = {
@@ -209,9 +241,9 @@
 
 // 鐢ㄥ嵃鐢宠琛ㄦ牸鍒楅厤缃紙闇�鍦� getStatusText/getSealTypeText 绛変箣鍚庡畾涔夛級
 const sealTableColumn = ref([
-  { label: '鐢宠缂栧彿', prop: 'applicationNum',},
+  { label: '鐢宠缂栧彿', prop: 'applicationNum' },
   { label: '鐢宠鏍囬', prop: 'title', showOverflowTooltip: true },
-  { label: '鐢宠浜�', prop: 'createUserName', },
+  { label: '鐢宠浜�', prop: 'createUserName' },
   { label: '鎵�灞為儴闂�', prop: 'department', width: 150 },
   {
     label: '鐢ㄥ嵃绫诲瀷',
@@ -229,34 +261,38 @@
     formatData: (v) => getStatusText(v),
     formatType: (v) => getStatusType(v)
   },
+  { label: '瀹℃壒浜�', prop: 'approveUserName', width: 100 },
   {
     dataType: 'action',
     label: '鎿嶄綔',
-    width: 200,
+    width: 250,
     fixed: 'right',
     align: 'center',
     operation: [
-      { name: '鏌ョ湅', clickFun: (row) => viewSealDetail(row) },
       {
         name: '瀹℃壒',
         clickFun: (row) => approveSeal(row),
-        showHide: (row) => row.status === 'pending'
+        showHide: (row) => row.status === 'pending' && Number(userStore.id) === row.approveUserId
       },
       {
         name: '鎷掔粷',
         clickFun: (row) => rejectSeal(row),
-        showHide: (row) => row.status === 'pending'
-      }
+        showHide: (row) => row.status === 'pending' && Number(userStore.id) === row.approveUserId
+      },
+      {
+        name: '閲嶆柊鐢宠',
+        clickFun: (row) => reapplySeal(row),
+        showHide: (row) => row.status === 'rejected' && Number(userStore.id) === row.createUser
+      },
+      { name: '璇︽儏', clickFun: (row) => viewSealDetail(row) }
     ]
   }
 ])
 
 // 鎼滅储鍗扮珷鐢宠
 const searchSealApplications = () => {
-  page.current=1
+  page.current = 1
   getSealApplicationList()
-
-  // ElMessage.success('鎼滅储瀹屾垚')
 }
 // 閲嶇疆鍗扮珷鐢宠鎼滅储
 const resetSealSearch = () => {
@@ -265,43 +301,66 @@
   sealSearchForm.applicationNum = ''
   searchSealApplications()
 }
+
+// 閲嶆柊鐢宠鐢ㄥ嵃
+const reapplySeal = (row) => {
+  // 棰勫~琛ㄥ崟鏁版嵁
+  Object.assign(sealForm, {
+    id: row.id,
+    applicationNum: row.applicationNum,
+    title: row.title,
+    sealType: row.sealType,
+    reason: row.reason,
+    approveUserId: row.approveUserId,
+    urgency: row.urgency || 'normal',
+    status: 'pending',
+    storageBlobDTOs: row.storageBlobVOList || []
+  })
+  showSealApplyDialog.value = true
+}
+
 // 鎻愪氦鐢ㄥ嵃鐢宠
 const submitSealApplication = async () => {
   try {
     await sealFormRef.value.validate()
-    addSealApplication(sealForm).then(res => {
-      if(res.code == 200){
-        ElMessage.success('鐢宠鎻愪氦鎴愬姛')
+    const request = sealForm.id ? updateSealApplication : addSealApplication
+    request(sealForm).then(res => {
+      if (res.code == 200) {
+        ElMessage.success(sealForm.id ? '閲嶆柊鐢宠鎴愬姛' : '鐢宠鎻愪氦鎴愬姛')
         closeSealApplyDialog()
         getSealApplicationList()
         Object.assign(sealForm, {
-        applicationNum: '',
-        title: '',
-        sealType: '',
-        reason: '',
-        approveUserId: '',
-        urgency: 'normal',
-        status: 'pending'
-      })
+          id: null,
+          applicationNum: '',
+          title: '',
+          sealType: '',
+          reason: '',
+          approveUserId: '',
+          urgency: 'normal',
+          status: 'pending',
+          storageBlobDTOs: []
+        })
       }
     }).catch(err => {
       console.log(err.msg)
     })
-  
   } catch (error) {
   }
 }
+
 // 鍏抽棴鐢ㄥ嵃鐢宠瀵硅瘽妗�
 const closeSealApplyDialog = () => {
   // 娓呯┖琛ㄥ崟鏁版嵁
   Object.assign(sealForm, {
+    id: null,
     applicationNum: '',
     title: '',
     sealType: '',
     reason: '',
     approveUserId: '',
     urgency: 'normal',
-    status: 'pending'
+    status: 'pending',
+    storageBlobDTOs: []
   })
   // 娓呴櫎琛ㄥ崟楠岃瘉鐘舵��
   if (sealFormRef.value) {
@@ -319,6 +378,27 @@
   currentSealDetail.value = row
   showSealDetailDialog.value = true
 }
+
+// 棰勮鏂囦欢
+const previewFile = (row) => {
+  const url = row.previewURL || row.previewUrl || row.url
+  if (url && filePreviewRef.value) {
+    filePreviewRef.value.open(url)
+  } else {
+    ElMessage.warning('鏂囦欢鍦板潃鏃犳晥锛屾棤娉曢瑙�')
+  }
+}
+
+// 涓嬭浇鏂囦欢
+const downloadFile = (row) => {
+  const url = row.downloadURL || row.downloadUrl || row.url
+  if (url) {
+    const filename = row.originalFilename || row.name || row.fileName || 'download'
+    download.byUrl(url, filename)
+  } else {
+    ElMessage.warning('鏂囦欢鍦板潃鏃犳晥锛屾棤娉曚笅杞�')
+  }
+}
 // 瀹℃壒鐢ㄥ嵃鐢宠
 const approveSeal = (row) => {
   ElMessageBox.confirm('纭閫氳繃璇ョ敤鍗扮敵璇凤紵', '鎻愮ず', {
@@ -328,7 +408,7 @@
   }).then(() => {
     row.status = 'approved'
     updateSealApplication(row).then(res => {
-      if(res.code == 200){
+      if (res.code == 200) {
         ElMessage.success('瀹℃壒閫氳繃')
         getSealApplicationList()
       }
@@ -344,8 +424,9 @@
     inputErrorMessage: '鎷掔粷鍘熷洜涓嶈兘涓虹┖'
   }).then(({ value }) => {
     row.status = 'rejected'
+    row.reason = value
     updateSealApplication(row).then(res => {
-      if(res.code == 200){
+      if (res.code == 200) {
         ElMessage.success('宸叉嫆缁濈敵璇�')
         getSealApplicationList()
       }
@@ -363,13 +444,13 @@
 const getSealApplicationList = async () => {
   tableLoading.value = true
   listSealApplication(page, sealSearchForm)
-  .then(res => {
-    sealApplications.value = res.data.records
-    page.total = res.data.total
-    tableLoading.value = false
-  }).catch(err => {
-    tableLoading.value = false
-  })
+    .then(res => {
+      sealApplications.value = res.data.records
+      page.total = res.data.total
+      tableLoading.value = false
+    }).catch(err => {
+      tableLoading.value = false
+    })
 }
 // 鍒嗛〉鍙樺寲澶勭悊
 const paginationChange = (obj) => {
@@ -421,4 +502,19 @@
 .ml-10 {
   margin-left: 10px;
 }
-</style>
+
+.attachment-section {
+  margin-top: 20px;
+}
+
+.attachment-title {
+  font-size: 14px;
+  color: #606266;
+  margin-bottom: 10px;
+  font-weight: 500;
+}
+
+.attachment-table {
+  border-radius: 4px;
+}
+</style>
\ No newline at end of file

--
Gitblit v1.9.3