From 2122e30c435e4287a035162aee4469a8e558f408 Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期三, 22 四月 2026 13:43:56 +0800
Subject: [PATCH] 新增采购详情和产品明细展示功能

---
 src/pages/cooperativeOffice/collaborativeApproval/approve.vue |  376 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 372 insertions(+), 4 deletions(-)

diff --git a/src/pages/cooperativeOffice/collaborativeApproval/approve.vue b/src/pages/cooperativeOffice/collaborativeApproval/approve.vue
index 161176f..751dde9 100644
--- a/src/pages/cooperativeOffice/collaborativeApproval/approve.vue
+++ b/src/pages/cooperativeOffice/collaborativeApproval/approve.vue
@@ -25,6 +25,139 @@
           <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">
+            <text class="info-label">璇峰亣寮�濮嬫椂闂�</text>
+            <text class="info-value">{{ approvalData.startDate || '-' }}</text>
+          </view>
+          <view class="info-row">
+            <text class="info-label">璇峰亣缁撴潫鏃堕棿</text>
+            <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>
+
+    <!-- 鍏ュ簱璇︽儏 -->
+    <view v-if="approvalData.approveType === 9" class="stockin-info">
+      <view class="info-header stockin-header" @click="toggleStockInCollapse">
+        <text class="info-title">鍏ュ簱璇︽儏</text>
+        <text class="collapse-text">{{ stockInCollapsed ? '灞曞紑' : '鏀惰捣' }}</text>
+      </view>
+      <view v-show="!stockInCollapsed" class="stockin-table">
+        <view class="stockin-row">
+          <text class="stockin-label">閿�鍞悎鍚屽彿</text>
+          <text class="stockin-value">{{ stockInOrderInfoData.salesContractNo || '-' }}</text>
+          <text class="stockin-label">瀹㈡埛鍚嶇О</text>
+          <text class="stockin-value">{{ stockInOrderInfoData.customerName || stockInOrderInfoData.supplierName || '-' }}</text>
+        </view>
+        <view class="stockin-row">
+          <text class="stockin-label">椤圭洰鍚嶇О</text>
+          <text class="stockin-value">{{ stockInOrderInfoData.projectName || '-' }}</text>
+          <text class="stockin-label">涓氬姟鍛�</text>
+          <text class="stockin-value">{{ stockInOrderInfoData.businessUserName || stockInOrderInfoData.recorderName || '-' }}</text>
+        </view>
+        <view v-for="(product, index) in stockInProducts" :key="product.id || index">
+          <view class="stockin-row">
+            <text class="stockin-label">浜у搧鍚嶇О</text>
+            <text class="stockin-value">{{ product.speculativeTradingName || product.productCategory || '-' }}</text>
+            <text class="stockin-label">瑙勬牸鍨嬪彿</text>
+            <text class="stockin-value">{{ product.specificationModel || '-' }}</text>
+          </view>
+          <view class="stockin-row">
+            <text class="stockin-label">鍗曚綅</text>
+            <text class="stockin-value">{{ product.unit || '-' }}</text>
+            <text class="stockin-label">鏁伴噺</text>
+            <text class="stockin-value">{{ product.quantity ?? '-' }}</text>
+          </view>
+        </view>
+        <view v-if="!stockInProducts.length" class="stockin-row">
+          <text class="stockin-label">浜у搧鍚嶇О</text>
+          <text class="stockin-value">-</text>
+          <text class="stockin-label">瑙勬牸鍨嬪彿</text>
+          <text class="stockin-value">-</text>
+        </view>
+        <view v-if="!stockInProducts.length" class="stockin-row">
+          <text class="stockin-label">鍗曚綅</text>
+          <text class="stockin-value">-</text>
+          <text class="stockin-label">鏁伴噺</text>
+          <text class="stockin-value">-</text>
+        </view>
+      </view>
+    </view>
+
+    <!-- 閲囪喘璇︽儏 -->
+    <view v-if="approvalData.approveType === 5" class="purchase-info">
+      <view class="info-header purchase-header" @click="togglePurchaseCollapse">
+        <text class="info-title">閲囪喘璇︽儏</text>
+        <text class="collapse-text">{{ purchaseCollapsed ? '灞曞紑' : '鏀惰捣' }}</text>
+      </view>
+      <view v-show="!purchaseCollapsed" class="purchase-table">
+        <view class="purchase-row">
+          <text class="purchase-label">閲囪喘鍚堝悓鍙�</text>
+          <text class="purchase-value">{{ purchaseInfoData.purchaseContractNumber || extractPurchaseContractNumber() || '-' }}</text>
+          <text class="purchase-label">渚涘簲鍟嗗悕绉�</text>
+          <text class="purchase-value">{{ purchaseInfoData.supplierName || '-' }}</text>
+        </view>
+        <view class="purchase-row">
+          <text class="purchase-label">椤圭洰鍚嶇О</text>
+          <text class="purchase-value">{{ purchaseInfoData.projectName || '-' }}</text>
+          <text class="purchase-label">閿�鍞悎鍚屽彿</text>
+          <text class="purchase-value">{{ purchaseInfoData.salesContractNo || '-' }}</text>
+        </view>
+        <view class="purchase-row">
+          <text class="purchase-label">绛捐鏃ユ湡</text>
+          <text class="purchase-value">{{ purchaseInfoData.executionDate || purchaseInfoData.signDate || '-' }}</text>
+          <text class="purchase-label">褰曞叆鏃ユ湡</text>
+          <text class="purchase-value">{{ purchaseInfoData.entryDate || '-' }}</text>
+        </view>
+        <view class="purchase-row">
+          <text class="purchase-label">浠樻鏂瑰紡</text>
+          <text class="purchase-value">{{ purchaseInfoData.paymentMethod || '-' }}</text>
+          <text class="purchase-label">鍚堝悓閲戦</text>
+          <text class="purchase-value amount">{{ formatMoney(purchaseInfoData.contractAmount || purchaseInfoData.totalAmount) }}</text>
+        </view>
+      </view>
+    </view>
+
+    <!-- 浜у搧鏄庣粏 -->
+    <view v-if="approvalData.approveType === 5" class="purchase-info">
+      <view class="info-header purchase-header" @click="togglePurchaseProductCollapse">
+        <text class="info-title">浜у搧鏄庣粏</text>
+        <text class="collapse-text">{{ purchaseProductCollapsed ? '灞曞紑' : '鏀惰捣' }}</text>
+      </view>
+      <view v-show="!purchaseProductCollapsed" class="product-table">
+        <view class="product-head">
+          <text class="product-cell">浜у搧鍚嶇О</text>
+          <text class="product-cell">瑙勬牸鍨嬪彿</text>
+          <text class="product-cell">鍗曚綅</text>
+          <text class="product-cell">鏁伴噺</text>
+          <text class="product-cell">鍚◣鍗曚环</text>
+          <text class="product-cell">鍚◣鎬讳环</text>
+        </view>
+        <view v-for="(product, idx) in purchaseProducts" :key="product.id || idx" class="product-body-row">
+          <text class="product-cell body">{{ product.productCategory || product.speculativeTradingName || '-' }}</text>
+          <text class="product-cell body">{{ product.specificationModel || '-' }}</text>
+          <text class="product-cell body">{{ product.unit || '-' }}</text>
+          <text class="product-cell body">{{ product.quantity ?? '-' }}</text>
+          <text class="product-cell body">{{ formatMoney(product.taxInclusiveUnitPrice) }}</text>
+          <text class="product-cell body">{{ formatMoney(product.taxInclusiveTotalPrice) }}</text>
+        </view>
+        <view v-if="!purchaseProducts.length" class="product-empty">鏆傛棤浜у搧鏄庣粏</view>
       </view>
     </view>
 
@@ -103,7 +236,14 @@
 
 <script setup>
 import { ref, onMounted, computed } from 'vue'
-import { approveProcessGetInfo, approveProcessDetails, updateApproveNode } from '@/api/collaborativeApproval/approvalProcess'
+import {
+  approveProcessGetInfo,
+  approveProcessDetails,
+  updateApproveNode,
+  stockInOrderInfo,
+  stockInProductList,
+  getPurchaseByCode
+} from '@/api/collaborativeApproval/approvalProcess'
 import useUserStore from '@/store/modules/user'
 const showToast = (message) => {
 	uni.showToast({
@@ -118,6 +258,13 @@
 const approvalSteps = ref([])
 const approvalOpinion = ref('')
 const approveId = ref('')
+const stockInOrderInfoData = ref({})
+const stockInProducts = ref([])
+const stockInCollapsed = ref(true)
+const purchaseInfoData = ref({})
+const purchaseProducts = ref([])
+const purchaseCollapsed = ref(true)
+const purchaseProductCollapsed = ref(true)
 
 // 浠庤鎯呮帴鍙e瓧娈靛榻� canApprove锛氫粎褰撴湁 isShen 鐨勮妭鐐规椂鍙鎵�
 const canApprove = computed(() => {
@@ -125,9 +272,7 @@
 })
 
 onMounted(() => {
-  const pages = getCurrentPages()
-  const currentPage = pages[pages.length - 1]
-  approveId.value = currentPage.options.approveId
+  approveId.value = uni.getStorageSync('approveId')
   if (approveId.value) {
     loadApprovalData()
   }
@@ -137,6 +282,20 @@
   // 鍩烘湰鐢宠淇℃伅
   approveProcessGetInfo({ id: approveId.value }).then(res => {
     approvalData.value = res.data || {}
+    if (approvalData.value.approveType === 9) {
+      loadStockInInfo()
+      purchaseInfoData.value = {}
+      purchaseProducts.value = []
+    } else if (approvalData.value.approveType === 5) {
+      loadPurchaseInfo()
+      stockInOrderInfoData.value = {}
+      stockInProducts.value = []
+    } else {
+      stockInOrderInfoData.value = {}
+      stockInProducts.value = []
+      purchaseInfoData.value = {}
+      purchaseProducts.value = []
+    }
   })
   // 瀹℃壒鑺傜偣璇︽儏
   approveProcessDetails(approveId.value).then(res => {
@@ -163,7 +322,79 @@
   })
 }
 
+const loadStockInInfo = () => {
+  const query = { approveId: approveId.value, id: approveId.value }
+  Promise.all([stockInOrderInfo(query), stockInProductList(query)])
+    .then(([orderRes, productRes]) => {
+      const orderInfo = orderRes?.data?.orderInfo || {}
+      stockInOrderInfoData.value = orderInfo
+      stockInProducts.value = Array.isArray(productRes?.data) ? productRes.data : []
+    })
+    .catch(() => {
+      stockInOrderInfoData.value = {}
+      stockInProducts.value = []
+    })
+}
+
+const toggleStockInCollapse = () => {
+  stockInCollapsed.value = !stockInCollapsed.value
+}
+
+const togglePurchaseCollapse = () => {
+  purchaseCollapsed.value = !purchaseCollapsed.value
+}
+
+const togglePurchaseProductCollapse = () => {
+  purchaseProductCollapsed.value = !purchaseProductCollapsed.value
+}
+
+const extractPurchaseContractNumber = () => {
+  const raw = approvalData.value || {}
+  const candidates = [
+    raw.purchaseContractNumber,
+    raw.purchaseLedgerNo,
+    raw.businessNo,
+    raw.contractNo
+  ]
+  const target = candidates.find(item => String(item || '').trim())
+  if (target) {
+    return String(target).trim()
+  }
+  const reason = String(raw.approveReason || '')
+  const match = reason.match(/[A-Za-z]{1,4}\d{6,}/)
+  return match ? match[0] : ''
+}
+
+const loadPurchaseInfo = () => {
+  const purchaseContractNumber = extractPurchaseContractNumber()
+  if (!purchaseContractNumber) {
+    purchaseInfoData.value = {}
+    purchaseProducts.value = []
+    return
+  }
+  getPurchaseByCode({ purchaseContractNumber })
+    .then(res => {
+      const payload = res?.data || res || {}
+      const orderInfo = payload.orderInfo || payload.purchaseInfo || payload
+      const products = payload.productData || payload.productList || payload.products || []
+      purchaseInfoData.value = orderInfo || {}
+      purchaseProducts.value = Array.isArray(products) ? products : []
+    })
+    .catch(() => {
+      purchaseInfoData.value = {}
+      purchaseProducts.value = []
+    })
+}
+
+const formatMoney = (value) => {
+  if (value === null || value === undefined || value === '') return '-'
+  const num = Number(value)
+  if (Number.isNaN(num)) return `楼${value}`
+  return `楼${num.toFixed(2)}`
+}
+
 const goBack = () => {
+  uni.removeStorageSync('approveId');
   uni.navigateBack()
 }
 
@@ -297,6 +528,143 @@
   overflow: hidden;
 }
 
+.stockin-info {
+  background: #fff;
+  margin: 16px;
+  border-radius: 12px;
+  overflow: hidden;
+}
+
+.purchase-info {
+  background: #fff;
+  margin: 16px;
+  border-radius: 12px;
+  overflow: hidden;
+}
+
+.purchase-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.purchase-table {
+  border-top: 1px solid #f0f0f0;
+}
+
+.purchase-row {
+  display: grid;
+  grid-template-columns: 18% 32% 18% 32%;
+}
+
+.purchase-label {
+  font-size: 11px;
+  color: #666;
+  padding: 12px 8px;
+  background: #f7f8fa;
+  border-right: 1px solid #f0f0f0;
+  border-bottom: 1px solid #f0f0f0;
+}
+
+.purchase-value {
+  font-size: 11px;
+  color: #333;
+  padding: 12px 8px;
+  border-right: 1px solid #f0f0f0;
+  border-bottom: 1px solid #f0f0f0;
+  word-break: break-all;
+}
+
+.purchase-value.amount {
+  color: #ed8d05;
+  font-weight: 600;
+}
+
+.purchase-row .purchase-value:last-child,
+.purchase-row .purchase-label:last-child {
+  border-right: none;
+}
+
+.product-table {
+  border-top: 1px solid #f0f0f0;
+}
+
+.product-head,
+.product-body-row {
+  display: grid;
+  grid-template-columns: 16% 16% 12% 12% 22% 22%;
+}
+
+.product-cell {
+  font-size: 10px;
+  color: #666;
+  padding: 10px 6px;
+  text-align: center;
+  background: #f7f8fa;
+  border-right: 1px solid #f0f0f0;
+  border-bottom: 1px solid #f0f0f0;
+}
+
+.product-cell.body {
+  color: #333;
+  background: #fff;
+}
+
+.product-head .product-cell:last-child,
+.product-body-row .product-cell:last-child {
+  border-right: none;
+}
+
+.product-empty {
+  font-size: 11px;
+  color: #999;
+  text-align: center;
+  padding: 20px 0;
+}
+
+.stockin-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.collapse-text {
+  font-size: 10px;
+  color: #666;
+}
+
+.stockin-table {
+  border-top: 1px solid #f0f0f0;
+}
+
+.stockin-row {
+  display: grid;
+  grid-template-columns: 22% 28% 22% 28%;
+}
+
+.stockin-label {
+  font-size: 10px;
+  color: #666;
+  padding: 12px 10px;
+  background: #f7f8fa;
+  border-right: 1px solid #f0f0f0;
+  border-bottom: 1px solid #f0f0f0;
+}
+
+.stockin-value {
+  font-size: 10px;
+  color: #333;
+  padding: 12px 10px;
+  border-right: 1px solid #f0f0f0;
+  border-bottom: 1px solid #f0f0f0;
+  word-break: break-all;
+}
+
+.stockin-row .stockin-value:last-child,
+.stockin-row .stockin-label:last-child {
+  border-right: none;
+}
+
 .process-header {
   padding: 16px;
   border-bottom: 1px solid #f0f0f0;

--
Gitblit v1.9.3