From b3fedd4221b807a07058be9d5d5d8ba8998adbcb Mon Sep 17 00:00:00 2001
From: Bang Hu <hu_bang@hotmail.com>
Date: 星期四, 11 九月 2025 21:35:31 +0800
Subject: [PATCH] Bug修改代码提交

---
 src/views/approveManage/tradeApproval/approve.vue | 1231 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 1,182 insertions(+), 49 deletions(-)

diff --git a/src/views/approveManage/tradeApproval/approve.vue b/src/views/approveManage/tradeApproval/approve.vue
index b9fa7c0..5c64ccb 100644
--- a/src/views/approveManage/tradeApproval/approve.vue
+++ b/src/views/approveManage/tradeApproval/approve.vue
@@ -1,93 +1,1226 @@
 <template>
   <div class="default-main">
+    <!-- 璁㈠崟淇℃伅 + 鐢宠浜轰俊鎭� + 浜ゆ槗鍐呭锛堝悎骞朵负鍚屼竴鍗$墖锛� -->
     <el-card shadow="never">
-      <div class="title">璁㈠崟淇℃伅</div>
-      <el-descriptions :column="3" border class="mt10">
+      <el-descriptions
+        :column="2"
+        border
+        class="mt10 order-desc fixed-label"
+        label-width="180px"
+        :label-style="labelStyle"
+        :content-style="contentStyle"
+      >
+        <el-descriptions-item :span="2" class="section-header">
+          <template #label>
+            <el-icon class="section-icon"><Document /></el-icon>
+            <span>璁㈠崟淇℃伅</span>
+          </template>
+          <template #default></template>
+        </el-descriptions-item>
         <el-descriptions-item label="璁㈠崟缂栧彿">{{ detail.orderNo }}</el-descriptions-item>
         <el-descriptions-item label="浜ゆ槗璧勬簮绫诲瀷">{{ detail.resourceTypeName }}</el-descriptions-item>
-        <el-descriptions-item label="浜ゆ槗鐘舵��">{{ detail.statusName }}</el-descriptions-item>
         <el-descriptions-item label="鐢宠鏃堕棿">{{ detail.applyTime }}</el-descriptions-item>
-        <el-descriptions-item label="鍗曚綅">{{ detail.unitName }}</el-descriptions-item>
-        <el-descriptions-item label="鐢ㄦ埛鍚�">{{ detail.userName }}</el-descriptions-item>
+        <el-descriptions-item label="浜ゆ槗鐘舵��">
+          <el-tag :type="getStatusType(detail.status)" size="small">{{ detail.statusName }}</el-tag>
+        </el-descriptions-item>
       </el-descriptions>
-    </el-card>
+      
+      <!-- 鐢宠浜轰俊鎭紙涓庤鍗曚俊鎭悓鍗$墖锛屽鐢ㄥ垎闅旀爣棰樻牱寮忥級 -->
+      <el-descriptions
+        :column="2"
+        border
+        class="mt15 order-desc fixed-label"
+        label-width="180px"
+        :label-style="labelStyle"
+        :content-style="contentStyle"
+      >
+        <el-descriptions-item :span="2" class="section-header">
+          <template #label>
+            <el-icon class="section-icon"><User /></el-icon>
+            <span>鐢宠浜轰俊鎭�</span>
+          </template>
+          <template #default></template>
+        </el-descriptions-item>
+        <el-descriptions-item label="濮撳悕">{{ detail.userName || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="鍗曚綅">{{ detail.unitName || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="閮ㄩ棬">{{ detail.userDept || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="鐢ㄦ埛鍚�">{{ detail.userAccount || '-' }}</el-descriptions-item>
+      </el-descriptions>
 
-    <el-card class="mt15" shadow="never">
-      <div class="title">浜ゆ槗鍐呭</div>
-      <el-table :data="detail.items" border class="mt10">
-        <el-table-column label="璇︽儏" min-width="280">
-          <template #default="{ row }">
-            <div>
-              <div>{{ row.name }}</div>
-              <div class="gray">瀹㈡埛瀵硅薄锛歿{ row.customerTarget }}</div>
-              <div class="gray">骞跺彂鑺傜偣鏁帮細{{ row.concurrentNodes }}</div>
-            </div>
+      <!-- 浜ゆ槗鍐呭锛堢揣闅忕敵璇蜂汉淇℃伅锛屽悓鍗$墖锛屽鐢ㄥ垎闅旀爣棰樻牱寮忥級 -->
+      <el-descriptions
+        :column="2"
+        border
+        class="mt15 order-desc fixed-label"
+        label-width="180px"
+        :label-style="labelStyle"
+        :content-style="contentStyle"
+      >
+        <el-descriptions-item :span="2" class="section-header">
+          <template #label>
+            <el-icon class="section-icon"><Goods /></el-icon>
+            <span>浜ゆ槗鍐呭</span>
+          </template>
+          <template #default></template>
+        </el-descriptions-item>
+        <el-descriptions-item label="浜у搧鍚嶇О">
+          <el-link type="primary" :underline="false">{{ detail.productName }}</el-link>
+        </el-descriptions-item>
+        <el-descriptions-item label="鎻愪緵鑰�">{{ detail.supplier }}</el-descriptions-item>
+        <el-descriptions-item label="琛屼笟棰嗗煙">{{ detail.industry }}</el-descriptions-item>
+        <el-descriptions-item label="鍗曚綅宸ョ▼">{{ detail.projectUnit }}</el-descriptions-item>
+        <el-descriptions-item label="浜у搧绫诲瀷">{{ detail.productType || '-' }}</el-descriptions-item>
+        <el-descriptions-item label="浜у搧绠�浠�">
+          <div class="desc-wrap">{{ detail.productDesc }}</div>
+        </el-descriptions-item>
+      </el-descriptions>
+      
+      <!-- 璁㈠崟璇︽儏锛堢Щ鍔ㄥ埌浜ゆ槗鍐呭涓嬮潰锛屽悓涓�鍗$墖鍐咃級 -->
+      <div ref="orderTableWrapRef">
+        <el-table
+          :data="tableData"
+          border
+          class="mt10 order-table"
+          :header-cell-style="headerCenterStyle"
+          :cell-style="bodyCellStyle"
+          :row-class-name="getRowClassName"
+          :span-method="arraySpanMethod"
+        >
+        <el-table-column>
+          <template #header>
+            <el-icon class="header-icon"><List /></el-icon>
+            <span>璇︽儏</span>
+          </template>
+          <el-table-column label="" :width="colWidths.detail1">
+            <template #default="{ row }">
+              <div v-if="!row.isSummary">{{ row.name }}</div>
+              <div v-else class="summary-merged">
+                <div class="summary-left">
+                  鍏� <span class="count">{{ detail.items.length }}</span> 浠�
+                </div>
+                <div class="summary-right">
+                  鎬昏锛�<span class="price">{{ detail.pointTotal }}</span> 绉垎
+                  <span class="ml20 price">{{ detail.cashTotal }}</span> 鍏�
+                </div>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column label="" :width="colWidths.detail2">
+            <template #default="{ row }">
+              <div v-if="!row.isSummary" class="gray">閿�鍞舰寮忥細{{ row.saleType || '-' }}</div>
+              <div v-if="!row.isSummary" class="gray">璐︽埛鏁伴噺锛歿{ row.accountCount ?? '-' }}</div>
+            </template>
+          </el-table-column>
+          <el-table-column label="" :width="colWidths.detail3">
+            <template #default="{ row }">
+              <div v-if="!row.isSummary" class="gray">瀹㈡埛瀵硅薄锛歿{ row.customerTarget || '-' }}</div>
+              <div v-if="!row.isSummary" class="gray">骞跺彂鑺傜偣鏁伴噺锛歿{ row.concurrentNodes ?? '-' }}</div>
+            </template>
+          </el-table-column>
+        </el-table-column>
+        <el-table-column label="鍗曚环">
+          <el-table-column label="" :width="colWidths.price">
+            <template #default="{ row }">
+              <div v-if="!row.isSummary">{{ formatPrice(row) }}</div>
+            </template>
+          </el-table-column>
+        </el-table-column>
+        <el-table-column label="鏁伴噺">
+          <el-table-column label="" :width="colWidths.quantity">
+            <template #default="{ row }">
+              <div v-if="!row.isSummary">{{ row.quantity }}</div>
+            </template>
+          </el-table-column>
+        </el-table-column>
+        <el-table-column label="鏈熼檺(骞�)">
+          <el-table-column label="" :width="colWidths.period">
+            <template #default="{ row }">
+              <div v-if="!row.isSummary">{{ formatPeriod(row) }}</div>
+            </template>
+          </el-table-column>
+        </el-table-column>
+        </el-table>
+      </div>
+
+      <!-- 绉婚櫎鍘熸潵鐨勮〃鏍煎簳閮ㄤ俊鎭紝鍥犱负宸茬粡绉诲埌琛ㄦ牸鏈�鍚庝竴琛� -->
+
+       <!-- 浜ゆ槗鏂囦欢锛堢Щ鍔ㄥ埌璁㈠崟璇︽儏涓嬮潰锛屽悓涓�鍗$墖鍐咃級 -->
+       <div class="file-section" v-if="isAgreementOrder && fileList.length > 0">
+         <el-table
+           :data="fileList"
+           border
+           class="file-table"
+           :header-cell-style="fileTableHeaderStyle"
+           :cell-style="fileTableCellStyle"
+         >
+           <el-table-column min-width="200">
+             <template #header>
+               <el-icon class="header-icon"><Document /></el-icon>
+               <span>浜ゆ槗鏂囦欢</span>
+             </template>
+             <template #default="{ row }">
+               <div class="file-name">
+                 <el-icon class="file-icon"><Document /></el-icon>
+                 <span>{{ row.name }}</span>
+               </div>
+             </template>
+           </el-table-column>
+           <el-table-column label="鏂囦欢澶у皬" prop="size" width="120">
+             <template #default="{ row }">
+               {{ formatFileSize(row.size) }}
+             </template>
+           </el-table-column>
+                     <el-table-column label="鎿嶄綔" width="180">
+            <template #default="{ row }">
+              <div class="file-actions">
+                <el-button
+                  type="text"
+                  size="small"
+                  class="preview-btn"
+                  @click="handlePreview(row)"
+                  v-if="isPreviewable(row)"
+                  :disabled="!isFileUploaded(row)"
+                >
+                  棰勮
+                </el-button>
+                <el-button
+                  type="text"
+                  size="small"
+                  class="download-btn"
+                  @click="handleDownload(row)"
+                  :disabled="!isFileUploaded(row)"
+                >
+                  涓嬭浇
+                </el-button>
+              </div>
+            </template>
+          </el-table-column>
+         </el-table>
+       </div>
+     </el-card>
+
+         <!-- 浜ゆ槗淇℃伅澶囨敞 -->
+   <el-card class="mt15" shadow="never">
+     <div class="title">浜ゆ槗淇℃伅澶囨敞</div>
+     <el-table :data="form.items" border class="mt10 remark-table">
+       <el-table-column label="璇︽儏" prop="name" min-width="200" />
+        <el-table-column label="澶囨敞" min-width="400">
+          <template #default="{ row, $index }">
+            <el-input
+              v-model="form.items[$index].remark"
+              type="textarea"
+              :rows="1"
+              placeholder="寮�閫氳处鍙蜂俊鎭強涓暟锛岀櫥褰曟彁绀虹瓑淇℃伅"
+              maxlength="500"
+              show-word-limit
+              class="remark-input"
+            />
           </template>
         </el-table-column>
-        <el-table-column label="鍗曚环" prop="priceName" width="140" />
-        <el-table-column label="鏁伴噺" prop="quantity" width="80" />
-        <el-table-column label="鏈熼檺(骞�)" prop="period" width="120" />
-      </el-table>
-
-      <div class="total">
-        鎬昏锛�<span class="price">{{ detail.pointTotal }}</span> 绉垎
-        <span class="ml20 price">{{ detail.cashTotal }}</span> 鍏�
-      </div>
+            </el-table>
     </el-card>
 
+    <!-- 瀹℃壒鍐呭 -->
     <el-card class="mt15" shadow="never">
-      <div class="title">瀹℃壒</div>
-      <el-form :model="form" label-width="100px" class="mt10" ref="formRef" :rules="rules">
-        <el-form-item label="瀹℃壒鎰忚" prop="remark">
-          <el-input v-model="form.remark" type="textarea" :autosize="{ minRows: 4 }" placeholder="璇疯緭鍏ュ鎵规剰瑙�" />
-        </el-form-item>
-      </el-form>
-      <div class="ba-center mt15">
-        <el-button @click="goBack">杩斿洖</el-button>
-        <el-button type="success" @click="approve(true)">瀹℃壒閫氳繃</el-button>
-        <el-button type="danger" @click="approve(false)">椹冲洖</el-button>
+      <div class="title">瀹℃壒鍐呭</div>
+      <div class="approval-content">
+        <div class="approval-form">
+          <div class="form-item">
+            <label class="required">瀹℃壒鎰忚:</label>
+            <el-input
+              v-model="approvalForm.comments"
+              type="textarea"
+              :rows="4"
+              placeholder="璇疯緭鍏ュ鎵规剰瑙�"
+              maxlength="500"
+              show-word-limit
+            />
+          </div>
+        </div>
+        <div class="approval-actions">
+          <el-button @click="goBack">杩斿洖</el-button>
+          <el-button 
+            type="primary" 
+            @click="handleApprove"
+            :loading="approvalLoading"
+          >
+            {{ isAgreementOrder ? '瀹℃壒閫氳繃' : '瀹屾垚鎺堟潈' }}
+          </el-button>
+          <el-button 
+            v-if="isAgreementOrder"
+            type="danger" 
+            @click="handleReject"
+            :loading="approvalLoading"
+          >
+            椹冲洖
+          </el-button>
+        </div>
       </div>
     </el-card>
   </div>
 </template>
 
 <script setup lang="ts">
-import { onMounted, reactive, ref } from 'vue'
+import { onMounted, reactive, ref, computed, type CSSProperties } from 'vue'
 import { useRoute, useRouter } from 'vue-router'
-import { fetchApprovalDetail, submitApproval } from '@/api/approvalManage'
-import { ElMessage, FormInstance } from 'element-plus'
+import { Document, User, Goods, List } from '@element-plus/icons-vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import orderApi from '@/api/orderApi'
+import { approveOrder } from '@/api/approvalManage'
+import { useUserInfo } from '@/stores/modules/userInfo'
+import createAxios from '@/utils/axios'
+import productApi from '@/api/productApi'
+import sysUserService from "@/api/sysUser";
+import workFlowApi from "@/api/workFlowApi";
+import {queryUserDetail} from "@/api/userInfo";
 
 const route = useRoute()
 const router = useRouter()
-const formRef = ref<FormInstance>()
+const userStore = useUserInfo()
 const detail = reactive<any>({ items: [] })
-const form = reactive({ remark: '' })
-const rules = { remark: [{ required: true, message: '璇疯緭鍏ュ鎵规剰瑙�', trigger: 'blur' }] }
+const form = reactive<any>({ items: [] })
+const fileList = ref<any[]>([])
+const orderTableWrapRef = ref<HTMLElement | null>(null)
+const labelStyle = { width: '180px', maxWidth: '180px' }
+const contentStyle = { width: 'calc(50% - 180px)' }
+
+// 鏄惁涓哄崗璁鍗�
+const isAgreementOrder = ref(false)
+
+// 瀹℃壒琛ㄥ崟鏁版嵁
+const approvalForm = reactive({
+  comments: ''
+})
+
+// 瀹℃壒loading鐘舵��
+const approvalLoading = ref(false)
+
+// 璁$畻琛ㄦ牸鏁版嵁锛屾坊鍔犳眹鎬昏
+const tableData = computed(() => {
+  const summaryRow = {
+    id: 'summary',
+    isSummary: true,
+    name: '',
+    saleType: '',
+    accountCount: 0,
+    customerTarget: '',
+    concurrentNodes: 0,
+    pricePoint: 0,
+    priceCash: 0,
+    quantity: 0,
+    period: 0,
+  }
+  return [...detail.items, summaryRow]
+})
+
+const taskId = computed(() => {
+  return String(route.params.taskId || '')
+})
+
+// 鐘舵�佹槧灏勶紙鍚庣涓枃 -> 鍓嶇鏋氫妇锛�
+const statusServerToUi: Record<string, string> = {
+  '寰呬笂浼犳枃浠�': 'WAIT_UPLOAD',
+  '寰呮巿鏉�': 'WAIT_AUTHORIZE',
+  '寰呬氦鏄撶‘璁�': 'WAIT_CONFIRM',
+  '宸插畬鎴�': 'COMPLETED',
+  '宸茶瘎浠�': 'EVALUATED',
+}
+
+const formatDateTime = (val?: string) => (val ? val.replace('T', ' ').slice(0, 19) : '')
+
+const normalizePriceType = (val?: string): 'points' | 'currency' | 'agreement' | 'free' => {
+  if (!val) return 'currency'
+  const s = String(val)
+  if (/(绉垎|points)/i.test(s)) return 'points'
+  if (/(鍗忚|agreement)/i.test(s)) return 'agreement'
+  if (/(鍏嶈垂|free)/i.test(s)) return 'free'
+  return 'currency'
+}
 
 onMounted(async () => {
-  const { data } = (await fetchApprovalDetail({ id: route.params.id })) as any
-  Object.assign(detail, data || {})
+  const orderId = String(route.params.id || '')
+  console.log(route.params.taskId)
+  if (!orderId) return
+
+  // 鑾峰彇鐢ㄦ埛淇℃伅
+  if (!userStore.getUserId) {
+    try {
+      const res: any = await queryUserDetail()
+      if (res?.code === 200 && res.data) {
+        userStore.updateUserDetail(res.data)
+      } else {
+        ElMessage.error(res?.msg || '鏃犳硶鑾峰彇鐢ㄦ埛淇℃伅锛岃鍏堢櫥褰�')
+        return
+      }
+    } catch (e) {
+      console.error('鑾峰彇鐢ㄦ埛璇︽儏澶辫触:', e)
+      ElMessage.error('鑾峰彇鐢ㄦ埛淇℃伅澶辫触锛岃绋嶅悗閲嶈瘯')
+      return
+    }
+  }
+
+  try {
+    // 骞惰鑾峰彇璁㈠崟璇︽儏鍜屽崗璁被鍨嬫鏌�
+    const [orderRes, agreementRes] = await Promise.all([
+      orderApi.getOrderDetail(orderId),
+      orderApi.checkAgreementPriceType(orderId)
+    ])
+    
+    const res = orderRes as any
+    const data = res?.data || {}
+    
+    // 璁剧疆鏄惁涓哄崗璁鍗�
+    const agreementResult = agreementRes as any
+    isAgreementOrder.value = agreementResult?.data === true
+
+    const statusName: string = data.orderStatus || ''
+    const uiStatus = statusServerToUi[statusName] || 'INFO'
+
+    // 鏍规嵁浜у搧id鑾峰彇浜у搧淇℃伅锛屾洿鏂板ご閮ㄥ睍绀�
+    try {
+      if (data.productId) {
+        const detailRes: any = await productApi.getProductById({ id: data.productId })
+        if (detailRes?.code === 200 && detailRes.data) {
+          // 鐢ㄤ骇鍝佽鎯呰ˉ鍏ㄥご淇℃伅
+          data.productName = detailRes.data.name || data.productName
+          data.providerName = detailRes.data.submissionUnit || data.providerName
+          data.industry = detailRes.data.industrialChainName || data.industry
+          data.productDesc = detailRes.data.describe || data.productDesc
+          data.projectUnit = detailRes.data.importantAreaName || data.productDesc
+          data.productType = detailRes.data.typeName || data.productDesc
+        }
+      }
+    } catch (e) {
+      // 蹇界暐浜у搧璇︽儏澶辫触锛屼笉闃诲璁㈠崟璇︽儏
+    }
+    
+    // 鑾峰彇鐢ㄦ埛淇℃伅
+    // 鑾峰彇鐢ㄦ埛淇℃伅
+    try {
+      const userRes: any = await sysUserService.getUserdetail({ userId: data.userId })
+      if (userRes?.code === 200 && userRes.data) {
+        // 鐢ㄤ骇鍝佽鎯呰ˉ鍏ㄥご淇℃伅
+        data.unitName = userRes.data.unitName || data.unitName
+        data.userName = userRes.data.name || data.userName
+        data.userDept = userRes.data.departmentName || data.userDept
+        data.userPhone = userRes.data.phone || data.userPhone
+        data.userAccount = userRes.data.username || data.userAccount
+      }
+    }catch (e){
+
+    }
+
+    // 鏄犲皠璁㈠崟璇︽儏澶撮儴淇℃伅
+    const head = {
+      orderNo: data.orderId,
+      resourceTypeName: '杞欢浜у搧',
+      status: uiStatus,
+      statusName,
+      applyTime: formatDateTime(data.applyTime),
+      unitName: data.unitName || '-',
+      userName: data.userName || '-',
+      userAccount: data.userAccount || '-',
+      userDept: data.userDept || '-',
+      userPhone: data.userPhone || '-',
+      productName: data.productName || '-',
+      supplier: data.providerName || '-',
+      industry: data.industry || '-',
+      projectUnit: data.projectUnit || '-',
+      productType: data.productType || '-',
+      productDesc: data.productDesc || '-',
+    }
+
+    // 鏄庣粏椤规槧灏�
+    const items: any[] = Array.isArray(data.orderDetails)
+      ? data.orderDetails.map((d: any, idx: number) => {
+          const pt = normalizePriceType(d.priceType)
+          return {
+            id: String(d.id ?? idx + 1),
+            name: d.suiteName,
+            saleType: d.salesForm,
+            accountCount: d.accountLimit,
+            customerTarget: d.customerType,
+            concurrentNodes: d.concurrentNodes,
+            pricePoint: pt === 'points' ? Number(d.unitPrice || 0) : 0,
+            priceCash: pt === 'currency' ? Number(d.unitPrice || 0) : 0,
+            priceProtocol: pt === 'agreement',
+            quantity: Number(d.quantity || 0),
+            period: Number(d.duration || 0),
+            remarks: d.remarks || '', // 鏂板 remarks 瀛楁
+          }
+        })
+      : []
+
+    // 姹囨�伙紙绠�鍗曠浉鍔狅細鍗曚环*鏁伴噺锛�
+    const pointTotalNum = items.reduce((sum, it) => sum + Number(it.pricePoint || 0) * Number(it.quantity || 0), 0)
+    const cashTotalNum = items.reduce((sum, it) => sum + Number(it.priceCash || 0) * Number(it.quantity || 0), 0)
+
+    Object.assign(detail, head, {
+      items,
+      pointTotal: pointTotalNum.toLocaleString(),
+      cashTotal: cashTotalNum.toLocaleString(),
+      workflowId: data.workflowId || data.processinstId || ''
+    })
+
+    // 鍒濆鍖栬〃鍗曟暟鎹�
+    form.items = (detail.items || []).map((item: any, index: number) => {
+      return { 
+        id: item.id, // 淇濆瓨order_detail鐨刬d
+        name: item.name,
+        remark: item.remarks || '' // 浣跨敤濂椾欢淇℃伅涓殑remarks瀛楁
+      }
+    })
+
+    // 鑾峰彇璁㈠崟闄勪欢鍒楄〃锛堝鏋滄湁鐨勮瘽锛�
+    if (data.attachments && Array.isArray(data.attachments)) {
+      fileList.value = data.attachments.map((file: any) => ({
+        name: file.fileName || file.originalName,
+        size: file.fileSize || 0,
+        uid: file.id,
+        status: 'success',
+        url: file.fileUrl,
+        uploaded: true
+      }))
+    } else {
+      fileList.value = []
+    }
+  } catch (error) {
+    console.error('鑾峰彇璁㈠崟璇︽儏澶辫触:', error)
+    ElMessage.error('鑾峰彇璁㈠崟璇︽儏澶辫触')
+  }
 })
 
 const goBack = () => router.back()
-const approve = async (pass: boolean) => {
-  await formRef.value?.validate()
-  const { code } = (await submitApproval({ id: route.params.id, pass, remark: form.remark })) as any
-  if (code === 200) {
-    ElMessage.success('鎻愪氦鎴愬姛')
-    router.back()
+
+// 瀹℃壒閫氳繃澶勭悊
+const handleApprove = async () => {
+  if (!approvalForm.comments.trim()) {
+    ElMessage.warning('璇疯緭鍏ュ鎵规剰瑙�')
+    return
+  }
+  
+  try {
+    approvalLoading.value = true
+    await ElMessageBox.confirm('纭畾瑕佸鎵归�氳繃鍚楋紵', '纭鎿嶄綔', {
+      confirmButtonText: '纭畾',
+      cancelButtonText: '鍙栨秷',
+      type: 'warning'
+    })
+    
+    const orderId = String(route.params.id || '')
+    console.log(String(route.params.taskId || ''))
+    const taskId1 = taskId.value
+    const userId = userStore.getUserId ? userStore.getUserId : undefined
+    const comments = approvalForm.comments.trim()
+
+    if (!orderId || !userId) {
+      ElMessage.error('璁㈠崟ID鎴栫敤鎴稩D涓嶈兘涓虹┖')
+      approvalLoading.value = false
+      return
+    }
+
+    // 璋冪敤瀹℃壒閫氳繃API
+    const result = await approveOrder({
+      orderId: orderId,
+      taskId: taskId1,
+      approvalOpinion: comments,
+      approverId: userId,
+      approverName: userStore.getUserDetail || '绠$悊鍛�',
+      approvalType: isAgreementOrder.value ? '瀹℃壒' : '鎺堟潈',
+      approvalResult: '閫氳繃',
+      orderDetails: form.items.map((item: any) => ({
+        id: item.id,
+        remarks: item.remark || '' // 浣跨敤琛ㄥ崟涓殑澶囨敞
+      }))
+    })
+    
+    if (result && result.code === 200) {
+      // 鏇存柊浜ゆ槗淇℃伅澶囨敞锛堝彧鏇存柊remarks锛屼笉鏇存柊璁㈠崟鐘舵�侊級
+      // const updateData = {
+      //   orderId: orderId,
+      //   orderDetails: form.items.map((item: any) => ({
+      //     id: item.id,
+      //     remarks: item.remark || '' // 浣跨敤琛ㄥ崟涓殑澶囨敞
+      //   }))
+      // }
+      //
+      // await orderApi.updateOrderDetailRemarksOnly(updateData)
+      //
+      // // 瀹℃壒閫氳繃鍚庯紝浣跨敤鏂扮殑API鎺ュ彛鏇存柊璁㈠崟鐘舵�佸埌涓嬩竴涓姸鎬�
+      // await orderApi.updateOrderStatusToNext(orderId)
+      ElMessage.success('瀹℃壒閫氳繃鎴愬姛')
+      // if(!detail.workflowId.value){
+      //   ElMessage.error("宸ヤ綔娴乮d涓虹┖涓嶈兘杩涜宸ヤ綔娴佷换鍔℃彁浜�")
+      //   return
+      // }
+      // // 璋冪敤宸ヤ綔娴�
+      // const wfRes: any = await workFlowApi.completeWorkflow({
+      //   taskId: String(detail.workflowId.value),
+      //   userid: userStore.getUserId,
+      //   commponet: '瀹℃牳閫氳繃'
+      // })
+      // if (wfRes?.code === 200 && wfRes.data?.processinstId) {
+      //    console.log('宸ヤ綔娴佹彁浜ゆ垚鍔�')
+      // }
+      router.back()
+    } else {
+      ElMessage.error(result?.msg || '瀹℃壒閫氳繃澶辫触')
+    }
+  } catch (error) {
+    if (error !== 'cancel') {
+      console.error('瀹℃壒澶辫触:', error)
+      ElMessage.error('瀹℃壒澶辫触')
+    }
+  } finally {
+    approvalLoading.value = false
   }
 }
+
+// 椹冲洖澶勭悊
+const handleReject = async () => {
+  if (!approvalForm.comments.trim()) {
+    ElMessage.warning('璇疯緭鍏ュ鎵规剰瑙�')
+    return
+  }
+  
+  try {
+    approvalLoading.value = true
+    await ElMessageBox.confirm('纭畾瑕侀┏鍥炲悧锛�', '纭鎿嶄綔', {
+      confirmButtonText: '纭畾',
+      cancelButtonText: '鍙栨秷',
+      type: 'warning'
+    })
+    
+    const orderId = String(route.params.id || '')
+    const userId = userStore.getUserId ?  userStore.getUserId : undefined
+    const comments = approvalForm.comments.trim()
+    const taskId1 = String(route.params.taskId || '')
+
+    if (!orderId || !userId) {
+      ElMessage.error('璁㈠崟ID鎴栫敤鎴稩D涓嶈兘涓虹┖')
+      approvalLoading.value = false
+      return
+    }
+
+    // 璋冪敤瀹℃壒椹冲洖API
+    const result = await approveOrder({
+      orderId: orderId,
+      approvalOpinion: comments,
+      approverId: userId,
+      taskId: taskId1,
+      approverName: userStore.getUserDetail || '绠$悊鍛�',
+      approvalType: isAgreementOrder.value ? '瀹℃壒' : '鎺堟潈',
+      approvalResult: '椹冲洖'
+    })
+    
+    if (result && result.code === 200) {
+      // 椹冲洖璁㈠崟锛屾洿鏂拌鍗曠姸鎬佸埌涓婁竴涓姸鎬�
+      // await orderApi.updateOrderStatusToPrevious(orderId)
+      ElMessage.success('椹冲洖鎴愬姛')
+      // 璋冪敤宸ヤ綔娴�
+      // const wfRes: any = await workFlowApi.rejectStartNodeWorkflow({
+      //   taskId: String(detail.workflowId.value),
+      //   userid: userStore.getUserId,
+      //   commponet: '椹冲洖'
+      // })
+      // if (wfRes?.code === 200 && wfRes.data?.processinstId) {
+      //   console.log('宸ヤ綔娴侀┏鍥炴垚鍔�')
+      // }
+      router.back()
+    } else {
+      ElMessage.error(result?.msg || '椹冲洖澶辫触')
+    }
+  } catch (error) {
+    if (error !== 'cancel') {
+      console.error('椹冲洖澶辫触:', error)
+      ElMessage.error('椹冲洖澶辫触')
+    }
+  } finally {
+    approvalLoading.value = false
+  }
+}
+
+// 涓庡垪琛ㄩ〉淇濇寔涓�鑷寸殑鐘舵�佺被鍨嬫槧灏勶紙UI灞曠ず鐢級
+const getStatusType = (status: string) => {
+  const statusMap: Record<string, 'warning' | 'danger' | 'success' | 'info'> = {
+    WAIT_APPROVAL: 'warning',
+    WAIT_UPLOAD: 'warning',
+    WAIT_CHECK: 'warning',
+    WAIT_CONFIRM: 'warning',
+    REJECTED: 'danger',
+    FINISH: 'success',
+  }
+  return statusMap[status] || 'info'
+}
+
+// 璁㈠崟璇︽儏涓�"鍗曚环"鏄剧ず锛氫紭鍏堟樉绀虹Н鍒嗭紝鍏舵鏄剧ず璐у竵锛涙牸寮忕ず渚嬶細
+// "绉垎锛�50,000/濂�" 鎴� "璐у竵锛�7,500/濂�/骞�" 鎴� "鍏嶈垂锛�/骞�"
+const formatPrice = (row: any) => {
+  const point = Number(row.pricePoint || 0)
+  const cash = Number(row.priceCash || 0)
+  const protocol = Boolean(row.priceProtocol)
+
+  // 鍏嶈垂
+  if (!point && !cash) {
+    return protocol ? '鍗忚锛�/骞�' : '鍏嶈垂锛�/骞�'
+  }
+  if (point) {
+    return `绉垎锛�${point.toLocaleString()}/濂梎
+  }
+  // 浠呯幇閲�
+  return `璐у竵锛�${cash.toLocaleString()}/濂�/骞碻
+}
+
+// 鏈熼檺灞曠ず锛�0 琛ㄧず"姘镐箙"锛屽叾浠栨樉绀烘暟瀛�
+const formatPeriod = (row: any) => {
+  const p = Number(row.period || 0)
+  return p === 0 ? '姘镐箙' : `${p}`
+}
+
+// 琛ㄥご鏂囧瓧灞呬腑锛屼絾绗竴琛岀殑"璇︽儏"鏂囧瓧闈犲乏瀵归綈
+const headerCenterStyle: CSSProperties = { 
+  textAlign: 'center',
+  fontSize: '14px',
+  background: '#f3f6fb'
+}
+
+// 琛ㄤ綋鏂囧瓧澶у皬
+const bodyCellStyle: CSSProperties = { fontSize: '12px' }
+
+// 涓烘眹鎬昏娣诲姞鐗规畩鏍峰紡绫诲悕
+const getRowClassName = ({ row }: { row: any }) => {
+  return row.isSummary ? 'summary-row' : ''
+}
+
+// 鍗曞厓鏍煎悎骞舵柟娉�
+const arraySpanMethod = ({ row, column, rowIndex, columnIndex }: any) => {
+  if (row.isSummary) {
+    // 姹囨�昏锛氱涓�鍒楁樉绀哄悎骞跺唴瀹癸紝鍏朵粬鍒楅殣钘�
+    if (columnIndex === 0) {
+      return [1, 6] // 鍚堝苟1琛�6鍒�
+    } else {
+      return [0, 0] // 闅愯棌鍏朵粬鍒�
+    }
+  }
+  return [1, 1] // 鏅�氳姝e父鏄剧ず
+}
+
+// 鏂囦欢鍒楄〃琛ㄦ牸琛ㄥご鏂囧瓧灞呬腑锛屼絾绗竴鍒楃殑"浜ゆ槗鏂囦欢"鏂囧瓧闈犲乏瀵归綈
+const fileTableHeaderStyle: CSSProperties = { 
+  textAlign: 'center',
+  fontSize: '14px',
+  background: '#f3f6fb'
+}
+// 鏂囦欢鍒楄〃琛ㄦ牸琛ㄤ綋鏂囧瓧澶у皬
+const fileTableCellStyle: CSSProperties = { fontSize: '12px' }
+
+// 鏂囦欢澶у皬鏍煎紡鍖�
+const formatFileSize = (size: number) => {
+  if (!size || size === 0) return '0 Bytes';
+  const k = 1024;
+  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
+  const i = Math.floor(Math.log(size) / Math.log(k));
+  return parseFloat((size / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
+};
+
+// 鍒ゆ柇鏂囦欢鏄惁鍙瑙�
+const isPreviewable = (file: any) => {
+  // 棣栧厛妫�鏌IME绫诲瀷
+  const previewableTypes = [
+    'image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/bmp', 'image/webp',
+    'text/plain', 'text/html', 'text/css', 'text/javascript',
+    'application/pdf',
+    'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // .docx
+    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // .xlsx
+    'application/vnd.openxmlformats-officedocument.presentationml.presentation', // .pptx
+  ]
+  
+  // 濡傛灉MIME绫诲瀷鍖归厤锛岀洿鎺ヨ繑鍥瀟rue
+  if (previewableTypes.includes(file.type || '')) {
+    return true
+  }
+  
+  // 濡傛灉MIME绫诲瀷涓虹┖鎴栦笉鍖归厤锛屾牴鎹枃浠舵墿灞曞悕鍒ゆ柇
+  const fileName = file.name || ''
+  const fileExtension = fileName.toLowerCase().split('.').pop()
+  
+  const previewableExtensions = [
+    'jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp',
+    'txt', 'html', 'htm', 'css', 'js',
+    'pdf',
+    'docx', 'xlsx', 'pptx'
+  ]
+  
+  return previewableExtensions.includes(fileExtension)
+}
+
+// 鍒ゆ柇鏂囦欢鏄惁宸蹭笂浼犳垚鍔�
+const isFileUploaded = (file: any) => {
+  // 鏂囦欢鏈塽rl涓旂姸鎬佷负success琛ㄧず宸蹭笂浼犳垚鍔�
+  return file.url && (file.status === 'success' || file.uploaded)
+}
+
+// 鏂囦欢棰勮
+const handlePreview = async (file: any) => {
+  if (!file.url) {
+    ElMessage.warning('鏂囦欢閾炬帴涓嶅瓨鍦�')
+    return
+  }
+  
+  // 鑾峰彇鏂囦欢鎵╁睍鍚�
+  const fileName = file.name || ''
+  const fileExtension = fileName.toLowerCase().split('.').pop()
+  
+  let previewUrl = file.url
+  
+  // 濡傛灉鏂囦欢瀛樺偍鍦∕inIO锛屼紭鍏堜娇鐢ㄩ瑙圲RL
+  if (file.url.includes('order-attachments')) {
+    try {
+      // 棣栧厛灏濊瘯鑾峰彇棰勮URL
+      const previewResponse = await createAxios({
+        url: `/admin/file/preview`,
+        method: 'GET',
+        params: {
+          fileName: file.url
+        }
+      })
+      
+      console.log('棰勮URL鍝嶅簲:', previewResponse)
+      
+      // 妫�鏌ュ搷搴旀牸寮�
+      const responseData = previewResponse as any
+      if (responseData && responseData.code === 200 && responseData.data) {
+        previewUrl = responseData.data.replaceAll('http://192.168.20.52:9000',import.meta.env.VITE_FILE_PREVIEW_URL)
+        console.log('浣跨敤棰勮URL:', previewUrl)
+      } else {
+        console.log('棰勮URL鑾峰彇澶辫触锛屼娇鐢ㄤ笅杞芥柟寮�')
+        // 濡傛灉棰勮URL鑾峰彇澶辫触锛屽洖閫�鍒颁笅杞芥柟寮�
+        const response = await createAxios({
+          url: `/admin/file/download`,
+          method: 'GET',
+          responseType: 'blob',
+          params: {
+            fileName: file.url,
+            originalName: file.name
+          }
+        })
+        
+        // 鍒涘缓棰勮URL
+        const blob = new Blob([response as any])
+        previewUrl = window.URL.createObjectURL(blob)
+        console.log('浣跨敤Blob URL:', previewUrl)
+      }
+    } catch (error) {
+      console.error('鑾峰彇鏂囦欢澶辫触:', error)
+      ElMessage.error('鑾峰彇鏂囦欢澶辫触锛屾棤娉曢瑙�')
+      return
+    }
+  }
+  
+  // 鍥剧墖鏂囦欢鐩存帴鍦ㄦ柊绐楀彛鎵撳紑
+  if ((file.type && file.type.startsWith('image/')) || 
+      ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(fileExtension)) {
+    console.log('棰勮鍥剧墖鏂囦欢:', previewUrl)
+    window.open(previewUrl, '_blank')
+    return
+  }
+  
+  // PDF鏂囦欢鍦ㄦ柊绐楀彛鎵撳紑
+  if (file.type === 'application/pdf' || fileExtension === 'pdf') {
+    console.log('棰勮PDF鏂囦欢:', previewUrl)
+    window.open(previewUrl, '_blank')
+    return
+  }
+  
+  // 鏂囨湰鏂囦欢鍦ㄦ柊绐楀彛鎵撳紑
+  if ((file.type && file.type.startsWith('text/')) || 
+      ['txt', 'html', 'htm', 'css', 'js'].includes(fileExtension)) {
+    console.log('棰勮鏂囨湰鏂囦欢:', previewUrl)
+    window.open(previewUrl, '_blank')
+    return
+  }
+  
+  // Office鏂囨。鍜屽叾浠栨枃浠剁被鍨嬶紝灏濊瘯鍦ㄦ柊绐楀彛鎵撳紑
+  try {
+    console.log('棰勮鍏朵粬鏂囦欢:', previewUrl)
+    window.open(previewUrl, '_blank')
+  } catch (error) {
+    console.error('棰勮澶辫触:', error)
+    ElMessage.error('棰勮澶辫触锛岃涓嬭浇鍚庢煡鐪�')
+  }
+}
+
+// 鏂囦欢涓嬭浇
+const handleDownload = async (file: any) => {
+  if (!file.url) {
+    ElMessage.warning('鏂囦欢閾炬帴涓嶅瓨鍦�')
+    return
+  }
+  
+  console.log('寮�濮嬩笅杞芥枃浠�:', file.name, 'URL:', file.url)
+  
+  try {
+    // 濡傛灉鏂囦欢瀛樺偍鍦∕inIO锛屼娇鐢ㄥ悗绔洿鎺ヤ笅杞紸PI
+    if (file.url.includes('order-attachments')) {
+      console.log('浣跨敤MinIO涓嬭浇API')
+      
+      // 浣跨敤axios閫氳繃浠g悊璁块棶鍚庣API
+      const response = await createAxios({
+        url: `/admin/file/download`,
+        method: 'GET',
+        responseType: 'blob',
+        params: {
+          fileName: file.url,
+          originalName: file.name
+        }
+      })
+      
+      console.log('涓嬭浇鍝嶅簲:', response)
+      
+      // 鍒涘缓涓嬭浇閾炬帴
+      const blob = new Blob([response as any])
+      const downloadUrl = window.URL.createObjectURL(blob)
+      
+      console.log('鍒涘缓涓嬭浇閾炬帴:', downloadUrl)
+      
+      const link = document.createElement('a')
+      link.href = downloadUrl
+      link.download = file.name || 'download'
+      link.target = '_blank'
+      link.rel = 'noopener noreferrer'
+      
+      document.body.appendChild(link)
+      link.click()
+      document.body.removeChild(link)
+      
+      // 娓呯悊URL瀵硅薄
+      window.URL.revokeObjectURL(downloadUrl)
+      
+      ElMessage.success('鏂囦欢涓嬭浇鎴愬姛')
+    } else {
+      console.log('浣跨敤鐩存帴URL涓嬭浇')
+      // 鍏朵粬鎯呭喌鐩存帴浣跨敤鍘烾RL
+      const link = document.createElement('a')
+      link.href = file.url
+      link.download = file.name || 'download'
+      link.target = '_blank'
+      link.rel = 'noopener noreferrer'
+      
+      document.body.appendChild(link)
+      link.click()
+      document.body.removeChild(link)
+      
+      ElMessage.success('寮�濮嬩笅杞芥枃浠�')
+    }
+  } catch (error) {
+    console.error('涓嬭浇澶辫触:', error)
+    ElMessage.error('涓嬭浇澶辫触锛岃閲嶈瘯')
+  }
+}
+
+
+
+// 鐥囩粨涓庝慨澶嶈鏄庯細
+// 1) Element Plus 鐨� el-table 瀛愬垪 width 鐧惧垎姣旀槸鐩稿浜庤〃鏍煎鍣ㄧ殑鍍忕礌瀹藉害璁$畻锛屼絾鍙湁鍦ㄨ〃鏍煎鍣ㄦ湁鏄庣‘瀹藉害鏃舵墠鐢熸晥銆�
+// 2) 鍦ㄧ埗鍒�/澶氱骇琛ㄥご涓嬶紝瀛愬垪 width 涓虹櫨鍒嗘瘮鏃讹紝鏇寸ǔ瀹氱殑鍋氭硶鏄皢鍏惰绠椾负鍍忕礌鍊肩粦瀹氱粰瀛愬垪銆�
+// 3) 鍥犳鎴戜滑璇诲彇琛ㄦ牸澶栧眰瀹瑰櫒瀹藉害锛屾寜姣斾緥璁$畻鍍忕礌瀹藉害锛岄伩鍏嶅嚭鐜扮櫨鍒嗘瘮涓� table-layout 瀵艰嚧鐨勯敊浣嶄笌鎷変几銆�
+const colWidths = computed(() => {
+  const containerWidth = orderTableWrapRef.value?.clientWidth || 0
+  // 鐧惧垎姣斿垎鍒负锛氳鎯� 20% x 3锛屽崟浠� 15%锛屾暟閲� 10%锛屾湡闄� 15% => 鍚堣 100%
+  return {
+    detail1: Math.floor(containerWidth * 0.2),
+    detail2: Math.floor(containerWidth * 0.2),
+    detail3: Math.floor(containerWidth * 0.2),
+    price: Math.floor(containerWidth * 0.15),
+    quantity: Math.floor(containerWidth * 0.1),
+    period: Math.floor(containerWidth * 0.15),
+  }
+})
 </script>
 
 <style scoped lang="scss">
 .title { font-weight: 600; }
+.sub-title { font-weight: 600; margin: 10px 0; }
 .mt10 { margin-top: 10px; }
 .mt15 { margin-top: 15px; }
 .gray { color: #909399; font-size: 12px; }
 .total { text-align: right; margin-top: 10px; }
 .price { color: #f56c6c; font-weight: 600; }
 .ml20 { margin-left: 20px; }
+.item-block { padding: 10px; border: 1px solid #ebeef5; border-radius: 4px; margin-bottom: 10px; }
+
+/* 缁熶竴琛ㄦ牸鍐呭鏂囧瓧澶у皬 */
+.order-table :deep(.el-table__body),
+.order-table :deep(.el-table__header) {
+  font-size: 12px;
+}
+/* 琛ㄥご绗竴琛岃儗鏅壊锛堜笌浜ゆ槗鍐呭鏍囬琛屼繚鎸佷竴鑷达級 */
+.order-table :deep(.el-table__header-wrapper thead tr:first-child > th) {
+  background: #f3f6fb !important;
+  font-size: 14px !important;
+}
+/* 琛ㄥご绗簩琛岄珮搴︿笌鍐呰竟璺� */
+.order-table :deep(.el-table__header-wrapper thead tr:nth-child(2) > th) {
+  height: 5px !important;
+  padding-top: 0 !important;
+  padding-bottom: 0 !important;
+  padding-left: 0 !important;
+  padding-right: 0 !important;
+}
+/* 寮哄埗琛ㄦ牸鍒楀浐瀹氬竷灞�锛岄伩鍏嶅唴瀹瑰奖鍝嶅垪瀹� */
+.order-table :deep(table) {
+  table-layout: fixed;
+  width: 100% !important;
+}
+
+/* 姹囨�昏鏍峰紡 */
+.summary-row {
+  font-weight: 600;
+  color: #f56c6c;
+}
+.summary-total {
+  text-align: right;
+  font-weight: 600;
+}
+.summary-merged {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  width: 100%;
+}
+.summary-left {
+  text-align: left;
+}
+.summary-left .count {
+  color: #f56c6c;
+  font-weight: 600;
+}
+.summary-right {
+  text-align: right;
+}
+.order-table :deep(.summary-row) {
+  background-color: #fafafa;
+}
+.order-table :deep(.summary-row td) {
+  border-top: 2px solid #e4e7ed;
+}
+
+/* 琛ㄥご绗竴琛�"璇︽儏"鏂囧瓧闈犲乏瀵归綈 */
+.order-table :deep(.el-table__header-wrapper thead tr:first-child th:first-child) {
+  text-align: left !important;
+}
+
+/* 琛ㄥご鍥炬爣鏍峰紡 */
+.header-icon {
+  margin-right: 6px;
+  color: #409eff;
+  vertical-align: middle;
+}
+
+/* 鍒嗛殧鏍囬椋庢牸 */
+.section-header {
+  background: #f3f6fb;
+  font-weight: 600;
+  --el-border-color: #e4e7ed;
+}
+.section-header :deep(.el-descriptions__label) {
+  background: #f3f6fb;
+  border-right: none !important;
+  width: 100%;
+}
+.section-header :deep(.el-descriptions__cell) {
+  background: #f3f6fb;
+}
+.section-header :deep(.el-descriptions__content) {
+  display: none !important;
+  padding: 0 !important;
+  border: 0 !important;
+}
+.section-icon {
+  margin-right: 6px;
+  color: #409eff;
+}
+
+/* 璋冩暣鎻忚堪缁勪欢杈规浠ヤ究鏍囬琛岄鑹茶鐩栦腑闂村垎闅旂嚎 */
+:deep(.el-descriptions--border .el-descriptions__body .el-descriptions__table .el-descriptions__cell) {
+  border-right: 1px solid var(--el-border-color);
+}
+.section-header :deep(.el-descriptions__cell) {
+  border-right-color: transparent !important;
+}
+
+/* 寮哄埗 Element Plus 鎻忚堪椤圭殑 label 瀹藉害閬靛惊 label-width锛堥伩鍏嶅唴瀹规拺寮�锛� */
+/* 鍏滃簳锛氬嵆浣垮唴鑱旀牱寮忚瑕嗙洊锛屼篃鐢� important 寮哄埗鍥哄畾 */
+.fixed-label :deep(.el-descriptions__label) {
+  width: 180px !important;
+  max-width: 180px !important;
+}
+.fixed-label :deep(.el-descriptions__content) {
+  width: calc(50% - 180px) !important;
+}
+
+/* 寮哄寲绗竴琛屽垎闅旀爣棰樼殑鑳屾櫙涓庤竟妗嗚鐩� */
+.order-desc :deep(.el-descriptions__table tr:first-child .el-descriptions__cell),
+.order-desc :deep(.el-descriptions__table tr:first-child .el-descriptions__label),
+.order-desc :deep(.el-descriptions__table tr:first-child .el-descriptions__content) {
+  background: #eef3fb !important;
+  border-top-color: transparent !important;
+  border-bottom-color: #dcdfe6 !important;
+}
+.order-desc :deep(.el-descriptions__table tr:first-child .el-descriptions__label) {
+  border-right-color: transparent !important;
+}
+
+/* 缁熶竴涓や釜鎻忚堪琛ㄦ牸鐨勫垪瀵归綈锛堟爣绛惧垪鍥哄畾瀹藉害锛屽唴瀹瑰垪绛夊垎鍓╀綑瀹藉害锛� */
+.order-desc :deep(.el-descriptions__table) {
+  table-layout: fixed;
+  width: 100%;
+}
+/* 浣跨敤绫婚�夋嫨鍣ㄨ�岄潪 nth-child锛屾彁鍗囩ǔ瀹氭�э紝纭繚姣忚涓ゅ垪涓ユ牸瀵归綈 */
+.order-desc :deep(.el-descriptions__table tr:not(:first-child) .el-descriptions__label) {
+  width: 180px !important;
+  max-width: 180px !important;
+  box-sizing: border-box;
+}
+.order-desc :deep(.el-descriptions__table tr:not(:first-child) .el-descriptions__content) {
+  width: calc(50% - 180px) !important;
+}
+
+.desc-wrap {
+  white-space: pre-wrap;
+  line-height: 22px;
+}
+
+/* 鏂囦欢鍒楄〃琛ㄦ牸鏍峰紡 */
+.file-section {
+  margin-top: 15px;
+  .file-title {
+    font-weight: 600;
+    margin-bottom: 10px;
+  }
+  .file-table {
+    width: 100%;
+    .file-name {
+      display: flex;
+      align-items: center;
+      .file-icon {
+        margin-right: 8px;
+        color: #409eff;
+      }
+    }
+    .preview-btn {
+      color: #409eff;
+      &:hover {
+        text-decoration: underline;
+      }
+    }
+  }
+}
+
+/* 鏂囦欢琛ㄦ牸琛ㄥご绗竴鍒�"浜ゆ槗鏂囦欢"鏂囧瓧闈犲乏瀵归綈 */
+.file-table :deep(.el-table__header-wrapper thead tr th:first-child) {
+  text-align: left !important;
+}
+
+/* 鏂囦欢鎿嶄綔鎸夐挳鏍峰紡 */
+.file-actions {
+  display: flex;
+  gap: 8px;
+  align-items: center;
+  justify-content: center;
+  
+  .preview-btn {
+    color: #409eff;
+    &:hover {
+      text-decoration: underline;
+    }
+    &:disabled {
+      color: #c0c4cc;
+      cursor: not-allowed;
+    }
+  }
+  
+  .download-btn {
+    color: #67c23a;
+    &:hover {
+      text-decoration: underline;
+    }
+    &:disabled {
+      color: #c0c4cc;
+      cursor: not-allowed;
+    }
+  }
+}
+
+/* 浜ゆ槗淇℃伅澶囨敞琛ㄦ牸鏍峰紡 */
+.remark-table {
+  width: 100%;
+  
+  .remark-input {
+    width: 100%;
+    
+    :deep(.el-textarea__inner) {
+      border: none;
+      box-shadow: none;
+      background: transparent;
+      resize: none;
+      padding: 8px 0;
+      
+      &:focus {
+        border: 1px solid #409eff;
+        box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
+        border-radius: 4px;
+        background: #fff;
+        padding: 8px 12px;
+      }
+    }
+    
+    :deep(.el-input__count) {
+      background: transparent;
+      bottom: 2px;
+      right: 8px;
+    }
+  }
+}
+
+/* 瀹℃壒鍐呭鏍峰紡 */
+.approval-content {
+  .approval-form {
+    .form-item {
+      display: flex;
+      align-items: flex-start;
+      margin-bottom: 20px;
+      
+      label {
+        width: 120px;
+        line-height: 32px;
+        margin-right: 10px;
+        font-weight: 500;
+        
+        &.required::before {
+          content: '*';
+          color: #f56c6c;
+          margin-right: 4px;
+        }
+      }
+      
+      .el-textarea {
+        flex: 1;
+      }
+    }
+  }
+  
+  .approval-actions {
+    display: flex;
+    justify-content: center;
+    gap: 15px;
+    margin-top: 30px;
+    
+    .el-button {
+      min-width: 100px;
+    }
+  }
+}
 </style>
 
 

--
Gitblit v1.8.0