From bfbb1ea3c6bb2dd7db064fb189290a1bfcf6c9cd Mon Sep 17 00:00:00 2001
From: seatonwan9
Date: 星期四, 28 八月 2025 02:14:48 +0800
Subject: [PATCH] 提交源码

---
 src/views/productManage/productPriceViewer/index.vue |  308 ++++++++++++++++++++++++++++++--------------------
 1 files changed, 184 insertions(+), 124 deletions(-)

diff --git a/src/views/productManage/productPriceViewer/index.vue b/src/views/productManage/productPriceViewer/index.vue
index a559117..71022ee 100644
--- a/src/views/productManage/productPriceViewer/index.vue
+++ b/src/views/productManage/productPriceViewer/index.vue
@@ -1,12 +1,5 @@
 <template>
-  <el-dialog
-    v-model="visible"
-    :title="dialogTitle"
-    :before-close="handleClose"
-    destroy-on-close
-    class="product-price-dialog"
-    :width="dialogWidth"
-  >
+   <div>
     <div class="price-viewer-container" v-loading="loading">
       <!-- 浠锋牸瀵规瘮琛ㄦ牸 -->
       <div class="pricing-table-container" v-if="showPricePanel && priceList.length > 0">
@@ -19,7 +12,7 @@
           >
             <div class="pricing-table-wrapper">
               <table class="pricing-table">
-                 <thead>
+                                 <thead>
                    <tr>
                      <th class="feature-column">鍔熻兘瀵规瘮</th>
                      <th 
@@ -174,19 +167,19 @@
               <span class="label">浜у搧鍚嶇О锛�</span><span class="value strong">{{ productHeader.name }}</span>
             </div>
             <div class="grid-item">
-              <span class="label">琛屼笟鏉垮潡锛�</span><span class="value">{{ productHeader.industry }}</span>
+              <span class="label">琛屼笟鏉垮潡锛�</span><span class="value">{{ productHeader.industrialChainName }}</span>
             </div>
             <div class="grid-item">
-              <span class="label">鎻愪緵鑰咃細</span><span class="value">{{ productHeader.provider }}</span>
+              <span class="label">鎻愪緵鑰咃細</span><span class="value">{{ productHeader.submissionUnit }}</span>
             </div>
             <div class="grid-item">
               <span class="label">鐢ㄦ埛濮撳悕锛�</span><span class="value">{{ userInfo.name }}</span>
             </div>
             <div class="grid-item">
-              <span class="label">鍗曚綅锛�</span><span class="value">{{ userInfo.unit }}</span>
+              <span class="label">鍗曚綅锛�</span><span class="value">{{ userInfo.unitName }}</span>
             </div>
             <div class="grid-item">
-              <span class="label">閮ㄩ棬锛�</span><span class="value">{{ userInfo.department }}</span>
+              <span class="label">閮ㄩ棬锛�</span><span class="value">{{ userInfo.departmentName }}</span>
             </div>
           </div>
         </el-card>
@@ -338,32 +331,29 @@
         <el-empty description="鏆傛棤浠锋牸淇℃伅" />
       </div>
     </div>
-
-    <template #footer v-if="!showOrderStatus">
-      <span class="dialog-footer">
-        <template v-if="showPricePanel">
-        <el-button @click="handleClose">鍏抽棴</el-button>
-        <el-button type="primary" @click="handleOrder">绔嬪嵆璁㈣喘</el-button>
-        </template>
-        <template v-else>
-          <el-button @click="returnPricePanel">杩斿洖浠锋牸瀵规瘮</el-button>
-          <el-button type="primary" @click="submitOrder">鎻愪氦鐢宠</el-button>
-        </template>
-      </span>
-    </template>
-  </el-dialog>
+    <div class="footer" v-if="showPricePanel">
+     <el-button type="primary" @click="handleOrder">绔嬪嵆璁㈣喘</el-button>
+    </div>
+    <div class="footer" v-else>
+      <el-button @click="returnPricePanel">杩斿洖浠锋牸瀵规瘮</el-button>
+      <el-button type="primary" @click="submitOrder">鎻愪氦鐢宠</el-button>
+    </div>
+  </div>
 
   <!-- 浜у搧璁㈣喘瀵硅瘽妗嗙Щ闄わ紝鏀逛负鍐呭祵灞曠ず -->
 </template>
 
 <script setup lang="ts">
-import { ref, watch, computed } from 'vue'
+import { ref, watch, computed, onMounted } from 'vue'
 import { ElMessage } from 'element-plus'
 import { useRoute } from 'vue-router'
 import productPricingApi from '@/api/productPricingApi'
 import cartApi from '@/api/cartApi'
 import orderApi from '@/api/orderApi'
 import { ShoppingCart, Coin, Money } from '@element-plus/icons-vue'
+import { useUserInfo } from '@/stores/modules/userInfo'
+import { queryUserDetail } from '@/api/userInfo'
+import productApi from '@/api/productApi'
 
 const route = useRoute()
 
@@ -384,36 +374,11 @@
   enableStatus: 'ENABLED' | 'DISABLED'
 }
 
-interface Props {
-  modelValue: boolean
-  productId?: string
-  width?: string
-}
-
-interface Emits {
-  (e: 'update:modelValue', value: boolean): void
-  (e: 'order', selectedItems: PriceItem[]): void
-}
-
 // 鍏煎 path 鍙傛暟 productId 涓� query 鍙傛暟 id/productId
 const currentProductId = computed<string | undefined>(() => {
   return (route.params.productId as string) || (route.query.productId as string) || (route.query.id as string)
 })
 
-
-const props = withDefaults(defineProps<Props>(), {
-  modelValue: false,
-  productId: '',
-  width: '90%'
-})
-
-
-const emit = defineEmits<Emits>()
-
-const visible = computed({
-  get: () => props.modelValue,
-  set: (value) => emit('update:modelValue', value)
-})
 
 const loading = ref(false)
 const activeTab = ref('enterprise')
@@ -424,8 +389,32 @@
 const showPricePanel = ref(true)
 const showOrderStatus = ref(false)
 // 妯℃嫙鐢ㄦ埛淇℃伅锛堝疄闄呭簲浠庣敤鎴风姸鎬佽幏鍙栵級
-const currentUserId = ref(1)
-const currentUnitId = ref(1)
+const userStore = useUserInfo()
+let currentUserId = computed(() => userStore.getUserId || userStore.getUserInfo?.userId)
+const currentUnitId = computed(() => userStore.getUnitId || userStore.getUserInfo?.unitId || '')
+
+onMounted(async () => {
+  if (!currentUserId.value) {
+    try {
+      const res: any = await queryUserDetail()
+      if (res?.code === 200 && res.data) {
+        userStore.updateUserDetail(res.data)
+        currentUserId = res.data.userId || res.data.id
+        userInfo.value = res.data
+      } else {
+        ElMessage.error(res?.msg || '鏃犳硶鑾峰彇鐢ㄦ埛淇℃伅锛岃鍏堢櫥褰�')
+        return
+      }
+    } catch (e) {
+      console.error('鑾峰彇鐢ㄦ埛璇︽儏澶辫触:', e)
+      ElMessage.error('鑾峰彇鐢ㄦ埛淇℃伅澶辫触锛岃绋嶅悗閲嶈瘯')
+      return
+    }
+  }else{
+    userInfo.value = userStore.getUserInfos
+  }
+  
+})
 type PriceTypeKey = 'POINTS' | 'CURRENCY' | 'AGREEMENT' | 'FREE'
 interface OrderSuite extends PriceItem {
   selected: boolean
@@ -513,14 +502,15 @@
 
 // 浜у搧淇℃伅/鐢ㄦ埛淇℃伅锛堥潤鎬侊級
 const productHeader = ref({
-  name: '涓氦鏂硅繙鏅鸿兘瀹炴祴瀹為噺绠$悊绯荤粺',
-  industry: '鍏矾,甯傛斂,寤虹瓚',
-  provider: '涓氦寤虹瓚闆嗗洟绗竴宸ョ▼鏈夐檺鍏徃'
+  name: '',
+  industrialChainName: '',
+  submissionUnit: '',
+  createUserId: ''
 })
 const userInfo = ref({
-  name: '寮犻潤',
-  unit: '淇$闆嗗洟',
-  department: '闂ㄦ埛绯荤粺涓存椂缁�'
+  name: '',
+  departmentName: '',
+  unitName: ''
 })
 
 // 鍏ㄩ��
@@ -551,7 +541,7 @@
   const suite = orderSuites.value[index]
   if (!suite) return
   try {
-    await removeFromCart(suite.id)
+    await removeFromCart(String(suite.id))
     orderSuites.value.splice(index, 1)
   } catch (e) {
   }
@@ -563,8 +553,6 @@
   ElMessage.success('璁㈣喘鐢宠鎻愪氦鎴愬姛锛�')
   // 娓呯┖閫夋嫨鐘舵��
   selectedSuiteIds.value.clear()
-  // 鍏抽棴浠锋牸鏌ョ湅鍣�
-  visible.value = false
 }
 
 // 寮圭獥鏍囬
@@ -572,10 +560,6 @@
   return `銆�${productName.value}銆戜骇鍝佸畾浠穈
 })
 
-// 寮圭獥瀹藉害
-const dialogWidth = computed(() => {
-  return props.width
-})
 
 // 鎸夊鎴峰璞″垎缁勭殑浠锋牸鏁版嵁
 const groupedPriceData = computed(() => {
@@ -701,31 +685,33 @@
   } finally {
     loading.value = false
   }
+  //鑾峰彇浜у搧璇︽儏淇℃伅
+  try {
+    // productDetail.value = mockProductMap[productId] || null
+    const data = {
+      id: productId
+    }
+    const detailRes: any = await productApi.getProductById(data)
+    if (detailRes?.code === 200) {
+      productHeader.value = detailRes.data || { name: '', industrialChainName: '', submissionUnit: '', createUserId: '' }
+    } else {
+      productHeader.value = { name: '', industrialChainName: '', submissionUnit: '', createUserId: '' }
+      ElMessage.error(detailRes?.msg || '鑾峰彇浜у搧璇︽儏澶辫触')
+    }
+  } catch (e) {
+    productHeader.value = { name: '', industrialChainName: '', submissionUnit: '', createUserId: '' }
+    ElMessage.error('鑾峰彇浜у搧璇︽儏澶辫触')
+  } finally {
+    loading.value = false
+  }
 }
 
 // 鐩戝惉浜у搧ID鍙樺寲
-watch(() => props.productId, (newProductId) => {
-  if (newProductId && visible.value) {
+watch(currentProductId, (newProductId) => {
+  if (newProductId) {
     fetchProductData(newProductId)
   }
-})
-
-// 鐩戝惉寮圭獥鏄剧ず鐘舵��
-watch(() => visible.value, (newVisible) => {
-  if (newVisible && props.productId) {
-    fetchProductData(props.productId)
-  }
-})
-
-// 鍏抽棴寮圭獥
-const handleClose = () => {
-  visible.value = false
-  showOrderPanel.value = false
-  showOrderStatus.value = false
-  showPricePanel.value = true
-  orderSuites.value = []
-  selectedSuiteIds.value.clear()
-}
+},{ immediate: true })
 
 // 濂椾欢閫夋嫨澶勭悊
 const handleSuiteSelect = (suiteId: number, checked: any) => {
@@ -740,7 +726,7 @@
   } else {
     selectedSuiteIds.value.delete(suiteId)
     // 浠庤喘鐗╄溅绉婚櫎
-    removeFromCart(suiteId)
+    removeFromCart(String(suiteId))
   }
 }
 
@@ -784,24 +770,31 @@
     ElMessage.error('鏆備笉鏀寔璐у竵浜ゆ槗锛岃閫夋嫨绉垎鎴栧崗璁敮浠樻柟寮�')
     return
   }
-
+  
   if (!idempotencyToken.value) {
     ElMessage.error('涓嬪崟Token鑾峰彇澶辫触锛岃杩斿洖閲嶈瘯')
     return
   }
-
+  const hasPoints = items.some(item => item.priceType === 'POINTS')
+  const hasAGREEMENT = items.some(item => item.priceType === 'AGREEMENT')
+  let paymentType = ''
+  if(hasPoints){
+     paymentType = '绉垎'
+  }else{
+     paymentType = '鍗忚'
+  }
   // 缁勮鍒涘缓璁㈠崟鍙傛暟锛圕reateOrderDTO锛�
   const payload = {
     userId: currentUserId.value,
     unitId: currentUnitId.value,
     productName: productHeader.value.name,
-    providerName: productHeader.value.provider,
-    providerId: 3,
-    paymentType: '绉垎',
+    providerName: productHeader.value.submissionUnit,
+    providerId: productHeader.value.createUserId,
+    paymentType: paymentType,
     buyerRemarks: '',
     items: items.map(it => ({
       pricingId: it.id,
-      productId: Number(it.productId),
+      productId: it.productId,
       suiteName: getProductSuiteText(it.productSuite),
       salesForm: getSalesFormText(it.salesForm),
       customerType: getCustomerObjectText(it.customerObject),
@@ -813,8 +806,8 @@
       quantity: it.quantity,
       duration: it.duration,
       totalPrice: undefined,
-      providerId: 3,
-      providerName: productHeader.value.provider,
+      providerId: productHeader.value.createUserId,
+      providerName: productHeader.value.submissionUnit,
       remarks: ''
     }))
   }
@@ -827,11 +820,28 @@
       orderStatus.value = {
         id: data.orderId || '鈥�',
         productName: data.productName || productHeader.value.name,
-        provider: data.providerName || productHeader.value.provider,
+        provider: data.providerName || productHeader.value.submissionUnit,
         status: 'SUBMITTED',
         submitTime: data.applyTime ? String(data.applyTime) : new Date().toLocaleString(),
         applyTime: data.applyTime ? String(data.applyTime) : new Date().toLocaleString()
       }
+      // 璋冪敤宸ヤ綔娴佹帴鍙e彂璧峰鎵规祦绋嬶紝鎷垮埌娴佺▼瀹炰緥ID鍚庡洖鍐欒鍗晈orkflow_id
+      try {
+        // 鏍规嵁鏄惁鍖呭惈鍗忚鏄庣粏锛岄厤缃笉鍚屾祦绋嬪畾涔変笌涓氬姟Key锛堝厛鐢ㄩ潤鎬佸�煎崰浣嶏級
+        const processdefId = hasAGREEMENT ? 'Process_Agreement_Static' : 'Process_Points_Static'
+        const businessKey = hasAGREEMENT ? 'agreement_biz_key' : 'points_biz_key'
+        const wfRes: any = await orderApi.startWorkflowAndComplete({
+          processdefId,
+          userid: String(currentUserId.value || ''),
+          businessKey
+        })
+        if (wfRes?.code === 200 && wfRes.data?.processinstId) {
+          await orderApi.updateWorkflowId(data.orderId, wfRes.data.processinstId)
+        }
+      } catch (e) {
+        console.warn('鍚姩宸ヤ綔娴佸け璐ユ垨鏇存柊workflow_id澶辫触', e)
+      }
+
       // 娓呯┖璐墿杞︼紙鍚庣 + 鏈湴鐘舵�侊級
       try {
         const clearRes: any = await cartApi.clearCart(currentUserId.value, currentUnitId.value)
@@ -859,7 +869,7 @@
   try {
     const cartData = {
       pricingId: priceItem.id,
-      productId: Number(priceItem.productId),
+      productId: priceItem.productId,
       productName: productName.value,
       suiteName: getProductSuiteText(priceItem.productSuite),
       salesForm: getSalesFormText(priceItem.salesForm),
@@ -885,7 +895,7 @@
   }
 }
 
-const removeFromCart = async (pricingId: number) => {
+const removeFromCart = async (pricingId: string) => {
   try {
     const res: any = await cartApi.removeFromCart(currentUserId.value, currentUnitId.value, pricingId)
     if (res?.code === 200) {
@@ -1084,29 +1094,65 @@
   .pricing-table-container {
     .pricing-tabs {
       :deep(.el-tabs__header) {
-        margin-bottom: 5px;
+        margin-bottom: 12px;
       }
-      
+      /* 灞呬腑 tabs 瀵艰埅 */
+      :deep(.el-tabs__nav-wrap) {
+        display: flex;
+        justify-content: center;
+      }
+      :deep(.el-tabs__nav) {
+        margin: 0 auto;
+        border: none !important;
+      }
+      /* 鍗$墖鍨� tabs 缇庡寲涓哄渾瑙掕兌鍥婃晥鏋� */
+      :deep(.el-tabs--card > .el-tabs__header .el-tabs__nav) {
+        border: none;
+      }
+      :deep(.el-tabs--card > .el-tabs__header .el-tabs__item) {
+        border: none;
+      }
+      :deep(.el-tabs__item) {
+        border-radius: 999px;
+        padding: 8px 18px;
+        margin: 0 6px;
+        color: #606266;
+        background: #f6f8fb;
+        transition: all .2s ease;
+      }
+      :deep(.el-tabs__item:hover) {
+        color: #3a7afe;
+        background: #eff4ff;
+      }
       :deep(.el-tabs__item.is-active) {
-        font-weight: bold;
+        font-weight: 600;
+        color: #fff;
+        background: #3a7afe;
+        box-shadow: 0 6px 16px rgba(58, 122, 254, 0.25);
       }
     }
 
     .pricing-table-wrapper {
       overflow-x: auto;
+      background: #fff;
+      border-radius: 12px;
+      box-shadow: 0 6px 24px rgba(0, 0, 0, 0.06);
+      padding: 8px;
       
       .pricing-table {
         width: 100%;
-        border-collapse: collapse;
-        border: 1px solid #e4e7ed;
+        border-collapse: separate;
+        border-spacing: 0;
         background: #fff;
+        border-radius: 10px;
         
         th, td {
-          border: 1px solid #e4e7ed;
-          padding: 6px 8px;
+          border-bottom: 1px solid #eef2f7;
+          border-right: 1px solid #f3f5f7;
+          padding: 12px 14px;
           text-align: center;
           vertical-align: middle;
-          font-size: 16px;
+          font-size: 14px;
         }
         tr th:first-child, td:first-child{
           font-weight: 700;
@@ -1114,7 +1160,7 @@
         }
         
         th {
-          background-color: #f5f7fa;
+          background: linear-gradient(180deg, #f7f9fc 0%, #eef2f7 100%);
           font-weight: 600;
           color: #303133;
         }
@@ -1126,9 +1172,9 @@
         
         .sub-header {
           th {
-            background-color: #fafafa;
+            background-color: #f8fafc;
             font-weight: 500;
-              font-size: 16px;
+            font-size: 13px;
             color: #606266;
           }
         }
@@ -1141,26 +1187,34 @@
         }
         
         .feature-value {
-          color: #606266;
-          background: #fafafa; /* 琛屼负鐏拌壊 */
+          color: #303133;
+          background: #fff;
+        }
+
+        tbody tr:hover td {
+          background: #fafcff;
         }
         
         .order-methods {
           display: flex;
           flex-direction: column;
-          gap: 4px;
+          gap: 6px;
           align-items: center;
           
           .method-item {
-            font-size: 16px;
-            color: #409eff;
+            font-size: 12px;
+            color: #3a7afe;
+            background: #f4f7ff;
+            border: 1px solid #e3ebff;
+            border-radius: 999px;
+            padding: 2px 10px;
           }
         }
         
         .price-info {
           display: flex;
           flex-direction: column; /* 绔栨帓 */
-          gap: 8px;
+          gap: 10px;
           align-items: center;
           
           .price-item {
@@ -1168,24 +1222,29 @@
             align-items: flex-start;
             flex-direction: column;
             gap: 6px;
+            padding: 10px 12px;
+            border: 1px solid #f0f2f5;
+            border-radius: 10px;
+            background: #fff;
+            box-shadow: inset 0 -1px 0 rgba(0,0,0,0.02);
             .price-lable-icon{
               display: flex;
               gap: 6px;
             }
             .price-label {
-              font-size: 16px;
-              color: #606266;
+              font-size: 12px;
+              color: #909399;
             }
             
             .price-value {
-              font-weight: 500;
-              font-size: 20px;
+              font-weight: 600;
+              font-size: 18px;
               &.points {
                 color: #e7900d;
               }
               
               &.currency {
-                color: #e7900d;
+                color: #10b981;
               }
               
               &.free {
@@ -1193,7 +1252,7 @@
               }
             }
             .price-icon.points { color: #e6a23c; }
-            .price-icon.currency { color: #e7900d; }
+            .price-icon.currency { color: #16a34a; }
           }
           
                      .add-checkbox {
@@ -1206,7 +1265,7 @@
            justify-content: center;
            align-items: center;
            padding: 8px 0;
-           .add-cart-icon { color: #409eff; font-size:22px}
+           .add-cart-icon { color: #3a7afe; font-size:22px}
          }
       }
     }
@@ -1348,4 +1407,5 @@
 .order-summary .summary-value.highlight{ color:#409eff; }
 .order-summary .summary-value.total{ color:#e6a23c; }
 .order-summary .summary-value.currency{ color:#f56c6c; }
+.footer { display: flex; flex-direction: row-reverse; margin-right: 50px; gap: 50px; margin-top: 20px;}
 </style>

--
Gitblit v1.8.0