From 207c564c2b8d46fd86160c4f6583c2fc9d4a4e5c Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 21 四月 2026 10:44:45 +0800
Subject: [PATCH] 湟水峡app 1.协同审批功能删减

---
 src/pages/cooperativeOffice/collaborativeApproval/approve.vue                |  247 +++++++
 src/pages/index.vue                                                          |    6 
 src/pages/cooperativeOffice/collaborativeApproval/indexNew.vue               |  382 +++++++++++
 src/pages.json                                                               |    7 
 src/pages/cooperativeOffice/collaborativeApproval/index.vue                  |   44 +
 src/pages/works.vue                                                          |   52 
 src/pages/cooperativeOffice/collaborativeApproval/components/infoFormDia.vue |  504 ++++++++++++++
 src/pages/indexItem.vue                                                      |   14 
 src/api/procurementManagement/procurementLedger.js                           |    8 
 src/pages/cooperativeOffice/collaborativeApproval/detail.vue                 |  214 +++++-
 src/config.js                                                                |    2 
 src/pages/cooperativeOffice/collaborativeApproval/components/approvalDia.vue |  535 +++++++++++++++
 12 files changed, 1,920 insertions(+), 95 deletions(-)

diff --git a/src/api/procurementManagement/procurementLedger.js b/src/api/procurementManagement/procurementLedger.js
index 0a05d2e..44e8df6 100644
--- a/src/api/procurementManagement/procurementLedger.js
+++ b/src/api/procurementManagement/procurementLedger.js
@@ -78,4 +78,12 @@
         method: 'get',
         params: query,
     })
+}
+// 鏌ヨ閿�鍞鎯咃紙鐢ㄤ簬閿�鍞鎵癸級
+export function getSalesByCode(query) {
+  return request({
+    url: "/purchase/ledger/getSalesByCode",
+    method: "get",
+    params: query,
+  });
 }
\ No newline at end of file
diff --git a/src/config.js b/src/config.js
index 42a7174..666a478 100644
--- a/src/config.js
+++ b/src/config.js
@@ -1,6 +1,6 @@
 // 搴旂敤鍏ㄥ眬閰嶇疆
 const config = {
-  baseUrl: "http://1.15.17.182:9003",
+  baseUrl: "http://192.168.0.244:7003",
   fileUrl: "http://1.15.17.182:9002",
   // 搴旂敤淇℃伅
   appInfo: {
diff --git a/src/pages.json b/src/pages.json
index e52db8a..95df8f2 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -423,6 +423,13 @@
       }
     },
     {
+      "path": "pages/cooperativeOffice/collaborativeApproval/index",
+      "style": {
+        "navigationBarTitleText": "鍗忓悓瀹℃壒",
+        "navigationStyle": "custom"
+      }
+    },
+    {
       "path": "pages/managementMeetings/meetingSettings/index",
       "style": {
         "navigationBarTitleText": "浼氳璁剧疆",
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/approve.vue b/src/pages/cooperativeOffice/collaborativeApproval/approve.vue
index aaad83e..c17236e 100644
--- a/src/pages/cooperativeOffice/collaborativeApproval/approve.vue
+++ b/src/pages/cooperativeOffice/collaborativeApproval/approve.vue
@@ -9,6 +9,11 @@
         <text class="info-title">鐢宠淇℃伅</text>
       </view>
       <view class="info-content">
+        <!-- 瀹℃壒鏍囬锛堜粎 approveType=9 鎴� 10 鏄剧ず锛� -->
+        <view v-if="approvalData.approveType === 9 || approvalData.approveType === 10" class="info-row">
+          <text class="info-label">瀹℃壒鏍囬</text>
+          <text class="info-value">{{ approvalData.approveTitle || '-' }}</text>
+        </view>
         <view class="info-row">
           <text class="info-label">鐢宠浜�</text>
           <text class="info-value">{{ approvalData.approveUserName }}</text>
@@ -18,14 +23,14 @@
           <text class="info-value">{{ approvalData.approveDeptName }}</text>
         </view>
         <view class="info-row">
-          <text class="info-label">鐢宠浜嬬敱</text>
+          <text class="info-label">{{ getApproveReasonLabel() }}</text>
           <text class="info-value">{{ approvalData.approveReason }}</text>
         </view>
         <view class="info-row">
           <text class="info-label">鐢宠鏃ユ湡</text>
           <text class="info-value">{{ approvalData.approveTime }}</text>
         </view>
-        
+
         <!-- approveType=2 璇峰亣鐩稿叧瀛楁 -->
         <template v-if="approvalData.approveType === 2">
           <view class="info-row">
@@ -37,19 +42,89 @@
             <text class="info-value">{{ approvalData.endDate || '-' }}</text>
           </view>
         </template>
-        
+
         <!-- approveType=3 鍑哄樊鐩稿叧瀛楁 -->
         <view v-if="approvalData.approveType === 3" class="info-row">
           <text class="info-label">鍑哄樊鍦扮偣</text>
           <text class="info-value">{{ approvalData.location || '-' }}</text>
         </view>
-        
+
         <!-- approveType=4 鎶ラ攢鐩稿叧瀛楁 -->
         <view v-if="approvalData.approveType === 4" class="info-row">
           <text class="info-label">鎶ラ攢閲戦</text>
           <text class="info-value">{{ approvalData.price ? `楼${approvalData.price}` : '-' }}</text>
         </view>
       </view>
+    </view>
+
+    <!-- 閿�鍞鎯咃紙approveType=9锛� -->
+    <view v-if="isSalesApproval && currentSales.salesContractNo" class="sales-detail">
+      <view class="detail-header">
+        <text class="detail-title">閿�鍞鎯�</text>
+      </view>
+      <view class="detail-content">
+        <view class="detail-row">
+          <text class="detail-label">閿�鍞悎鍚屽彿</text>
+          <text class="detail-value">{{ currentSales.salesContractNo }}</text>
+        </view>
+        <view class="detail-row">
+          <text class="detail-label">瀹㈡埛鍚嶇О</text>
+          <text class="detail-value">{{ currentSales.customerName }}</text>
+        </view>
+        <view class="detail-row">
+          <text class="detail-label">涓氬姟鍛�</text>
+          <text class="detail-value">{{ currentSales.salesman }}</text>
+        </view>
+        <view class="detail-row">
+          <text class="detail-label">褰曞叆浜�</text>
+          <text class="detail-value">{{ currentSales.entryPersonName }}</text>
+        </view>
+        <view class="detail-row">
+          <text class="detail-label">绛捐鏃ユ湡</text>
+          <text class="detail-value">{{ currentSales.executionDate }}</text>
+        </view>
+        <view class="detail-row">
+          <text class="detail-label">浠樻鏂瑰紡</text>
+          <text class="detail-value">{{ currentSales.paymentMethod }}</text>
+        </view>
+        <view class="detail-row total-row">
+          <text class="detail-label">鍚堝悓閲戦</text>
+          <text class="detail-value highlight">楼{{ calculateSalesTotalAmount() }}</text>
+        </view>
+        <!-- 浜у搧鏄庣粏 -->
+        <view v-if="currentSales.productData && currentSales.productData.length > 0" class="product-list">
+          <view class="product-header">
+            <text class="product-title">浜у搧鏄庣粏</text>
+          </view>
+          <view v-for="(product, pIndex) in currentSales.productData" :key="pIndex" class="product-item">
+            <view class="product-row">
+              <text class="product-label">浜у搧鍚嶇О</text>
+              <text class="product-value">{{ product.productCategory }}</text>
+            </view>
+            <view class="product-row">
+              <text class="product-label">瑙勬牸鍨嬪彿</text>
+              <text class="product-value">{{ product.specificationModel }}</text>
+            </view>
+            <view class="product-row">
+              <text class="product-label">鏁伴噺</text>
+              <text class="product-value">{{ product.quantity }}</text>
+            </view>
+            <view class="product-row">
+              <text class="product-label">鍚◣鍗曚环</text>
+              <text class="product-value">楼{{ Number(product.taxInclusiveUnitPrice || 0).toFixed(2) }}</text>
+            </view>
+            <view class="product-row">
+              <text class="product-label">鍚◣鎬讳环</text>
+              <text class="product-value">楼{{ Number(product.taxInclusiveTotalPrice || 0).toFixed(2) }}</text>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 鍔犺浇鐘舵�� -->
+    <view v-if="salesLoading" class="loading-state">
+      <text>鍔犺浇閿�鍞鎯呬腑...</text>
     </view>
 
     <!-- 瀹℃壒娴佺▼ -->
@@ -128,7 +203,9 @@
 <script setup>
 import { ref, onMounted, computed } from 'vue'
 import { approveProcessGetInfo, approveProcessDetails, updateApproveNode } from '@/api/collaborativeApproval/approvalProcess'
+import { getSalesByCode } from '@/api/procurementManagement/procurementLedger.js'
 import useUserStore from '@/store/modules/user'
+
 const showToast = (message) => {
 	uni.showToast({
 		title: message,
@@ -142,14 +219,44 @@
 const approvalSteps = ref([])
 const approvalOpinion = ref('')
 const approveId = ref('')
+const approveType = ref(0)
+const isSalesApproval = computed(() => Number(approveType.value) === 9)
+const currentSales = ref({})
+const salesLoading = ref(false)
 
 // 浠庤鎯呮帴鍙e瓧娈靛榻� canApprove锛氫粎褰撴湁 isShen 鐨勮妭鐐规椂鍙鎵�
 const canApprove = computed(() => {
   return approvalSteps.value.some(step => step.isShen === true)
 })
 
+// 鑾峰彇瀹℃壒浜嬬敱鏍囩
+const getApproveReasonLabel = () => {
+  const type = Number(approveType.value)
+  if (type === 5) {
+    return '閲囪喘鍚堝悓鍙�'
+  } else if (type === 9) {
+    return '閿�鍞悎鍚屽彿'
+  } else if (type === 10) {
+    return '瀹℃壒浜嬬敱'
+  }
+  return '鐢宠浜嬬敱'
+}
+
+// 璁$畻閿�鍞悎鍚岄噾棰濓紙浜у搧鏄庣粏鍚◣鎬讳环涔嬪拰锛�
+const calculateSalesTotalAmount = () => {
+  const products = currentSales.value?.productData || []
+  const total = products.reduce((sum, item) => {
+    return sum + Number(item.taxInclusiveTotalPrice || 0)
+  }, 0)
+  return total.toFixed(2)
+}
+
 onMounted(() => {
   approveId.value = uni.getStorageSync('approveId')
+  const storedApproveType = uni.getStorageSync('approveType')
+  if (storedApproveType) {
+    approveType.value = Number(storedApproveType)
+  }
   if (approveId.value) {
     loadApprovalData()
   }
@@ -159,6 +266,24 @@
   // 鍩烘湰鐢宠淇℃伅
   approveProcessGetInfo({ id: approveId.value }).then(res => {
     approvalData.value = res.data || {}
+    // 璁剧疆瀹℃壒绫诲瀷
+    if (res.data && res.data.approveType) {
+      approveType.value = Number(res.data.approveType)
+    }
+    // 閿�鍞鎵癸細鐢ㄥ鎵逛簨鐢卞瓧娈垫壙杞界殑"閿�鍞悎鍚屽彿"鍘绘煡閿�鍞鎯�
+    if (isSalesApproval.value) {
+      const salesContractNo = res.data?.approveReason
+      if (salesContractNo) {
+        salesLoading.value = true
+        getSalesByCode({ salesContractNo }).then(salesRes => {
+          currentSales.value = salesRes || {}
+        }).catch((err) => {
+          console.error('鏌ヨ閿�鍞鎯呭け璐�:', err)
+        }).finally(() => {
+          salesLoading.value = false
+        })
+      }
+    }
   })
   // 瀹℃壒鑺傜偣璇︽儏
   approveProcessDetails(approveId.value).then(res => {
@@ -505,9 +630,117 @@
   }
   
   /* 閫傞厤u-button鏍峰紡 */
-  :deep(.u-button) {
-    border-radius: 6px;
-  }
+:deep(.u-button) {
+  border-radius: 6px;
+}
+
+/* 閿�鍞鎯呮牱寮� */
+.sales-detail {
+  background: #fff;
+  margin: 16px;
+  border-radius: 12px;
+  overflow: hidden;
+}
+
+.detail-header {
+  padding: 16px;
+  border-bottom: 1px solid #f0f0f0;
+  background: #f8f9fa;
+}
+
+.detail-title {
+  font-size: 16px;
+  font-weight: 600;
+  color: #333;
+}
+
+.detail-content {
+  padding: 16px;
+}
+
+.detail-row {
+  display: flex;
+  align-items: center;
+  margin-bottom: 12px;
+}
+
+.detail-label {
+  font-size: 14px;
+  color: #666;
+  width: 80px;
+  flex-shrink: 0;
+}
+
+.detail-value {
+  font-size: 14px;
+  color: #333;
+  flex: 1;
+}
+
+.detail-value.highlight {
+  font-size: 18px;
+  color: #e6a23c;
+  font-weight: bold;
+}
+
+.total-row {
+  padding-top: 8px;
+  border-top: 1px solid #f0f0f0;
+  margin-top: 8px;
+}
+
+.product-list {
+  margin-top: 16px;
+  padding-top: 16px;
+  border-top: 1px solid #f0f0f0;
+}
+
+.product-header {
+  margin-bottom: 12px;
+}
+
+.product-title {
+  font-size: 15px;
+  font-weight: 600;
+  color: #333;
+}
+
+.product-item {
+  background: #f8f9fa;
+  border-radius: 8px;
+  padding: 12px;
+  margin-bottom: 8px;
+}
+
+.product-row {
+  display: flex;
+  align-items: center;
+  margin-bottom: 6px;
+}
+
+.product-row:last-child {
+  margin-bottom: 0;
+}
+
+.product-label {
+  font-size: 13px;
+  color: #666;
+  width: 70px;
+  flex-shrink: 0;
+}
+
+.product-value {
+  font-size: 13px;
+  color: #333;
+  flex: 1;
+}
+
+.loading-state {
+  text-align: center;
+  padding: 16px;
+  color: #999;
+  font-size: 14px;
+}
 
 @keyframes pulse {
   0% {
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/components/approvalDia.vue b/src/pages/cooperativeOffice/collaborativeApproval/components/approvalDia.vue
new file mode 100644
index 0000000..4133c2a
--- /dev/null
+++ b/src/pages/cooperativeOffice/collaborativeApproval/components/approvalDia.vue
@@ -0,0 +1,535 @@
+<template>
+  <div>
+    <el-dialog
+      v-model="dialogFormVisible"
+      :title="operationType === 'add' ? '鏂板瀹℃壒娴佺▼' : '缂栬緫瀹℃壒娴佺▼'"
+      width="700px"
+      @close="closeDia"
+    >
+			<el-form :model="form" label-width="140px" label-position="top" ref="formRef">
+				<el-row>
+					<el-col :span="24">
+						<el-form-item label="娴佺▼缂栧彿锛�" prop="approveId">
+							<el-input v-model="form.approveId" placeholder="鑷姩缂栧彿" clearable disabled/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row>
+					<el-col :span="24">
+						<el-form-item label="鐢宠閮ㄩ棬锛�" prop="approveDeptId">
+							<el-select
+								disabled
+								v-model="form.approveDeptId"
+								placeholder="閫夋嫨閮ㄩ棬"
+							>
+								<el-option
+									v-for="user in productOptions"
+									:key="user.deptId"
+									:label="user.deptName"
+									:value="user.deptId"
+								/>
+							</el-select>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<!-- 瀹℃壒鏍囬锛堜粎鑷敱鍗忓悓瀹℃壒鏄剧ず锛� -->
+				<el-row v-if="isFreeApproval">
+					<el-col :span="24">
+						<el-form-item label="瀹℃壒鏍囬锛�" prop="approveTitle">
+							<el-input v-model="form.approveTitle" placeholder="璇疯緭鍏�" clearable disabled/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row v-if="!isQuotationApproval && !isPurchaseApproval">
+					<el-col :span="24">
+						<el-form-item :label="props.approveType == 5 ? '閲囪喘鍚堝悓鍙凤細' : '瀹℃壒浜嬬敱锛�'" prop="approveReason">
+							<el-input v-model="form.approveReason" placeholder="璇疯緭鍏�" clearable type="textarea" disabled/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<!-- 瀹℃壒浜洪�夋嫨锛堝姩鎬佽妭鐐癸級 -->
+				<el-row :gutter="30">
+					<el-col :span="12">
+						<el-form-item label="鐢宠浜猴細" prop="approveUser">
+							<el-select
+								v-model="form.approveUser"
+								placeholder="閫夋嫨浜哄憳"
+								disabled
+							>
+								<el-option
+									v-for="user in userList"
+									:key="user.userId"
+									:label="user.nickName"
+									:value="user.userId"
+								/>
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="鐢宠鏃ユ湡锛�" prop="approveTime">
+							<el-date-picker
+								v-model="form.approveTime"
+								type="date"
+								placeholder="璇烽�夋嫨鏃ユ湡"
+								value-format="YYYY-MM-DD"
+								format="YYYY-MM-DD"
+								clearable
+								style="width: 100%"
+								disabled
+							/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+			</el-form>
+
+      <!-- 鎶ヤ环瀹℃壒锛氬睍绀烘姤浠疯鎯咃紙澶嶇敤閿�鍞姤浠�"鏌ョ湅璇︽儏瀵硅瘽妗�"鍐呭缁撴瀯锛� -->
+      <div v-if="isQuotationApproval" style="margin: 10px 0 18px;">
+        <el-divider content-position="left">鎶ヤ环璇︽儏</el-divider>
+        <el-skeleton :loading="quotationLoading" animated>
+          <template #template>
+            <el-skeleton-item variant="h3" style="width: 30%" />
+            <el-skeleton-item variant="text" style="width: 100%" />
+            <el-skeleton-item variant="text" style="width: 100%" />
+          </template>
+          <template #default>
+            <el-empty v-if="!currentQuotation || !currentQuotation.quotationNo" description="鏈煡璇㈠埌瀵瑰簲鎶ヤ环璇︽儏" />
+            <template v-else>
+              <el-descriptions :column="2" border>
+                <el-descriptions-item label="鎶ヤ环鍗曞彿">{{ currentQuotation.quotationNo }}</el-descriptions-item>
+                <el-descriptions-item label="瀹㈡埛鍚嶇О">{{ currentQuotation.customer }}</el-descriptions-item>
+                <el-descriptions-item label="涓氬姟鍛�">{{ currentQuotation.salesperson }}</el-descriptions-item>
+                <el-descriptions-item label="鎶ヤ环鏃ユ湡">{{ currentQuotation.quotationDate }}</el-descriptions-item>
+                <el-descriptions-item label="鏈夋晥鏈熻嚦">{{ currentQuotation.validDate }}</el-descriptions-item>
+                <el-descriptions-item label="浠樻鏂瑰紡">{{ currentQuotation.paymentMethod }}</el-descriptions-item>
+                <el-descriptions-item label="鎶ヤ环鎬婚" :span="2">
+                  <span style="font-size: 18px; color: #e6a23c; font-weight: bold;">
+                    楼{{ Number(currentQuotation.totalAmount ?? 0).toFixed(2) }}
+                  </span>
+                </el-descriptions-item>
+              </el-descriptions>
+
+              <div style="margin-top: 20px;">
+                <h4>浜у搧鏄庣粏</h4>
+                <el-table :data="currentQuotation.products || []" border style="width: 100%">
+                  <el-table-column prop="product" label="浜у搧鍚嶇О" />
+                  <el-table-column prop="specification" label="瑙勬牸鍨嬪彿" />
+                  <el-table-column prop="unit" label="鍗曚綅" />
+                  <el-table-column prop="unitPrice" label="鍗曚环">
+                    <template #default="scope">楼{{ Number(scope.row.unitPrice ?? 0).toFixed(2) }}</template>
+                  </el-table-column>
+                </el-table>
+              </div>
+
+              <div v-if="currentQuotation.remark" style="margin-top: 20px;">
+                <h4>澶囨敞</h4>
+                <p>{{ currentQuotation.remark }}</p>
+              </div>
+            </template>
+          </template>
+        </el-skeleton>
+      </div>
+
+      <!-- 閲囪喘瀹℃壒锛氬睍绀洪噰璐鎯� -->
+      <div v-if="isPurchaseApproval" style="margin: 10px 0 18px;">
+        <el-divider content-position="left">閲囪喘璇︽儏</el-divider>
+        <el-skeleton :loading="purchaseLoading" animated>
+          <template #template>
+            <el-skeleton-item variant="h3" style="width: 30%" />
+            <el-skeleton-item variant="text" style="width: 100%" />
+            <el-skeleton-item variant="text" style="width: 100%" />
+          </template>
+          <template #default>
+            <el-empty v-if="!currentPurchase || !currentPurchase.purchaseContractNumber" description="鏈煡璇㈠埌瀵瑰簲閲囪喘璇︽儏" />
+            <template v-else>
+              <el-descriptions :column="2" border>
+                <el-descriptions-item label="閲囪喘鍚堝悓鍙�">{{ currentPurchase.purchaseContractNumber }}</el-descriptions-item>
+                <el-descriptions-item label="渚涘簲鍟嗗悕绉�">{{ currentPurchase.supplierName }}</el-descriptions-item>
+                <el-descriptions-item label="椤圭洰鍚嶇О">{{ currentPurchase.projectName }}</el-descriptions-item>
+                <el-descriptions-item label="閿�鍞悎鍚屽彿">{{ currentPurchase.salesContractNo }}</el-descriptions-item>
+                <el-descriptions-item label="绛捐鏃ユ湡">{{ currentPurchase.executionDate }}</el-descriptions-item>
+                <el-descriptions-item label="褰曞叆鏃ユ湡">{{ currentPurchase.entryDate }}</el-descriptions-item>
+                <el-descriptions-item label="浠樻鏂瑰紡">{{ currentPurchase.paymentMethod }}</el-descriptions-item>
+                <el-descriptions-item label="鍚堝悓閲戦" :span="2">
+                  <span style="font-size: 18px; color: #e6a23c; font-weight: bold;">
+                    楼{{ Number(currentPurchase.contractAmount ?? 0).toFixed(2) }}
+                  </span>
+                </el-descriptions-item>
+              </el-descriptions>
+
+              <div style="margin-top: 20px;">
+                <h4>浜у搧鏄庣粏</h4>
+                <el-table :data="currentPurchase.productData || []" border style="width: 100%">
+                  <el-table-column prop="productCategory" label="浜у搧鍚嶇О" />
+                  <el-table-column prop="specificationModel" label="瑙勬牸鍨嬪彿" />
+                  <el-table-column prop="unit" label="鍗曚綅" />
+                  <el-table-column prop="quantity" label="鏁伴噺" />
+                  <el-table-column prop="taxInclusiveUnitPrice" label="鍚◣鍗曚环">
+                    <template #default="scope">楼{{ Number(scope.row.taxInclusiveUnitPrice ?? 0).toFixed(2) }}</template>
+                  </el-table-column>
+                  <el-table-column prop="taxInclusiveTotalPrice" label="鍚◣鎬讳环">
+                    <template #default="scope">楼{{ Number(scope.row.taxInclusiveTotalPrice ?? 0).toFixed(2) }}</template>
+                  </el-table-column>
+                </el-table>
+              </div>
+            </template>
+          </template>
+        </el-skeleton>
+      </div>
+
+      <!-- 閿�鍞鎵癸細灞曠ず閿�鍞鎯� -->
+      <div v-if="isSalesApproval" style="margin: 10px 0 18px;">
+        <el-divider content-position="left">閿�鍞鎯�</el-divider>
+        <el-skeleton :loading="salesLoading" animated>
+          <template #template>
+            <el-skeleton-item variant="h3" style="width: 30%" />
+            <el-skeleton-item variant="text" style="width: 100%" />
+            <el-skeleton-item variant="text" style="width: 100%" />
+          </template>
+          <template #default>
+            <el-empty v-if="!currentSales || !currentSales.salesContractNo" description="鏈煡璇㈠埌瀵瑰簲閿�鍞鎯�" />
+            <template v-else>
+              <el-descriptions :column="2" border>
+                <el-descriptions-item label="閿�鍞悎鍚屽彿">{{ currentSales.salesContractNo }}</el-descriptions-item>
+                <el-descriptions-item label="瀹㈡埛鍚嶇О">{{ currentSales.customerName }}</el-descriptions-item>
+                <el-descriptions-item label="涓氬姟鍛�">{{ currentSales.salesman }}</el-descriptions-item>
+                <el-descriptions-item label="褰曞叆浜�">{{ currentSales.entryPersonName }}</el-descriptions-item>
+                <el-descriptions-item label="绛捐鏃ユ湡">{{ currentSales.executionDate }}</el-descriptions-item>
+                <el-descriptions-item label="褰曞叆鏃ユ湡">{{ currentSales.entryDate }}</el-descriptions-item>
+                <el-descriptions-item label="浠樻鏂瑰紡">{{ currentSales.paymentMethod }}</el-descriptions-item>
+                <el-descriptions-item label="鍚堝悓閲戦" :span="2">
+                  <span style="font-size: 18px; color: #e6a23c; font-weight: bold;">
+                    楼{{ calculateSalesTotalAmount() }}
+                  </span>
+                </el-descriptions-item>
+              </el-descriptions>
+
+              <div style="margin-top: 20px;">
+                <h4>浜у搧鏄庣粏</h4>
+                <el-table :data="currentSales.productData || []" border style="width: 100%">
+                  <el-table-column prop="productCategory" label="浜у搧鍚嶇О" />
+                  <el-table-column prop="specificationModel" label="瑙勬牸鍨嬪彿" />
+                  <el-table-column prop="unit" label="鍗曚綅" />
+                  <el-table-column prop="quantity" label="鏁伴噺" />
+                  <el-table-column prop="taxInclusiveUnitPrice" label="鍚◣鍗曚环">
+                    <template #default="scope">楼{{ Number(scope.row.taxInclusiveUnitPrice ?? 0).toFixed(2) }}</template>
+                  </el-table-column>
+                  <el-table-column prop="taxInclusiveTotalPrice" label="鍚◣鎬讳环">
+                    <template #default="scope">楼{{ Number(scope.row.taxInclusiveTotalPrice ?? 0).toFixed(2) }}</template>
+                  </el-table-column>
+                </el-table>
+              </div>
+            </template>
+          </template>
+        </el-skeleton>
+      </div>
+
+      <el-form :model="{ activities }" ref="formRef" label-position="top">
+        <el-steps :active="getActiveStep()" finish-status="success" process-status="process" align-center direction="vertical">
+          <el-step
+            v-for="(activity, index) in activities"
+            :key="index"
+						finish-status="success"
+            :title="getNodeTitle(index, activities.length)"
+            :description="activity.approveNodeUser"
+            :icon="getNodeIcon(activity, index)"
+          >
+						<template #icon>
+							<el-icon v-if="activity.approveNodeStatus === 2" color="red" :size="22"><WarningFilled /></el-icon>
+							<el-icon v-else-if="activity.isShen" color="#1890ff" :size="22"><Edit /></el-icon>
+							<el-icon v-else-if="activity.approveNodeStatus === 1" color="#67C23A" :size="26"><Check /></el-icon>
+							<el-icon v-else color="#C0C4CC" :size="22"><MoreFilled /></el-icon>
+						</template>
+            <template #title>
+              <span style="color: #000000">{{ getNodeTitle(index, activities.length) }}</span>
+            </template>
+            <template #description>
+              <div class="node-user">
+                <div class="avatar-wrapper">
+                  <img :src="userStore.avatar" class="user-avatar" alt=""/>
+                </div>
+                <span style="color: #000000">{{ activity.approveNodeUser }}-{{activity.isApproval}}</span>
+              </div>
+              <div v-if="!activity.isShen" class="node-reason">
+                <span>瀹℃壒鎰忚锛�</span>{{ activity.approveNodeReason }}
+              </div>
+              <div v-else-if="activity.isShen">
+                <el-form-item
+                  :prop="'activities.' + index + '.approveNodeReason'"
+                  :rules="[{ required: true, message: '瀹℃壒鎰忚涓嶈兘涓虹┖', trigger: 'blur' }]"
+                >
+                  <el-input v-model="activity.approveNodeReason" clearable type="textarea" :disabled="operationType === 'view'"></el-input>
+                </el-form-item>
+              </div>
+            </template>
+          </el-step>
+        </el-steps>
+      </el-form>
+      <template #footer v-if="operationType === 'approval'">
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm(2)">涓嶉�氳繃</el-button>
+          <el-button type="primary" @click="submitForm(1)">閫氳繃</el-button>
+          <el-button @click="closeDia">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { computed, getCurrentInstance, nextTick, reactive, ref, toRefs } from "vue";
+import {
+	approveProcessDetails,
+	getDept,
+	updateApproveNode
+} from "@/api/collaborativeApproval/approvalProcess.js";
+import useUserStore from "@/store/modules/user.js";
+import {userListNoPageByTenantId} from "@/api/system/user.js";
+import { WarningFilled, Edit, Check, MoreFilled } from '@element-plus/icons-vue'
+import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
+import { getPurchaseByCode, getSalesByCode } from "@/api/procurementManagement/procurementLedger.js";
+const emit = defineEmits(['close'])
+const { proxy } = getCurrentInstance()
+
+const props = defineProps({
+  approveType: {
+    type: [Number, String],
+    default: 0
+  }
+})
+
+const dialogFormVisible = ref(false);
+const operationType = ref('')
+const activities = ref([])
+const formRef = ref(null);
+const userStore = useUserStore()
+const productOptions = ref([]);
+const userList = ref([])
+const quotationLoading = ref(false)
+const currentQuotation = ref({})
+const purchaseLoading = ref(false)
+const currentPurchase = ref({})
+const salesLoading = ref(false)
+const currentSales = ref({})
+const isQuotationApproval = computed(() => Number(props.approveType) === 6)
+const isPurchaseApproval = computed(() => Number(props.approveType) === 5)
+const isSalesApproval = computed(() => Number(props.approveType) === 9)
+const isFreeApproval = computed(() => Number(props.approveType) === 10)
+
+const data = reactive({
+	form: {
+		approveTime: "",
+		approveId: "",
+		approveUser: "",
+		approveDeptId: "",
+		approveReason: "",
+		checkResult: "",
+	},
+});
+const { form } = toRefs(data);
+
+// 鑺傜偣鏍囬
+const getNodeTitle = (index, len) => {
+  if (index === len - 1) return '缁撴潫';
+  return '瀹℃壒';
+};
+
+// 鑾峰彇褰撳墠婵�娲绘楠�
+const getActiveStep = () => {
+  // 濡傛灉鎵�鏈� isShen 閮戒负 false锛岃繑鍥炴渶鍚庝竴涓楠わ紙鍏ㄩ儴瀹屾垚锛�
+  const hasActive = activities.value.some(a => a.isShen === true);
+  if (!hasActive) return activities.value.length;
+  // 褰撳墠鑺傜偣绱㈠紩
+  return activities.value.findIndex(a => a.isShen  == true);
+};
+// 姝ラicon
+const getNodeIcon = (activity, index) => {
+  if (activity.approveNodeStatus === 2) return 'el-icon-warning'; // 涓嶉�氳繃
+  if (activity.isShen) return 'Edit';
+  return '';
+};
+
+// 鎵撳紑寮规
+const openDialog = (type, row) => {
+  operationType.value = type;
+  dialogFormVisible.value = true;
+  currentQuotation.value = {}
+  currentPurchase.value = {}
+	userListNoPageByTenantId().then((res) => {
+		userList.value = res.data;
+	});
+	form.value = {...row}
+	// 绔嬪嵆娓呴櫎琛ㄥ崟楠岃瘉鐘舵�侊紙鍥犱负瀛楁鏄痙isabled鐨勶紝涓嶉渶瑕侀獙璇侊級
+	nextTick(() => {
+		if (formRef.value) {
+			formRef.value.clearValidate();
+		}
+	});
+	// 纭繚閫夐」鍔犺浇瀹屾垚鍚庡啀鍖归厤鍊肩被鍨�
+	getProductOptions().then(() => {
+		// 纭繚鍊肩被鍨嬪尮閰嶏紙濡傛灉閫夐」宸插姞杞斤級
+		if (productOptions.value.length > 0 && form.value.approveDeptId) {
+			const matchedOption = productOptions.value.find(opt =>
+				opt.deptId == form.value.approveDeptId ||
+				String(opt.deptId) === String(form.value.approveDeptId)
+			);
+			if (matchedOption) {
+				form.value.approveDeptId = matchedOption.deptId;
+			}
+		}
+		// 鍐嶆娓呴櫎楠岃瘉锛岀‘淇濋�夐」鍔犺浇鍚庡�煎尮閰嶆纭�
+		nextTick(() => {
+			if (formRef.value) {
+				formRef.value.clearValidate();
+			}
+		});
+	});
+
+  // 鎶ヤ环瀹℃壒锛氱敤瀹℃壒浜嬬敱瀛楁鎵胯浇鐨�"鎶ヤ环鍗曞彿"鍘绘煡鎶ヤ环鍒楄〃
+  if (isQuotationApproval.value) {
+    const quotationNo = row?.approveReason;
+    if (quotationNo) {
+      quotationLoading.value = true
+      getQuotationList({ quotationNo }).then((res) => {
+        const records = res?.data?.records || []
+        currentQuotation.value = records[0] || {}
+      }).finally(() => {
+        quotationLoading.value = false
+      })
+    }
+  }
+
+  // 閲囪喘瀹℃壒锛氱敤瀹℃壒浜嬬敱瀛楁鎵胯浇鐨�"閲囪喘鍚堝悓鍙�"鍘绘煡閲囪喘璇︽儏
+  if (isPurchaseApproval.value) {
+    const purchaseContractNumber = row?.approveReason;
+    if (purchaseContractNumber) {
+      purchaseLoading.value = true
+      getPurchaseByCode({ purchaseContractNumber }).then((res) => {
+        currentPurchase.value = res
+      }).catch((err) => {
+        console.error('鏌ヨ閲囪喘璇︽儏澶辫触:', err)
+        proxy.$modal.msgError('鏌ヨ閲囪喘璇︽儏澶辫触')
+      }).finally(() => {
+        purchaseLoading.value = false
+      })
+    }
+  }
+
+  // 閿�鍞鎵癸細鐢ㄥ鎵逛簨鐢卞瓧娈垫壙杞界殑"閿�鍞悎鍚屽彿"鍘绘煡閿�鍞鎯�
+  if (isSalesApproval.value) {
+    const salesContractNo = row?.approveReason;
+    if (salesContractNo) {
+      salesLoading.value = true
+      getSalesByCode({ salesContractNo }).then((res) => {
+        currentSales.value = res
+      }).catch((err) => {
+        console.error('鏌ヨ閿�鍞鎯呭け璐�:', err)
+        proxy.$modal.msgError('鏌ヨ閿�鍞鎯呭け璐�')
+      }).finally(() => {
+        salesLoading.value = false
+      })
+    }
+  }
+
+  approveProcessDetails(row.approveId).then((res) => {
+    activities.value = res.data
+    // 澧炲姞isApproval瀛楁
+    activities.value.forEach(item => {
+			if (item.url && item.url.includes('word')) {
+				item.urlTem = item.url.replaceAll('word', 'img')
+			} else {
+				item.urlTem = item.url
+			}
+      if (item.approveNodeStatus === 2) {
+        item.isApproval = '宸查┏鍥�';
+      } else if (item.approveNodeStatus === 1) {
+        item.isApproval = '宸插悓鎰�';
+      } else {
+        item.isApproval = '鏈鎵�';
+      }
+    })
+  })
+}
+const getProductOptions = () => {
+	return getDept().then((res) => {
+		productOptions.value = res.data;
+	});
+};
+// 鎻愪氦瀹℃壒
+const submitForm = (status) => {
+  const filteredActivities = activities.value.filter(activity => activity.isShen);
+  if (!filteredActivities || filteredActivities.length === 0) {
+    proxy.$modal.msgError("鏈壘鍒板緟瀹℃壒鐨勮妭鐐�");
+    return;
+  }
+  const currentActivity = filteredActivities[0];
+  if (!currentActivity) {
+    proxy.$modal.msgError("鏈壘鍒板緟瀹℃壒鐨勮妭鐐�");
+    return;
+  }
+  currentActivity.approveNodeStatus = status;
+  // 鍒ゆ柇鏄惁涓烘渶鍚庝竴姝�
+  const isLast = activities.value.findIndex(a => a.isShen) === activities.value.length-1;
+  updateApproveNode({ ...currentActivity, isLast }).then(() => {
+    proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+    closeDia();
+  });
+};
+// 鍏抽棴寮规
+const closeDia = () => {
+  proxy.resetForm("formRef");
+  dialogFormVisible.value = false;
+  quotationLoading.value = false
+  currentQuotation.value = {}
+  purchaseLoading.value = false
+  currentPurchase.value = {}
+  salesLoading.value = false
+  currentSales.value = {}
+  emit('close')
+};
+
+// 璁$畻閿�鍞悎鍚岄噾棰濓紙浜у搧鏄庣粏鍚◣鎬讳环涔嬪拰锛�
+const calculateSalesTotalAmount = () => {
+  const products = currentSales.value?.productData || []
+  const total = products.reduce((sum, item) => {
+    return sum + Number(item.taxInclusiveTotalPrice || 0)
+  }, 0)
+  return total.toFixed(2)
+}
+
+defineExpose({
+  openDialog,
+});
+</script>
+
+<style scoped>
+
+.node-user {
+  margin: 10px 0;
+  font-size: 16px;
+  font-weight: 600;
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+.node-status {
+  color: #1890ff;
+  margin-left: 8px;
+  font-size: 14px;
+}
+.node-reason {
+  font-size: 15px;
+  color: #333;
+  margin: 10px 0;
+}
+.user-avatar {
+	cursor: pointer;
+	width: 30px;
+	height: 30px;
+	border-radius: 50px;
+}
+.signImg {
+	cursor: pointer;
+	width: 200px;
+	height: 60px;
+}
+</style>
\ No newline at end of file
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/components/infoFormDia.vue b/src/pages/cooperativeOffice/collaborativeApproval/components/infoFormDia.vue
new file mode 100644
index 0000000..92737fc
--- /dev/null
+++ b/src/pages/cooperativeOffice/collaborativeApproval/components/infoFormDia.vue
@@ -0,0 +1,504 @@
+<template>
+  <div>
+    <el-dialog
+        v-model="dialogFormVisible"
+        :title="operationType === 'add' ? '鏂板瀹℃壒娴佺▼' : '缂栬緫瀹℃壒娴佺▼'"
+        width="50%"
+        @close="closeDia"
+    >
+      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="娴佺▼缂栧彿锛�" prop="approveId">
+              <el-input v-model="form.approveId" placeholder="鑷姩缂栧彿" clearable disabled/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="鐢宠閮ㄩ棬锛�" prop="approveDeptName">
+<!--              <el-input v-model="form.approveDeptName" placeholder="璇疯緭鍏�" clearable/>-->
+							<el-select
+								v-model="form.approveDeptIdArray"
+								placeholder="閫夋嫨閮ㄩ棬"
+                multiple
+                collapse-tags
+                @change="handleDeptChange"
+                style="width: 100%"
+							>
+								<el-option
+									v-for="user in productOptions"
+									:key="user.deptId"
+									:label="user.deptName"
+									:value="user.deptId"
+								/>
+							</el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <!-- 瀹℃壒鏍囬锛堜粎褰� approveType 涓� 9 鏃舵樉绀猴級 -->
+        <el-row v-if="props.approveType == 9">
+          <el-col :span="24">
+            <el-form-item label="瀹℃壒鏍囬锛�" prop="approveTitle">
+              <el-input v-model="form.approveTitle" placeholder="璇疯緭鍏ュ鎵规爣棰�" clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item :label="getApproveReasonLabel()" prop="approveReason">
+              <el-input v-model="form.approveReason" placeholder="璇疯緭鍏�" clearable type="textarea" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <!-- 璇峰亣鏃堕棿锛堜粎褰� approveType 涓� 2 鏃舵樉绀猴級 -->
+        <el-row :gutter="30" v-if="props.approveType == 2">
+          <el-col :span="12">
+            <el-form-item label="璇峰亣寮�濮嬫椂闂达細" prop="startDate">
+              <el-date-picker
+                  v-model="form.startDate"
+                  type="date"
+                  placeholder="璇烽�夋嫨寮�濮嬫棩鏈�"
+                  value-format="YYYY-MM-DD"
+                  format="YYYY-MM-DD"
+                  clearable
+                  style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="璇峰亣缁撴潫鏃堕棿锛�" prop="endDate">
+              <el-date-picker
+                  v-model="form.endDate"
+                  type="date"
+                  placeholder="璇烽�夋嫨缁撴潫鏃ユ湡"
+                  value-format="YYYY-MM-DD"
+                  format="YYYY-MM-DD"
+                  clearable
+                  style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <!-- 鎶ラ攢閲戦锛堜粎褰� approveType 涓� 4 鏃舵樉绀猴級 -->
+        <el-row v-if="props.approveType == 4">
+          <el-col :span="24">
+            <el-form-item label="鎶ラ攢閲戦锛�" prop="price">
+              <el-input-number
+                  v-model="form.price"
+                  placeholder="璇疯緭鍏ユ姤閿�閲戦"
+                  :min="0"
+                  :precision="2"
+                  :step="0.01"
+                  style="width: 100%"
+                  clearable
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <!-- 鍑哄樊鍦扮偣锛堜粎褰� approveType 涓� 3 鏃舵樉绀猴級 -->
+        <el-row v-if="props.approveType == 3">
+          <el-col :span="24">
+            <el-form-item label="鍑哄樊鍦扮偣锛�" prop="location">
+              <el-input
+                  v-model="form.location"
+                  placeholder="璇疯緭鍏ュ嚭宸湴鐐�"
+                  clearable
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <!-- 瀹℃壒浜洪�夋嫨锛堝姩鎬佽妭鐐癸級 -->
+        <el-row>
+          <el-col :span="24">
+            <el-form-item>
+              <template #label>
+                <span>瀹℃壒浜洪�夋嫨锛�</span>
+                <el-button type="primary" @click="addApproverNode" style="margin-left: 8px;">鏂板鑺傜偣</el-button>
+              </template>
+              <div style="display: flex; align-items: flex-end; flex-wrap: wrap;">
+                <div
+                  v-for="(node, index) in approverNodes"
+                  :key="node.id"
+                  style="margin-right: 30px; text-align: center; margin-bottom: 10px;"
+                >
+                  <div>
+                    <span>瀹℃壒浜�</span>
+                    鈫�
+                  </div>
+                  <el-select
+                    v-model="node.userId"
+                    placeholder="閫夋嫨浜哄憳"
+                    style="width: 120px; margin-bottom: 8px;"
+                  >
+                    <el-option
+                      v-for="user in userList"
+                      :key="user.userId"
+                      :label="user.nickName"
+                      :value="user.userId"
+                    />
+                  </el-select>
+                  <div>
+                    <el-button
+                      type="danger"
+                      size="small"
+                      @click="removeApproverNode(index)"
+                      v-if="approverNodes.length > 1"
+                    >鍒犻櫎</el-button>
+                  </div>
+                </div>
+              </div>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鐢宠浜猴細" prop="approveUser">
+							<el-select
+								v-model="form.approveUser"
+								placeholder="閫夋嫨浜哄憳"
+                filterable
+                default-first-option
+                :reserve-keyword="false"
+							>
+								<el-option
+									v-for="user in userList"
+									:key="user.userId"
+									:label="user.nickName"
+									:value="user.userId"
+								/>
+							</el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鐢宠鏃ユ湡锛�" prop="approveTime">
+              <el-date-picker
+                  v-model="form.approveTime"
+                  type="date"
+                  placeholder="璇烽�夋嫨鏃ユ湡"
+                  value-format="YYYY-MM-DD"
+                  format="YYYY-MM-DD"
+                  clearable
+                  style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="闄勪欢鏉愭枡锛�" prop="remark">
+              <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload
+                         :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError"
+                         :on-success="handleUploadSuccess" :on-remove="handleRemove">
+                <el-button type="primary" v-if="operationType !== 'view'">涓婁紶</el-button>
+                <template #tip v-if="operationType !== 'view'">
+                  <div class="el-upload__tip">
+                    鏂囦欢鏍煎紡鏀寔
+                    doc锛宒ocx锛寈ls锛寈lsx锛宲pt锛宲ptx锛宲df锛宼xt锛寈ml锛宩pg锛宩peg锛宲ng锛実if锛宐mp锛宺ar锛寊ip锛�7z
+                  </div>
+                </template>
+              </el-upload>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitForm">纭</el-button>
+          <el-button @click="closeDia">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import {ref, reactive, toRefs, getCurrentInstance} from "vue";
+import {
+  approveProcessAdd, approveProcessGetInfo,
+  approveProcessUpdate,
+  getDept
+} from "@/api/collaborativeApproval/approvalProcess.js";
+import {
+  delLedgerFile,
+} from "@/api/salesManagement/salesLedger.js";
+import {userListNoPageByTenantId} from "@/api/system/user.js";
+import { getToken } from "@/utils/auth";
+const { proxy } = getCurrentInstance()
+const emit = defineEmits(['close'])
+import useUserStore from "@/store/modules/user";
+import { getCurrentDate } from "@/utils/index.js";
+import log from "@/views/monitor/job/log.vue";
+const userStore = useUserStore();
+
+const dialogFormVisible = ref(false);
+const operationType = ref('')
+const fileList = ref([]);
+const upload = reactive({
+  // 涓婁紶鐨勫湴鍧�
+  url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
+  // 璁剧疆涓婁紶鐨勮姹傚ご閮�
+  headers: { Authorization: "Bearer " + getToken() },
+});
+const data = reactive({
+  form: {
+    approveTime: "",
+    approveId: "",
+    approveUser: "",
+		approveDeptIdArray: [],
+    approveDeptName: "",
+    approveTitle: "", // 瀹℃壒鏍囬锛堣嚜鐢卞崗鍚屽鎵逛娇鐢級
+    approveReason: "",
+    checkResult: "",
+    tempFileIds: [],
+    approverList: [], // 鏂板瀛楁锛屽瓨鍌ㄦ墍鏈夎妭鐐圭殑瀹℃壒浜篿d
+    startDate: "", // 璇峰亣寮�濮嬫椂闂�
+    endDate: "", // 璇峰亣缁撴潫鏃堕棿
+    price: null, // 鎶ラ攢閲戦
+    location: "" // 鍑哄樊鍦扮偣
+  },
+  rules: {
+    approveTime: [{ required: false, message: "璇疯緭鍏�", trigger: "change" },],
+    approveId: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
+    approveUser: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
+    approveDeptName: [{ required: true, message: "璇烽�夋嫨鐢宠閮ㄩ棬", trigger: "change" }],
+    approveTitle: [{ required: true, message: "璇疯緭鍏ュ鎵规爣棰�", trigger: "blur" }],
+    approveReason: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    checkResult: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
+    startDate: [{ required: true, message: "璇烽�夋嫨璇峰亣寮�濮嬫椂闂�", trigger: "change" }],
+    endDate: [{ required: true, message: "璇烽�夋嫨璇峰亣缁撴潫鏃堕棿", trigger: "change" }],
+    price: [{ required: true, message: "璇疯緭鍏ユ姤閿�閲戦", trigger: "blur" }],
+    location: [{ required: true, message: "璇疯緭鍏ュ嚭宸湴鐐�", trigger: "blur" }],
+  },
+});
+const { form, rules } = toRefs(data);
+const productOptions = ref([]);
+const currentApproveStatus = ref(0)
+const props = defineProps({
+  approveType: {
+    type: [Number, String],
+    default: 0
+  }
+})
+
+// 鑾峰彇瀹℃壒浜嬬敱鏍囩
+const getApproveReasonLabel = () => {
+  const type = Number(props.approveType)
+  if (type === 5) {
+    return '閲囪喘璁″垝璇存槑锛�'
+  } else if (type === 9) {
+    return '閿�鍞悎鍚屽彿锛�'
+  } else if (type === 10) {
+    return '瀹℃壒浜嬬敱锛�'
+  }
+  return '瀹℃壒浜嬬敱锛�'
+}
+
+// 瀹℃壒浜鸿妭鐐圭浉鍏�
+const approverNodes = ref([
+  { id: 1, userId: null }
+])
+let nextApproverId = 2
+const userList = ref([])
+function addApproverNode() {
+  approverNodes.value.push({ id: nextApproverId++, userId: null })
+}
+function removeApproverNode(index) {
+  approverNodes.value.splice(index, 1)
+}
+// 澶勭悊閮ㄩ棬閫夋嫨鍙樺寲
+const handleDeptChange = (deptIds) => {
+  if (deptIds && deptIds.length > 0) {
+    const selectedNames = productOptions.value
+      .filter(dept => deptIds.includes(dept.deptId))
+      .map(dept => dept.deptName);
+    form.value.approveDeptName = selectedNames.join(',');
+  } else {
+    form.value.approveDeptName = '';
+  }
+};
+// 鎵撳紑寮规
+const openDialog = (type, row) => {
+  operationType.value = type;
+  dialogFormVisible.value = true;
+	userListNoPageByTenantId().then((res) => {
+    userList.value = res.data;
+  });
+  getProductOptions();
+	form.value = {}
+	approverNodes.value = [
+		{ id: 1, userId: null }
+	]
+  form.value.approveUser = userStore.id;
+  form.value.approveTime = getCurrentDate();
+  
+  // 鑾峰彇褰撳墠鐢ㄦ埛淇℃伅骞惰缃儴闂↖D
+  form.value.approveDeptIdArray = []
+  if (operationType.value === 'edit') {
+    fileList.value = row.commonFileList
+    form.value.tempFileIds = fileList.value.map(file => file.id)
+		currentApproveStatus.value = row.approveStatus
+    approveProcessGetInfo({id: row.approveId,approveReason: '1'}).then(res => {
+			form.value = {...res.data}
+      // 澶勭悊閮ㄩ棬鍙嶆樉锛堟牴鎹悗绔繑鍥炵殑 approveDeptId 澶勭悊涓烘暟缁勶級
+      const deptId = res.data.approveDeptId;
+      if (deptId !== undefined && deptId !== null) {
+        if (Array.isArray(deptId)) {
+          form.value.approveDeptIdArray = deptId;
+        } else if (typeof deptId === 'string' && deptId.includes(',')) {
+          form.value.approveDeptIdArray = deptId.split(',').map(id => parseInt(id.trim())).filter(id => !isNaN(id));
+        } else if (typeof deptId === 'string' || typeof deptId === 'number') {
+          form.value.approveDeptIdArray = [parseInt(deptId)];
+        }
+      } else {
+        form.value.approveDeptIdArray = [];
+      }
+      // 鍙嶆樉瀹℃壒浜�
+      if (res.data && res.data.approveUserIds) {
+        const userIds = res.data.approveUserIds.split(',')
+        approverNodes.value = userIds.map((userId, idx) => ({
+          id: idx + 1, 
+          userId: parseInt(userId.trim())
+        }))
+        nextApproverId = userIds.length + 1
+      } else {
+        approverNodes.value = [{ id: 1, userId: null }]
+        nextApproverId = 2
+      }
+    })
+  }
+}
+const getProductOptions = () => {
+  getDept().then((res) => {
+    productOptions.value = res.data;
+  });
+};
+function convertIdToValue(data) {
+  return data.map((item) => {
+    const { id, children, ...rest } = item;
+    const newItem = {
+      ...rest,
+      value: id, // 灏� id 鏀逛负 value
+    };
+    if (children && children.length > 0) {
+      newItem.children = convertIdToValue(children);
+    }
+    
+    return newItem;
+  });
+}
+// 鎻愪氦浜у搧琛ㄥ崟
+const submitForm = () => {
+  // 鏀堕泦鎵�鏈夎妭鐐圭殑瀹℃壒浜篿d
+  form.value.approveUserIds = approverNodes.value.map(node => node.userId).join(',')
+  form.value.approveType = props.approveType
+  // 瀹℃壒浜哄繀濉牎楠�
+  const hasEmptyApprover = approverNodes.value.some(node => !node.userId)
+  if (hasEmptyApprover) {
+    proxy.$modal.msgError("璇蜂负鎵�鏈夊鎵硅妭鐐归�夋嫨瀹℃壒浜猴紒")
+    return
+  }
+  // 褰� approveType 涓� 2 鏃讹紝鏍¢獙璇峰亣鏃堕棿
+  if (props.approveType == 2) {
+    if (!form.value.startDate) {
+      proxy.$modal.msgError("璇烽�夋嫨璇峰亣寮�濮嬫椂闂达紒")
+      return
+    }
+    if (!form.value.endDate) {
+      proxy.$modal.msgError("璇烽�夋嫨璇峰亣缁撴潫鏃堕棿锛�")
+      return
+    }
+    // 鏍¢獙缁撴潫鏃堕棿涓嶈兘鏃╀簬寮�濮嬫椂闂�
+    if (new Date(form.value.endDate) < new Date(form.value.startDate)) {
+      proxy.$modal.msgError("璇峰亣缁撴潫鏃堕棿涓嶈兘鏃╀簬寮�濮嬫椂闂达紒")
+      return
+    }
+  }
+  // 褰� approveType 涓� 3 鏃讹紝鏍¢獙鍑哄樊鍦扮偣
+  if (props.approveType == 3) {
+    if (!form.value.location || form.value.location.trim() === '') {
+      proxy.$modal.msgError("璇疯緭鍏ュ嚭宸湴鐐癸紒")
+      return
+    }
+  }
+  // 褰� approveType 涓� 4 鏃讹紝鏍¢獙鎶ラ攢閲戦
+  if (props.approveType == 4) {
+    if (!form.value.price || form.value.price <= 0) {
+      proxy.$modal.msgError("璇疯緭鍏ユ湁鏁堢殑鎶ラ攢閲戦锛�")
+      return
+    }
+  }
+  proxy.$refs.formRef.validate(valid => {
+    if (valid) {
+      const submitData = { ...form.value };
+      if (operationType.value === "add" || currentApproveStatus.value == 3) {
+        approveProcessAdd(submitData).then(res => {
+          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+          closeDia();
+        })
+      } else {
+        approveProcessUpdate(submitData).then(res => {
+          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+          closeDia();
+        })
+      }
+    }
+  })
+}
+// 鍏抽棴寮规
+const closeDia = () => {
+  fileList.value = []
+  proxy.resetForm("formRef");
+  dialogFormVisible.value = false;
+  emit('close')
+};
+
+// 涓婁紶鍓嶆牎妫�
+function handleBeforeUpload(file) {
+  // 鏍℃鏂囦欢澶у皬
+  // if (file.size > 1024 * 1024 * 10) {
+  //   proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
+  //   return false;
+  // }
+  proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
+  return true;
+}
+// 涓婁紶澶辫触
+function handleUploadError(err) {
+  proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
+  proxy.$modal.closeLoading();
+}
+// 涓婁紶鎴愬姛鍥炶皟
+function handleUploadSuccess(res, file, uploadFiles) {
+  proxy.$modal.closeLoading();
+  if (res.code === 200) {
+    // 纭繚 tempFileIds 瀛樺湪涓斾负鏁扮粍
+    if (!form.value.tempFileIds) {
+      form.value.tempFileIds = [];
+    }
+    form.value.tempFileIds.push(res.data.tempId);
+    proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
+  } else {
+    proxy.$modal.msgError(res.msg);
+    proxy.$refs.fileUpload.handleRemove(file);
+  }
+}
+// 绉婚櫎鏂囦欢
+function handleRemove(file) {
+  if (operationType.value === "edit") {
+    let ids = [];
+    ids.push(file.id);
+    delLedgerFile(ids).then((res) => {
+      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    });
+  }
+}
+
+defineExpose({
+  openDialog,
+});
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/detail.vue b/src/pages/cooperativeOffice/collaborativeApproval/detail.vue
index 04a4c18..c4cce2c 100644
--- a/src/pages/cooperativeOffice/collaborativeApproval/detail.vue
+++ b/src/pages/cooperativeOffice/collaborativeApproval/detail.vue
@@ -14,22 +14,29 @@
                  disabled
                  placeholder="鑷姩缂栧彿" />
       </u-form-item>
+      <!-- 瀹℃壒鏍囬锛堜粎褰� approveType 涓� 9 鎴� 10 鏃舵樉绀猴級 -->
+      <u-form-item v-if="approveType === 9 || approveType === 10"
+                   prop="approveTitle"
+                   label="瀹℃壒鏍囬"
+                   required>
+        <u-input v-model="form.approveTitle"
+                 placeholder="璇疯緭鍏ュ鎵规爣棰�"
+                 clearable />
+      </u-form-item>
       <u-form-item prop="approveReason"
-                   :label="approveType === 5 ? '閲囪喘浜嬬敱' : '鐢宠浜嬬敱'"
+                   :label="getApproveReasonLabel()"
                    required>
         <u-input v-model="form.approveReason"
                  type="textarea"
                  rows="2"
                  auto-height
                  maxlength="200"
-                 :placeholder="approveType === 5 ? '璇疯緭鍏ラ噰璐簨鐢�' : '璇疯緭鍏ョ敵璇蜂簨鐢�'"
+                 :placeholder="getApproveReasonPlaceholder()"
                  show-word-limit />
       </u-form-item>
       <u-form-item prop="approveDeptName"
                    label="鐢宠閮ㄩ棬"
                    required>
-        <!-- <u-input v-model="form.approveDeptName"
-                 placeholder="璇烽�夋嫨鐢宠閮ㄩ棬" /> -->
         <u-input v-model="form.approveDeptName"
                  readonly
                  placeholder="璇烽�夋嫨鐢宠閮ㄩ棬"
@@ -103,6 +110,19 @@
                  type="number"
                  placeholder="璇疯緭鍏ユ姤閿�閲戦"
                  clearable />
+      </u-form-item>
+      <!-- 闄勪欢涓婁紶 -->
+      <u-form-item label="闄勪欢鏉愭枡">
+        <view class="file-upload-area">
+          <view v-for="(file, index) in fileList" :key="file.id || index" class="file-item">
+            <text class="file-name">{{ file.name || file.fileName }}</text>
+            <text class="file-delete" @click="removeFile(index)">脳</text>
+          </view>
+          <view class="upload-btn" @click="chooseFile" v-if="operationType !== 'view'">
+            <up-icon name="plus" size="20" color="#006cfb"></up-icon>
+            <text class="upload-text">涓婁紶闄勪欢</text>
+          </view>
+        </view>
       </u-form-item>
     </u-form>
     <!-- 閫夋嫨鍣ㄥ脊绐� -->
@@ -227,6 +247,7 @@
       approveUserName: "",
       approveDeptName: "",
       approveDeptId: "",
+      approveTitle: "", // 瀹℃壒鏍囬锛堣嚜鐢卞崗鍚屽鎵逛娇鐢級
       approveReason: "",
       checkResult: "",
       tempFileIds: [],
@@ -239,8 +260,9 @@
     rules: {
       approveTime: [{ required: false, message: "璇疯緭鍏�", trigger: "change" }],
       approveId: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
-      approveDeptId: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      approveDeptId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
       approveReason: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      approveTitle: [{ required: true, message: "璇疯緭鍏ュ鎵规爣棰�", trigger: "blur" }],
       checkResult: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
       startDate: [
         { required: false, message: "璇烽�夋嫨寮�濮嬫椂闂�", trigger: "change" },
@@ -271,6 +293,32 @@
   const userStore = useUserStore();
   const approveType = ref(0);
 
+  // 鑾峰彇瀹℃壒浜嬬敱鏍囩
+  const getApproveReasonLabel = () => {
+    const type = Number(approveType.value);
+    if (type === 5) {
+      return '閲囪喘璁″垝璇存槑';
+    } else if (type === 9) {
+      return '閿�鍞悎鍚屽彿';
+    } else if (type === 10) {
+      return '瀹℃壒浜嬬敱';
+    }
+    return '瀹℃壒浜嬬敱';
+  };
+
+  // 鑾峰彇瀹℃壒浜嬬敱鍗犱綅绗�
+  const getApproveReasonPlaceholder = () => {
+    const type = Number(approveType.value);
+    if (type === 5) {
+      return '璇疯緭鍏ラ噰璐鍒掕鏄�';
+    } else if (type === 9) {
+      return '璇疯緭鍏ラ攢鍞悎鍚屽彿';
+    } else if (type === 10) {
+      return '璇疯緭鍏ュ鎵逛簨鐢�';
+    }
+    return '璇疯緭鍏ョ敵璇蜂簨鐢�';
+  };
+
   const getProductOptions = () => {
     getDept().then(res => {
       productOptions.value = res.data.map(item => ({
@@ -281,6 +329,76 @@
   };
   const fileList = ref([]);
   let nextApproverId = 2;
+
+  // 澶勭悊閮ㄩ棬閫夋嫨鍙樺寲
+  const handleDeptChange = (deptIds) => {
+    if (deptIds && deptIds.length > 0) {
+      const selectedNames = productOptions.value
+        .filter(dept => deptIds.includes(dept.value))
+        .map(dept => dept.name);
+      form.value.approveDeptName = selectedNames.join(',');
+    } else {
+      form.value.approveDeptName = '';
+    }
+  };
+
+  // 閫夋嫨瀹℃壒浜�
+  const addApprover = (stepIndex) => {
+    uni.setStorageSync("stepIndex", stepIndex);
+    uni.navigateTo({
+      url: "/pages/cooperativeOffice/collaborativeApproval/contactSelect",
+    });
+  };
+
+  // 娣诲姞瀹℃壒鑺傜偣
+  const addApprovalStep = () => {
+    approverNodes.value.push({ id: nextApproverId++, userId: null, nickName: null });
+  };
+
+  // 绉婚櫎瀹℃壒浜�
+  const removeApprover = (stepIndex) => {
+    approverNodes.value[stepIndex].userId = null;
+    approverNodes.value[stepIndex].nickName = null;
+  };
+
+  // 绉婚櫎瀹℃壒鑺傜偣
+  const removeApprovalStep = (stepIndex) => {
+    if (approverNodes.value.length > 1) {
+      approverNodes.value.splice(stepIndex, 1);
+    } else {
+      showToast("鑷冲皯闇�瑕佷竴涓鎵规楠�");
+    }
+  };
+
+  // 澶勭悊鑱旂郴浜洪�夋嫨缁撴灉
+  const handleSelectContact = (data) => {
+    const { stepIndex, contact } = data;
+    approverNodes.value[stepIndex].userId = contact.userId;
+    approverNodes.value[stepIndex].nickName = contact.nickName;
+  };
+
+  // 閫夋嫨鏂囦欢涓婁紶
+  const chooseFile = () => {
+    uni.chooseMessageFile({
+      count: 10,
+      success: (res) => {
+        const tempFilePaths = res.tempFiles;
+        // 杩欓噷鍙互娣诲姞涓婁紶閫昏緫
+        tempFilePaths.forEach(file => {
+          fileList.value.push({
+            name: file.name,
+            path: file.path,
+            size: file.size,
+          });
+        });
+      }
+    });
+  };
+
+  // 绉婚櫎鏂囦欢
+  const removeFile = (index) => {
+    fileList.value.splice(index, 1);
+  };
   const getCurrentinfo = () => {
     userStore.getInfo().then(res => {
       form.value.approveDeptId = res.user.tenantId;
@@ -461,44 +579,6 @@
       });
   };
 
-  // 澶勭悊鑱旂郴浜洪�夋嫨缁撴灉
-  const handleSelectContact = data => {
-    const { stepIndex, contact } = data;
-    // 灏嗛�変腑鐨勮仈绯讳汉璁剧疆涓哄搴斿鎵规楠ょ殑瀹℃壒浜�
-    approverNodes.value[stepIndex].userId = contact.userId;
-    approverNodes.value[stepIndex].nickName = contact.nickName;
-  };
-
-  const addApprover = stepIndex => {
-    // 璺宠浆鍒拌仈绯讳汉閫夋嫨椤甸潰
-    uni.setStorageSync("stepIndex", stepIndex);
-    uni.navigateTo({
-      url: "/pages/cooperativeOffice/collaborativeApproval/contactSelect",
-    });
-  };
-
-  const addApprovalStep = () => {
-    // 娣诲姞鏂扮殑瀹℃壒姝ラ
-    approverNodes.value.push({ userId: null, nickName: null });
-  };
-
-  const removeApprover = stepIndex => {
-    // 绉婚櫎瀹℃壒浜�
-    approverNodes.value[stepIndex].userId = null;
-    approverNodes.value[stepIndex].nickName = null;
-  };
-
-  const removeApprovalStep = stepIndex => {
-    // 纭繚鑷冲皯淇濈暀涓�涓鎵规楠�
-    if (approverNodes.value.length > 1) {
-      approverNodes.value.splice(stepIndex, 1);
-    } else {
-      uni.showToast({
-        title: "鑷冲皯闇�瑕佷竴涓鎵规楠�",
-        icon: "none",
-      });
-    }
-  };
   // 鏄剧ず鏃ユ湡閫夋嫨鍣�
   const showDatePicker = () => {
     showDate.value = true;
@@ -926,4 +1006,52 @@
     color: #3b82f6;
     font-size: 14px;
   }
+
+  // 鏂囦欢涓婁紶鍖哄煙鏍峰紡
+  .file-upload-area {
+    display: flex;
+    flex-direction: column;
+    gap: 8px;
+  }
+
+  .file-item {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    background: #f8f9fa;
+    padding: 10px 12px;
+    border-radius: 8px;
+  }
+
+  .file-name {
+    font-size: 14px;
+    color: #333;
+    flex: 1;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+
+  .file-delete {
+    font-size: 18px;
+    color: #ff4d4f;
+    margin-left: 8px;
+    padding: 0 4px;
+  }
+
+  .upload-btn {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    gap: 8px;
+    border: 2px dashed #d9d9d9;
+    border-radius: 8px;
+    padding: 16px;
+    background: #fafafa;
+  }
+
+  .upload-text {
+    font-size: 14px;
+    color: #666;
+  }
 </style>
\ No newline at end of file
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/index.vue b/src/pages/cooperativeOffice/collaborativeApproval/index.vue
index bc69a5f..06e6205 100644
--- a/src/pages/cooperativeOffice/collaborativeApproval/index.vue
+++ b/src/pages/cooperativeOffice/collaborativeApproval/index.vue
@@ -140,13 +140,16 @@
   import { onLoad, onShow } from "@dcloudio/uni-app";
   import useUserStore from "@/store/modules/user";
 
-  // 鎺ユ敹鐖剁粍浠朵紶閫掔殑 approveType 鍙傛暟
+  // 鎺ユ敹鐖剁粍浠朵紶閫掔殑 approveType 鍙傛暟锛堢敤浜� index1.vue, index2.vue 绛夌粍浠舵柟寮忚皟鐢級
   const props = defineProps({
     approveType: {
       type: Number,
       default: 0,
     },
   });
+
+  // 瀹℃壒绫诲瀷
+  const approveType = ref(0);
 
   // 鏄犲皠 approveType 鍒板搴旂殑椤甸潰鏍囬
   const getPageTitle = type => {
@@ -159,11 +162,13 @@
       6: "鎶ヤ环绠$悊",
       7: "鍙戣揣瀹℃壒",
       8: "鍗遍櫓浣滀笟瀹℃壒",
+      9: "閿�鍞鎵�",
+      10: "鑷敱鍗忓悓瀹℃壒",
     };
-    return titleMap[type] || "瀹℃壒绠$悊";
+    return titleMap[type] || "鍗忓悓瀹℃壒";
   };
 
-  const pageTitle = getPageTitle(props.approveType);
+  const pageTitle = ref("鍗忓悓瀹℃壒");
 
   const userStore = useUserStore();
   // 鏁版嵁
@@ -188,7 +193,7 @@
     };
     approveProcessListPage({
       ...page,
-      approveType: props.approveType,
+      approveType: approveType.value,
       ...searchForm.value,
     })
       .then(res => {
@@ -256,7 +261,7 @@
     uni.setStorageSync("invoiceLedgerEditRow", JSON.stringify(item));
     uni.setStorageSync("operationType", "edit");
     uni.setStorageSync("approveId", item.approveId);
-    uni.setStorageSync("approveType", props.approveType);
+    uni.setStorageSync("approveType", approveType.value);
     uni.navigateTo({
       url: "/pages/cooperativeOffice/collaborativeApproval/detail",
     });
@@ -265,31 +270,50 @@
   // 娣诲姞鏂拌褰�
   const handleAdd = () => {
     uni.setStorageSync("operationType", "add");
-    uni.setStorageSync("approveType", props.approveType);
+    uni.setStorageSync("approveType", approveType.value);
     uni.navigateTo({
-      url: `/pages/cooperativeOffice/collaborativeApproval/detail?approveType=${props.approveType}`,
+      url: `/pages/cooperativeOffice/collaborativeApproval/detail?approveType=${approveType.value}`,
     });
   };
   // 鐐瑰嚮瀹℃牳
   const approve = item => {
     uni.setStorageSync("approveId", item.approveId);
-    uni.setStorageSync("approveType", props.approveType);
+    uni.setStorageSync("approveType", approveType.value);
     uni.navigateTo({
       url:
         "/pages/cooperativeOffice/collaborativeApproval/approve?approveType=" +
-        props.approveType,
+        approveType.value,
     });
   };
 
   onLoad(options => {
+    console.log('onLoad options:', options, 'props.approveType:', props.approveType);
+    
+    // 浼樺厛浣跨敤 props 鐨� approveType锛堢粍浠舵柟寮忚皟鐢紝濡� index1.vue锛�
+    // 濡傛灉娌℃湁 props锛屽垯浣跨敤 URL 鍙傛暟锛堝 index?approveType=9锛�
+    if (props.approveType && props.approveType > 0) {
+      approveType.value = props.approveType;
+      console.log('浠� props 璁剧疆 approveType:', approveType.value);
+    } else if (options.approveType) {
+      approveType.value = Number(options.approveType);
+      console.log('浠� URL 鍙傛暟璁剧疆 approveType:', approveType.value);
+    } else {
+      console.log('鏈幏鍙栧埌 approveType 鍙傛暟');
+    }
+    
+    // 璁剧疆椤甸潰鏍囬
+    pageTitle.value = getPageTitle(approveType.value);
+    
     // 瑙f瀽approveId
     if (options.approveId) {
       searchForm.value.approveId = options.approveId;
     }
+    // 椤甸潰鍔犺浇鏃剁珛鍗宠幏鍙栧垪琛�
+    getList();
   });
 
   onShow(() => {
-    // 椤甸潰鍔犺浇瀹屾垚鍚庣殑鍒濆鍖栭�昏緫
+    // 椤甸潰鏄剧ず鏃跺埛鏂板垪琛�
     getList();
   });
 </script>
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/indexNew.vue b/src/pages/cooperativeOffice/collaborativeApproval/indexNew.vue
new file mode 100644
index 0000000..c0cc255
--- /dev/null
+++ b/src/pages/cooperativeOffice/collaborativeApproval/indexNew.vue
@@ -0,0 +1,382 @@
+<template>
+	<div class="app-container">
+		<!-- 鏍囩椤靛垏鎹笉鍚岀殑瀹℃壒绫诲瀷 -->
+		<el-tabs v-model="activeTab" @tab-change="handleTabChange" class="approval-tabs">
+			<el-tab-pane label="鍏嚭绠$悊" name="1"></el-tab-pane>
+			<el-tab-pane label="璇峰亣绠$悊" name="2"></el-tab-pane>
+			<el-tab-pane label="鍑哄樊绠$悊" name="3"></el-tab-pane>
+			<el-tab-pane label="鎶ラ攢绠$悊" name="4"></el-tab-pane>
+			<el-tab-pane label="閲囪喘璁″垝瀹℃壒" name="5"></el-tab-pane>
+			<!--      <el-tab-pane label="鎶ヤ环瀹℃壒" name="6"></el-tab-pane>-->
+			<el-tab-pane label="鍑哄簱瀹℃壒" name="7"></el-tab-pane>
+			<el-tab-pane label="閿�鍞鎵�" name="9"></el-tab-pane>
+			<el-tab-pane label="鑷敱鍗忓悓瀹℃壒" name="10"></el-tab-pane>
+		</el-tabs>
+		
+		<div class="search_form">
+			<div>
+				<span class="search_title">娴佺▼缂栧彿锛�</span>
+				<el-input
+					v-model="searchForm.approveId"
+					style="width: 240px"
+					placeholder="璇疯緭鍏ユ祦绋嬬紪鍙锋悳绱�"
+					@change="handleQuery"
+					clearable
+					:prefix-icon="Search"
+				/>
+				<span class="search_title ml10">瀹℃壒鐘舵�侊細</span>
+				<el-select v-model="searchForm.approveStatus" clearable @change="handleQuery" style="width: 240px">
+					<el-option label="寰呭鏍�" :value="0" />
+					<el-option label="瀹℃牳涓�" :value="1" />
+					<el-option label="瀹℃牳瀹屾垚" :value="2" />
+					<el-option label="瀹℃牳鏈�氳繃" :value="3" />
+					<el-option label="宸查噸鏂版彁浜�" :value="4" />
+				</el-select>
+				<el-button type="primary" @click="handleQuery" style="margin-left: 10px"
+				>鎼滅储</el-button
+				>
+			</div>
+			<div>
+				<el-button type="primary" @click="openForm('add')" v-if="currentApproveType !== 6 && currentApproveType !== 5 && currentApproveType !== 9">鏂板</el-button>
+				<el-button @click="handleOut">瀵煎嚭</el-button>
+				<el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+			</div>
+		</div>
+		<div class="table_list">
+			<PIMTable
+				rowKey="id"
+				:column="tableColumnCopy"
+				:tableData="tableData"
+				:page="page"
+				:isSelection="true"
+				@selection-change="handleSelectionChange"
+				:tableLoading="tableLoading"
+				@pagination="pagination"
+				:total="page.total"
+			></PIMTable>
+		</div>
+		<info-form-dia ref="infoFormDia" @close="handleQuery" :approveType="currentApproveType"></info-form-dia>
+		<approval-dia ref="approvalDia" @close="handleQuery" :approveType="currentApproveType"></approval-dia>
+		<FileList ref="fileListRef" />
+	</div>
+</template>
+
+<script setup>
+import FileList from "./fileList.vue";
+import { Search } from "@element-plus/icons-vue";
+import {onMounted, ref, computed, reactive, toRefs, nextTick, getCurrentInstance} from "vue";
+import {ElMessageBox} from "element-plus";
+import { useRoute } from 'vue-router';
+import InfoFormDia from "@/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue";
+import ApprovalDia from "@/views/collaborativeApproval/approvalProcess/components/approvalDia.vue";
+import {approveProcessDelete, approveProcessListPage} from "@/api/collaborativeApproval/approvalProcess.js";
+import useUserStore from "@/store/modules/user";
+
+const userStore = useUserStore();
+const route = useRoute();
+
+// 褰撳墠閫変腑鐨勬爣绛鹃〉锛岄粯璁や负鍏嚭绠$悊
+const activeTab = ref('1');
+
+// 褰撳墠瀹℃壒绫诲瀷锛屾牴鎹�変腑鐨勬爣绛鹃〉璁$畻
+const currentApproveType = computed(() => {
+	return Number(activeTab.value);
+});
+
+// 鏍囩椤靛垏鎹㈠鐞�
+const handleTabChange = (tabName) => {
+	// 鍒囨崲鏍囩椤垫椂閲嶇疆鎼滅储鏉′欢鍜屽垎椤碉紝骞堕噸鏂板姞杞芥暟鎹�
+	searchForm.value.approveId = '';
+	searchForm.value.approveStatus = '';
+	page.current = 1;
+	getList();
+};
+
+
+const data = reactive({
+	searchForm: {
+		approveId: "",
+		approveStatus: "",
+	},
+});
+const { searchForm } = toRefs(data);
+
+// 鍔ㄦ�佽〃鏍煎垪閰嶇疆锛屾牴鎹鎵圭被鍨嬬敓鎴愬垪
+const tableColumnCopy = computed(() => {
+	const isLeaveType = currentApproveType.value === 2; // 璇峰亣绠$悊
+	const isReimburseType = currentApproveType.value === 4; // 鎶ラ攢绠$悊
+	const isQuotationType = currentApproveType.value === 6; // 鎶ヤ环瀹℃壒
+	const isSalesType = currentApproveType.value === 9; // 閿�鍞鎵�
+	const isFreeType = currentApproveType.value === 10; // 鑷敱鍗忓悓瀹℃壒
+	
+	// 鍩虹鍒楅厤缃�
+	const baseColumns = [
+		{
+			label: "瀹℃壒鐘舵��",
+			prop: "approveStatus",
+			dataType: "tag",
+			width: 100,
+			formatData: (params) => {
+				if (params == 0) {
+					return "寰呭鏍�";
+				} else if (params == 1) {
+					return "瀹℃牳涓�";
+				} else if (params == 2) {
+					return "瀹℃牳瀹屾垚";
+				} else if (params == 4) {
+					return "宸查噸鏂版彁浜�";
+				} else {
+					return '涓嶉�氳繃';
+				}
+			},
+			formatType: (params) => {
+				if (params == 0) {
+					return "warning";
+				} else if (params == 1) {
+					return "primary";
+				} else if (params == 2) {
+					return "success";
+				} else if (params == 4) {
+					return "info";
+				} else {
+					return 'danger';
+				}
+			},
+		},
+		{
+			label: "娴佺▼缂栧彿",
+			prop: "approveId",
+			width: 170
+		},
+		{
+			label: "鐢宠閮ㄩ棬",
+			prop: "approveDeptName",
+			width: 220
+		},
+		// 瀹℃壒鏍囬锛堜粎鑷敱鍗忓悓瀹℃壒鏄剧ず锛�
+		...(isFreeType ? [{
+			label: "瀹℃壒鏍囬",
+			prop: "approveTitle",
+			width: 200
+		}] : []),
+		{
+			label: isQuotationType ? "鎶ヤ环鍗曞彿" : (isSalesType ? "閿�鍞悎鍚屽彿" : "瀹℃壒浜嬬敱"),
+			prop: "approveReason",
+			width: 200
+		},
+		{
+			label: "鐢宠浜�",
+			prop: "approveUserName",
+			width: 120
+		}
+	];
+	
+	// 閲戦鍒楋紙浠呮姤閿�绠$悊鏄剧ず锛�
+	if (isReimburseType) {
+		baseColumns.push({
+			label: "閲戦锛堝厓锛�",
+			prop: "price",
+			width: 120
+		});
+	}
+	
+	// 鏃ユ湡鍒楋紙鏍规嵁绫诲瀷鍔ㄦ�侀厤缃級
+	baseColumns.push(
+		{
+			label: isLeaveType ? "寮�濮嬫棩鏈�" : "鐢宠鏃ユ湡",
+			prop: isLeaveType ? "startDate" : "approveTime",
+			width: 200
+		},
+		{
+			label: "缁撴潫鏃ユ湡",
+			prop: isLeaveType ? "endDate" : "approveOverTime",
+			width: 120
+		}
+	);
+	
+	// 褰撳墠瀹℃壒浜哄垪
+	baseColumns.push({
+		label: "褰撳墠瀹℃壒浜�",
+		prop: "approveUserCurrentName",
+		width: 120
+	});
+	
+	// 鎿嶄綔鍒�
+	baseColumns.push({
+		dataType: "action",
+		label: "鎿嶄綔",
+		align: "center",
+		fixed: "right",
+		width: 230,
+		operation: [
+			{
+				name: "缂栬緫",
+				type: "text",
+				clickFun: (row) => {
+					openForm("edit", row);
+				},
+				disabled: (row) => currentApproveType.value === 6 || row.approveStatus == 2 || row.approveStatus == 1 || row.approveStatus == 4
+			},
+			{
+				name: "瀹℃牳",
+				type: "text",
+				clickFun: (row) => {
+					openApprovalDia("approval", row);
+				},
+				disabled: (row) => row.approveUserCurrentId == null || row.approveStatus == 2 || row.approveStatus == 3 || row.approveStatus == 4 || row.approveUserCurrentId !== userStore.id
+			},
+			{
+				name: "璇︽儏",
+				type: "text",
+				clickFun: (row) => {
+					openApprovalDia('view', row);
+				},
+			},
+			{
+				name: "闄勪欢",
+				type: "text",
+				clickFun: (row) => {
+					downLoadFile(row);
+				},
+			},
+		],
+	});
+	
+	return baseColumns;
+});
+const tableData = ref([]);
+const selectedRows = ref([]);
+const tableLoading = ref(false);
+const page = reactive({
+	current: 1,
+	size: 100,
+	total: 0
+});
+const infoFormDia = ref()
+const approvalDia = ref()
+const { proxy } = getCurrentInstance()
+
+// 鏌ヨ鍒楄〃
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+const handleQuery = () => {
+	page.current = 1;
+	getList();
+};
+const fileListRef = ref(null)
+const downLoadFile = (row) => {
+	fileListRef.value.open(row.commonFileList)
+	
+}
+const pagination = (obj) => {
+	page.current = obj.page;
+	page.size = obj.limit;
+	getList();
+};
+const getList = () => {
+	tableLoading.value = true;
+	approveProcessListPage({...page, ...searchForm.value, approveType: currentApproveType.value}).then(res => {
+		tableLoading.value = false;
+		tableData.value = res.data.records
+		page.total = res.data.total;
+	}).catch(err => {
+		tableLoading.value = false;
+	})
+};
+// 瀵煎嚭
+const handleOut = () => {
+	const type = currentApproveType.value
+	const urlMap = {
+		0: "/approveProcess/exportZero",
+		1: "/approveProcess/exportOne",
+		2: "/approveProcess/exportTwo",
+		3: "/approveProcess/exportThree",
+		4: "/approveProcess/exportFour",
+		5: "/approveProcess/exportFive",
+		6: "/approveProcess/exportSix",
+		7: "/approveProcess/exportSeven",
+		9: "/approveProcess/exportEight",
+		10: "/approveProcess/exportNine",
+	}
+	const url = urlMap[type] || urlMap[0]
+	const nameMap = {
+		0: "鍗忓悓瀹℃壒绠$悊琛�",
+		1: "鍏嚭绠$悊瀹℃壒琛�",
+		2: "璇峰亣绠$悊瀹℃壒琛�",
+		3: "鍑哄樊绠$悊瀹℃壒琛�",
+		4: "鎶ラ攢绠$悊瀹℃壒琛�",
+		5: "閲囪喘鐢宠瀹℃壒琛�",
+		6: "鎶ヤ环瀹℃壒琛�",
+		7: "鍑哄簱瀹℃壒琛�",
+		9: "閿�鍞鎵硅〃",
+		10: "鑷敱鍗忓悓瀹℃壒琛�",
+	}
+	const fileName = nameMap[type] || nameMap[0]
+	proxy.download(url, {}, `${fileName}.xlsx`)
+}
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+	selectedRows.value = selection;
+};
+
+// 鎵撳紑鏂板銆佺紪杈戝脊妗�
+const openForm = (type, row) => {
+	nextTick(() => {
+		infoFormDia.value?.openDialog(type, row)
+	})
+};
+// 鎵撳紑鏂板妫�楠屽脊妗�
+const openApprovalDia = (type, row) => {
+	nextTick(() => {
+		approvalDia.value?.openDialog(type, row)
+	})
+};
+
+// 鍒犻櫎
+const handleDelete = () => {
+	let ids = [];
+	if (selectedRows.value.length > 0) {
+		ids = selectedRows.value.map((item) => item.approveId);
+	} else {
+		proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+		return;
+	}
+	ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
+		confirmButtonText: "纭",
+		cancelButtonText: "鍙栨秷",
+		type: "warning",
+	})
+		.then(() => {
+			approveProcessDelete(ids).then((res) => {
+				proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+				getList();
+			});
+		})
+		.catch(() => {
+			proxy.$modal.msg("宸插彇娑�");
+		});
+};
+onMounted(() => {
+	// 鏍规嵁URL鍙傛暟璁剧疆鏍囩椤靛拰鏌ヨ鏉′欢
+	const approveType = route.query.approveType;
+	const approveId = route.query.approveId;
+	
+	if (approveType) {
+		// 璁剧疆鏍囩椤碉紙approveType 瀵瑰簲 activeTab 鐨� name锛�
+		activeTab.value = String(approveType);
+	}
+	
+	if (approveId) {
+		// 璁剧疆娴佺▼缂栧彿鏌ヨ鏉′欢
+		searchForm.value.approveId = String(approveId);
+	}
+	
+	// 鏌ヨ鍒楄〃
+	getList();
+});
+</script>
+
+<style scoped>
+.approval-tabs {
+	margin-bottom: 10px;
+}
+</style>
diff --git a/src/pages/index.vue b/src/pages/index.vue
index b7d3fa9..8d3d8fb 100644
--- a/src/pages/index.vue
+++ b/src/pages/index.vue
@@ -235,7 +235,7 @@
 
 // 瀹㈡埛鍚堝悓閲戦鍒嗘瀽锛氭棤闇�绛涢�夐」锛堟寜鎺ュ彛榛樿杩斿洖灞曠ず锛�
 
-const { triggerVersionCheck } = createVersionUpgradeChecker({ logPrefix: "[version-index]" });
+// const { triggerVersionCheck } = createVersionUpgradeChecker({ logPrefix: "[version-index]" });
 
 function toggleOverview() {
   overviewExpanded.value = !overviewExpanded.value;
@@ -447,12 +447,12 @@
   } catch (e) {
     isCanvas2d.value = false;
   }
-  triggerVersionCheck("onMounted");
+  // triggerVersionCheck("onMounted");
   loadHome();
 });
 
 onShow(() => {
-  triggerVersionCheck("onShow");
+  // triggerVersionCheck("onShow");
 });
 </script>
 
diff --git a/src/pages/indexItem.vue b/src/pages/indexItem.vue
index 61f6c15..f136f04 100644
--- a/src/pages/indexItem.vue
+++ b/src/pages/indexItem.vue
@@ -55,9 +55,11 @@
     "璇峰亣绠$悊": "/pages/cooperativeOffice/collaborativeApproval/index2",
     "鍑哄樊绠$悊": "/pages/cooperativeOffice/collaborativeApproval/index3",
     "鎶ラ攢绠$悊": "/pages/cooperativeOffice/collaborativeApproval/index4",
-    "閲囪喘瀹℃壒": "/pages/cooperativeOffice/collaborativeApproval/index5",
+    "閲囪喘璁″垝瀹℃壒": "/pages/cooperativeOffice/collaborativeApproval/index5",
     "鎶ヤ环瀹℃壒": "/pages/cooperativeOffice/collaborativeApproval/index6",
-    "鍙戣揣瀹℃壒": "/pages/cooperativeOffice/collaborativeApproval/index7",
+    "鍑哄簱瀹℃壒": "/pages/cooperativeOffice/collaborativeApproval/index7",
+    "閿�鍞鎵�": "/pages/cooperativeOffice/collaborativeApproval/index?approveType=9",
+    "鑷敱鍗忓悓瀹℃壒": "/pages/cooperativeOffice/collaborativeApproval/index?approveType=10",
     "鍗忓悓瀹℃壒": "/pages/cooperativeOffice/collaborativeApproval/index",
     "浼氳璁剧疆": "/pages/managementMeetings/meetingSettings/index",
     "浼氳鍒楄〃": "/pages/managementMeetings/meetingList/index",
@@ -106,9 +108,11 @@
       { icon: "/static/images/icon/qingjiaguanli.svg", label: "璇峰亣绠$悊" },
       { icon: "/static/images/icon/chuchaiguanli.svg", label: "鍑哄樊绠$悊" },
       { icon: "/static/images/icon/baoxiaoguanli.svg", label: "鎶ラ攢绠$悊" },
-      { icon: "/static/images/icon/caigouguanli.svg", label: "閲囪喘瀹℃壒" },
-      { icon: "/static/images/icon/baojiaguanli.svg", label: "鎶ヤ环瀹℃壒" },
-      { icon: "/static/images/icon/fahuoguanli.svg", label: "鍙戣揣瀹℃壒" },
+      { icon: "/static/images/icon/caigouguanli.svg", label: "閲囪喘璁″垝瀹℃壒" },
+      // { icon: "/static/images/icon/baojiaguanli.svg", label: "鎶ヤ环瀹℃壒" },
+      { icon: "/static/images/icon/fahuoguanli.svg", label: "鍑哄簱瀹℃壒" },
+      { icon: "/static/images/icon/fahuoguanli.svg", label: "閿�鍞鎵�" },
+      { icon: "/static/images/icon/fahuoguanli.svg", label: "鑷敱鍗忓悓瀹℃壒" },
     ],
   };
 
diff --git a/src/pages/works.vue b/src/pages/works.vue
index 8d37e74..78d9d00 100644
--- a/src/pages/works.vue
+++ b/src/pages/works.vue
@@ -280,7 +280,7 @@
   import useUserStore from "@/store/modules/user";
 
   const userStore = useUserStore();
-  const { triggerVersionCheck } = createVersionUpgradeChecker({ logPrefix: "[version-works]" });
+  // const { triggerVersionCheck } = createVersionUpgradeChecker({ logPrefix: "[version-works]" });
   const show = ref(false);
   const factoryList = ref([]);
   const factoryListTem = ref([]);
@@ -483,30 +483,30 @@
       icon: "/static/images/icon/xietongshenpi.svg",
       label: "鍗忓悓瀹℃壒",
     },
-    {
-      icon: "/static/images/icon/huiyiguanli.svg",
-      label: "浼氳绠$悊",
-    },
-    {
-      icon: "/static/images/icon/tongzhigonggao.svg",
-      label: "閫氱煡鍏憡",
-    },
-    {
-      icon: "/static/images/icon/zhishiku.svg",
-      label: "鐭ヨ瘑搴�",
-    },
-    {
-      icon: "/static/images/icon/yongyinguanli.svg",
-      label: "鐢ㄥ嵃绠$悊",
-    },
-    {
-      icon: "/static/images/icon/guizhangzhidu.svg",
-      label: "瑙勭珷鍒跺害",
-    },
-    {
-      icon: "/static/images/icon/kehubaifang.svg",
-      label: "瀹㈡埛鎷滆",
-    },
+    // {
+    //   icon: "/static/images/icon/huiyiguanli.svg",
+    //   label: "浼氳绠$悊",
+    // },
+    // {
+    //   icon: "/static/images/icon/tongzhigonggao.svg",
+    //   label: "閫氱煡鍏憡",
+    // },
+    // {
+    //   icon: "/static/images/icon/zhishiku.svg",
+    //   label: "鐭ヨ瘑搴�",
+    // },
+    // {
+    //   icon: "/static/images/icon/yongyinguanli.svg",
+    //   label: "鐢ㄥ嵃绠$悊",
+    // },
+    // {
+    //   icon: "/static/images/icon/guizhangzhidu.svg",
+    //   label: "瑙勭珷鍒跺害",
+    // },
+    // {
+    //   icon: "/static/images/icon/kehubaifang.svg",
+    //   label: "瀹㈡埛鎷滆",
+    // },
   ]);
 
   // 鐢熶骇绠℃帶鍔熻兘鏁版嵁
@@ -1155,7 +1155,7 @@
   const hasEquipmentItems = computed(() => equipmentItems.length > 0);
 
   onMounted(() => {
-    triggerVersionCheck("onMounted");
+    // triggerVersionCheck("onMounted");
     // 姣忔杩涘叆棣栭〉閮藉己鍒跺埛鏂扮敤鎴蜂俊鎭拰璺敱鏉冮檺锛屼笉鍋氭湰鍦扮紦瀛樺垽鏂�
     userStore.getInfo().then(() => {
       userStore

--
Gitblit v1.9.3