From dc98edae03217e7e254c9be94724ba715520c285 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期三, 08 四月 2026 11:27:42 +0800
Subject: [PATCH] 新疆马铃薯 1.添加收货管理页面并联调 2.首页展示数据修改

---
 src/views/index.vue                                                       |   16 
 src/views/procurementManagement/receivingManagement/modal/ReceiptForm.vue |  338 ++++++++++++++++++++++++++++
 src/views/procurementManagement/receivingManagement/index.vue             |  320 ++++++++++++++++++++++++++
 3 files changed, 666 insertions(+), 8 deletions(-)

diff --git a/src/views/index.vue b/src/views/index.vue
index 838182b..1285795 100644
--- a/src/views/index.vue
+++ b/src/views/index.vue
@@ -39,10 +39,10 @@
               <div class="data-desc">鏈湀閿�鍞/鍏�</div>
               <div class="data-value">{{ businessInfo.monthSaleMoney }}</div>
             </div>
-            <div>
-              <div class="data-desc">鏈紑绁ㄩ噾棰�/鍏�</div>
-              <div class="data-value">{{ businessInfo.monthSaleHaveMoney }}</div>
-            </div>
+<!--            <div>-->
+<!--              <div class="data-desc">鏈紑绁ㄩ噾棰�/鍏�</div>-->
+<!--              <div class="data-value">{{ businessInfo.monthSaleHaveMoney }}</div>-->
+<!--            </div>-->
           </div>
 
         </div>
@@ -53,10 +53,10 @@
               <div class="data-desc">鏈湀閲囪喘棰�/鍏�</div>
               <div class="data-value">{{ businessInfo.monthPurchaseMoney }}</div>
             </div>
-            <div>
-              <div class="data-desc">寰呬粯娆鹃噾棰�/鍏�</div>
-              <div class="data-value">{{ businessInfo.monthPurchaseHaveMoney }}</div>
-            </div>
+<!--            <div>-->
+<!--              <div class="data-desc">寰呬粯娆鹃噾棰�/鍏�</div>-->
+<!--              <div class="data-value">{{ businessInfo.monthPurchaseHaveMoney }}</div>-->
+<!--            </div>-->
           </div>
         </div>
         <div class="data-card inventory">
diff --git a/src/views/procurementManagement/receivingManagement/index.vue b/src/views/procurementManagement/receivingManagement/index.vue
new file mode 100644
index 0000000..a0d54a5
--- /dev/null
+++ b/src/views/procurementManagement/receivingManagement/index.vue
@@ -0,0 +1,320 @@
+<template>
+  <div class="app-container">
+    <div class="search_form">
+      <el-form :model="searchForm" :inline="true">
+        <el-form-item label="渚涘簲鍟嗗悕绉帮細">
+          <el-input
+            v-model="searchForm.supplierName"
+            placeholder="璇疯緭鍏�"
+            clearable
+            prefix-icon="Search"
+            @change="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="閲囪喘鍚堝悓鍙凤細">
+          <el-input
+            v-model="searchForm.purchaseContractNumber"
+            style="width: 240px"
+            placeholder="璇疯緭鍏�"
+            clearable
+            prefix-icon="Search"
+            @change="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="閿�鍞悎鍚屽彿锛�">
+          <el-input
+            v-model="searchForm.salesContractNo"
+            placeholder="璇疯緭鍏�"
+            clearable
+            prefix-icon="Search"
+            @change="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="椤圭洰鍚嶇О锛�">
+          <el-input
+            v-model="searchForm.projectName"
+            placeholder="璇疯緭鍏�"
+            clearable
+            prefix-icon="Search"
+            @change="handleQuery"
+          />
+        </el-form-item>
+        <el-form-item label="褰曞叆鏃ユ湡锛�">
+          <el-date-picker
+            v-model="searchForm.entryDate"
+            value-format="YYYY-MM-DD"
+            format="YYYY-MM-DD"
+            type="daterange"
+            placeholder="璇烽�夋嫨"
+            clearable
+            @change="changeDaterange"
+          />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="handleQuery">鎼滅储</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+
+    <div class="table_list">
+      <el-table
+        :data="tableData"
+        border
+        v-loading="tableLoading"
+        :expand-row-keys="expandedRowKeys"
+        :row-key="(row) => row.id"
+        show-summary
+        :summary-method="summarizeMainTable"
+        @expand-change="expandChange"
+        height="calc(100vh - 21.5em)"
+      >
+        <el-table-column type="expand">
+          <template #default="props">
+            <el-table
+              :data="props.row.children"
+              border
+              show-summary
+              :summary-method="summarizeChildrenTable"
+            >
+              <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+              <el-table-column label="浜у搧澶х被" prop="productCategory" />
+              <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
+              <el-table-column label="鍗曚綅" prop="unit" />
+              <el-table-column label="鏁伴噺" prop="quantity" />
+              <el-table-column label="鍙敤鏁伴噺" prop="availableQuality" />
+              <el-table-column label="閫�璐ф暟閲�" prop="returnQuality" />
+              <el-table-column label="绋庣巼(%)" prop="taxRate" />
+              <el-table-column label="鍚◣鍗曚环(鍏�)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" />
+              <el-table-column label="鍚◣鎬讳环(鍏�)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" />
+              <el-table-column label="涓嶅惈绋庢�讳环(鍏�)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" />
+            </el-table>
+          </template>
+        </el-table-column>
+        <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+        <el-table-column label="閲囪喘鍚堝悓鍙�" prop="purchaseContractNumber" width="160" show-overflow-tooltip />
+        <el-table-column label="閿�鍞悎鍚屽彿" prop="salesContractNo" width="160" show-overflow-tooltip />
+        <el-table-column label="渚涘簲鍟嗗悕绉�" prop="supplierName" width="160" show-overflow-tooltip />
+        <el-table-column label="椤圭洰鍚嶇О" prop="projectName" width="320" show-overflow-tooltip />
+        <el-table-column label="鏀惰揣鐘舵��" prop="status" width="100" show-overflow-tooltip>
+          <template #default="scope">
+            <el-tag :type="getReceiptStatusType(scope.row.status)" size="small">
+              {{ receiptStatusText[scope.row.status] || '鏈煡鐘舵��' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="瀹℃壒鐘舵��" prop="approvalStatus" width="100" show-overflow-tooltip>
+          <template #default="scope">
+            <el-tag :type="getApprovalStatusType(scope.row.approvalStatus)" size="small">
+              {{ approvalStatusText[scope.row.approvalStatus] || '鏈煡鐘舵��' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="绛捐鏃ユ湡" prop="executionDate" width="100" show-overflow-tooltip />
+        <el-table-column label="浠樻鏂瑰紡" prop="paymentMethod" width="100" show-overflow-tooltip />
+        <el-table-column label="鍚堝悓閲戦(鍏�)" prop="contractAmount" width="200" show-overflow-tooltip :formatter="formattedNumber" />
+        <el-table-column label="褰曞叆浜�" prop="recorderName" width="120" show-overflow-tooltip />
+        <el-table-column label="褰曞叆鏃ユ湡" prop="entryDate" width="100" show-overflow-tooltip />
+        <el-table-column label="澶囨敞" prop="remarks" width="200" show-overflow-tooltip />
+        <el-table-column fixed="right" label="鎿嶄綔" width="120" align="center">
+          <template #default="scope">
+            <el-button
+              link
+              type="primary"
+              :disabled="isConfirmed(scope.row)"
+              @click="confirmReceipt(scope.row)"
+            >
+              {{ isConfirmed(scope.row) ? '宸叉敹璐�' : '纭鏀惰揣' }}
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination
+        v-show="total > 0"
+        :total="total"
+        layout="total, sizes, prev, pager, next, jumper"
+        :page="page.current"
+        :limit="page.size"
+        @pagination="paginationChange"
+      />
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { onMounted, reactive, ref } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import dayjs from 'dayjs'
+import Pagination from '@/components/PIMTable/Pagination.vue'
+import { productList, purchaseListPage, updateApprovalStatus } from '@/api/procurementManagement/procurementLedger.js'
+
+const tableData = ref([])
+const tableLoading = ref(false)
+const total = ref(0)
+const expandedRowKeys = ref([])
+const receiptResultMap = ref({})
+
+const page = reactive({
+  current: 1,
+  size: 100
+})
+
+const searchForm = reactive({
+  supplierName: '',
+  purchaseContractNumber: '',
+  salesContractNo: '',
+  projectName: '',
+  entryDate: [],
+  entryDateStart: undefined,
+  entryDateEnd: undefined
+})
+
+const approvalStatusText = {
+  1: '寰呭鏍�',
+  2: '瀹℃壒涓�',
+  3: '瀹℃壒閫氳繃',
+  4: '瀹℃壒澶辫触'
+}
+
+const receiptStatusText = {
+  1: '寰呮敹璐�',
+  2: '鏀惰揣涓�',
+  3: '宸叉敹璐�'
+}
+
+const getApprovalStatusType = (status) => {
+  const typeMap = {
+    1: 'info',
+    2: 'warning',
+    3: 'success',
+    4: 'danger'
+  }
+  return typeMap[status]
+}
+
+const getReceiptStatusType = (status) => {
+  const typeMap = {
+    1: 'info',
+    2: 'warning',
+    3: 'success'
+  }
+  return typeMap[status]
+}
+
+const formattedNumber = (_row, _column, cellValue) => {
+  const value = Number(cellValue)
+  return Number.isFinite(value) ? value.toFixed(2) : '0.00'
+}
+
+const createSummary = (columns, data, sumFields) => {
+  const sums = []
+  columns.forEach((column, index) => {
+    if (index === 0) {
+      sums[index] = '鍚堣'
+      return
+    }
+    if (!sumFields.includes(column.property)) {
+      sums[index] = ''
+      return
+    }
+    const totalValue = data.reduce((sum, item) => sum + Number(item?.[column.property] || 0), 0)
+    sums[index] = Number.isFinite(totalValue) ? totalValue.toFixed(2) : '0.00'
+  })
+  return sums
+}
+
+const summarizeMainTable = ({ columns, data }) => createSummary(columns, data, ['contractAmount'])
+
+const summarizeChildrenTable = ({ columns, data }) =>
+  createSummary(columns, data, ['quantity', 'availableQuality', 'returnQuality', 'taxInclusiveUnitPrice', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice'])
+
+const isConfirmed = (row) => Number(row?.status) === 3 || Boolean(receiptResultMap.value[row?.id])
+
+const handleQuery = () => {
+  page.current = 1
+  getList()
+}
+
+const changeDaterange = (value) => {
+  if (value) {
+    searchForm.entryDateStart = dayjs(value[0]).format('YYYY-MM-DD')
+    searchForm.entryDateEnd = dayjs(value[1]).format('YYYY-MM-DD')
+  } else {
+    searchForm.entryDateStart = undefined
+    searchForm.entryDateEnd = undefined
+  }
+  handleQuery()
+}
+
+const paginationChange = (obj) => {
+  page.current = obj.page
+  page.size = obj.limit
+  getList()
+}
+
+const expandChange = async (row, expandedRows) => {
+  if (expandedRows.length > 0) {
+    expandedRowKeys.value = []
+    try {
+      const res = await productList({ salesLedgerId: row.id, type: 2 })
+      const index = tableData.value.findIndex((item) => item.id === row.id)
+      if (index > -1) {
+        tableData.value[index].children = res.data || []
+        expandedRowKeys.value.push(row.id)
+      }
+    } catch (_error) {
+      ElMessage.error('鍔犺浇浜у搧鍒楄〃澶辫触')
+      const index = expandedRows.findIndex((item) => item.id === row.id)
+      if (index > -1) {
+        expandedRows.splice(index, 1)
+      }
+    }
+  } else {
+    expandedRowKeys.value = []
+  }
+}
+
+const getList = () => {
+  tableLoading.value = true
+  const { entryDate, ...rest } = searchForm
+  purchaseListPage({ ...rest, ...page, approvalStatus: 3 })
+    .then((res) => {
+      tableData.value = (res.data?.records || []).map((record) => ({
+        ...record,
+        children: []
+      }))
+      total.value = res.data?.total || 0
+      expandedRowKeys.value = []
+    })
+    .finally(() => {
+      tableLoading.value = false
+    })
+}
+
+const confirmReceipt = async (row) => {
+  try {
+    await ElMessageBox.confirm('鏄惁纭鏀惰揣锛�', '纭鏀惰揣', {
+      type: 'warning',
+      confirmButtonText: '纭',
+      cancelButtonText: '鍙栨秷'
+    })
+
+    await updateApprovalStatus({
+      id: row.id,
+      status: 3
+    })
+
+    receiptResultMap.value[row.id] = true
+    ElMessage.success('纭鏀惰揣鎴愬姛')
+    getList()
+  } catch (error) {
+    if (error !== 'cancel' && error !== 'close') {
+      ElMessage.error('纭鏀惰揣澶辫触')
+    }
+  }
+}
+
+onMounted(() => {
+  getList()
+})
+</script>
diff --git a/src/views/procurementManagement/receivingManagement/modal/ReceiptForm.vue b/src/views/procurementManagement/receivingManagement/modal/ReceiptForm.vue
new file mode 100644
index 0000000..345431c
--- /dev/null
+++ b/src/views/procurementManagement/receivingManagement/modal/ReceiptForm.vue
@@ -0,0 +1,338 @@
+<template>
+  <FormDialog
+    v-model="dialogVisible"
+    title="纭鏀惰揣"
+    width="70%"
+    operation-type="edit"
+    @close="handleClose"
+    @cancel="handleClose"
+    @confirm="handleConfirm"
+  >
+    <el-form ref="formRef" :model="detailData" label-width="140px" label-position="top">
+      <el-row :gutter="30">
+        <el-col :span="12">
+          <el-form-item label="閲囪喘鍚堝悓鍙凤細">
+            <el-input :model-value="detailData.purchaseContractNumber || ''" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="閿�鍞悎鍚屽彿锛�">
+            <el-input :model-value="detailData.salesContractNo || ''" disabled />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="30">
+        <el-col :span="12">
+          <el-form-item label="渚涘簲鍟嗗悕绉帮細">
+            <el-input :model-value="detailData.supplierName || ''" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="椤圭洰鍚嶇О锛�">
+            <el-input :model-value="detailData.projectName || ''" disabled />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="30">
+        <el-col :span="12">
+          <el-form-item label="浠樻鏂瑰紡锛�">
+            <el-input :model-value="detailData.paymentMethod || ''" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="绛捐鏃ユ湡锛�">
+            <el-input :model-value="detailData.executionDate || ''" disabled />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="30">
+        <el-col :span="12">
+          <el-form-item label="褰曞叆浜猴細">
+            <el-input :model-value="detailData.recorderName || ''" disabled />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="褰曞叆鏃ユ湡锛�">
+            <el-input :model-value="detailData.entryDate || ''" disabled />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="30">
+        <el-col :span="24">
+          <el-form-item label="瀹℃壒浜洪�夋嫨锛�">
+            <div class="approver-nodes-container">
+              <div v-for="(name, index) in approverNames" :key="`${name}-${index}`" class="approver-node-item">
+                <div class="approver-node-header">
+                  <span class="approver-node-label">瀹℃壒鑺傜偣 {{ index + 1 }}</span>
+                </div>
+                <el-input :model-value="name" disabled />
+              </div>
+              <el-empty v-if="!approverNames.length" description="鏆傛棤瀹℃壒浜轰俊鎭�" />
+            </div>
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-form-item label="浜у搧淇℃伅锛�">
+        <el-table :data="detailData.productData" border show-summary :summary-method="summarizeProductTable">
+          <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+          <el-table-column label="浜у搧澶х被" prop="productCategory" />
+          <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
+          <el-table-column label="鍗曚綅" prop="unit" width="70" />
+          <el-table-column label="鏁伴噺" prop="quantity" width="90" />
+          <el-table-column label="搴撳瓨棰勮鏁伴噺" prop="warnNum" width="120" show-overflow-tooltip />
+          <el-table-column label="绋庣巼(%)" prop="taxRate" width="80" />
+          <el-table-column label="鍚◣鍗曚环(鍏�)" prop="taxInclusiveUnitPrice" width="150" :formatter="formattedNumber" />
+          <el-table-column label="鍚◣鎬讳环(鍏�)" prop="taxInclusiveTotalPrice" width="150" :formatter="formattedNumber" />
+          <el-table-column label="涓嶅惈绋庢�讳环(鍏�)" prop="taxExclusiveTotalPrice" width="150" :formatter="formattedNumber" />
+          <el-table-column label="鏄惁璐ㄦ" prop="isChecked" width="100">
+            <template #default="scope">
+              <el-tag :type="scope.row.isChecked ? 'success' : 'info'">
+                {{ scope.row.isChecked ? '鏄�' : '鍚�' }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="鏄惁鍚堟牸" min-width="180">
+            <template #default="scope">
+              <el-form-item
+                :prop="`productData.${scope.$index}.isQualified`"
+                :rules="[{ required: true, message: '璇烽�夋嫨鏄惁鍚堟牸', trigger: 'change' }]"
+                class="inline-form-item"
+              >
+                <el-radio-group v-model="scope.row.isQualified">
+                  <el-radio :label="1">鍚堟牸</el-radio>
+                  <el-radio :label="2">涓嶅悎鏍�</el-radio>
+                </el-radio-group>
+              </el-form-item>
+            </template>
+          </el-table-column>
+          <el-table-column label="涓嶅悎鏍煎師鍥�" min-width="220">
+            <template #default="scope">
+              <el-form-item
+                :prop="`productData.${scope.$index}.reason`"
+                :rules="[{
+                  validator: (_rule, value, callback) => validateReason(scope.row, value, callback),
+                  trigger: 'blur'
+                }]"
+                class="inline-form-item"
+              >
+                <el-input
+                  v-model="scope.row.reason"
+                  :disabled="scope.row.isQualified !== 2"
+                  placeholder="涓嶅悎鏍兼椂璇峰~鍐欏師鍥�"
+                  clearable
+                />
+              </el-form-item>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-form-item>
+
+      <el-row :gutter="30">
+        <el-col :span="24">
+          <el-form-item label="澶囨敞锛�">
+            <el-input :model-value="detailData.remarks || ''" type="textarea" :rows="2" disabled />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row :gutter="30">
+        <el-col :span="24">
+          <el-form-item label="闄勪欢鏉愭枡锛�">
+            <div class="file-list">
+              <el-tag v-for="file in detailData.salesLedgerFiles" :key="file.id || file.fileName" class="file-tag">
+                {{ file.fileName || file.name }}
+              </el-tag>
+              <el-empty v-if="!detailData.salesLedgerFiles?.length" description="鏆傛棤闄勪欢" />
+            </div>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+  </FormDialog>
+</template>
+
+<script setup>
+import { computed, reactive, ref, watch } from 'vue'
+import { ElMessage } from 'element-plus'
+import FormDialog from '@/components/Dialog/FormDialog.vue'
+
+const props = defineProps({
+  modelValue: {
+    type: Boolean,
+    default: false
+  },
+  record: {
+    type: Object,
+    default: () => ({})
+  }
+})
+
+const emit = defineEmits(['update:modelValue', 'submit'])
+
+const formRef = ref()
+
+const dialogVisible = computed({
+  get: () => props.modelValue,
+  set: (value) => emit('update:modelValue', value)
+})
+
+const createDefaultDetail = () => ({
+  id: '',
+  purchaseContractNumber: '',
+  salesContractNo: '',
+  supplierName: '',
+  projectName: '',
+  paymentMethod: '',
+  executionDate: '',
+  recorderName: '',
+  entryDate: '',
+  remarks: '',
+  approveUserIds: '',
+  approverNames: [],
+  salesLedgerFiles: [],
+  productData: []
+})
+
+const detailData = reactive(createDefaultDetail())
+
+const approverNames = computed(() => detailData.approverNames || [])
+
+const formattedNumber = (_row, _column, cellValue) => {
+  const value = Number(cellValue)
+  return Number.isFinite(value) ? value.toFixed(2) : '0.00'
+}
+
+const summarizeProductTable = ({ columns, data }) => {
+  const sumFields = ['quantity', 'taxInclusiveUnitPrice', 'taxInclusiveTotalPrice', 'taxExclusiveTotalPrice']
+  const sums = []
+  columns.forEach((column, index) => {
+    if (index === 0) {
+      sums[index] = '鍚堣'
+      return
+    }
+    if (!sumFields.includes(column.property)) {
+      sums[index] = ''
+      return
+    }
+    const total = data.reduce((sum, item) => sum + Number(item?.[column.property] || 0), 0)
+    sums[index] = Number.isFinite(total) ? total.toFixed(2) : '0.00'
+  })
+  return sums
+}
+
+const validateReason = (row, value, callback) => {
+  if (row.isQualified === 2 && (!value || !value.trim())) {
+    callback(new Error('涓嶅悎鏍兼椂蹇呴』濉啓鍘熷洜'))
+    return
+  }
+  callback()
+}
+
+watch(
+  () => props.record,
+  (value) => {
+    const nextData = createDefaultDetail()
+    Object.assign(nextData, value || {})
+    nextData.productData = (value?.productData || []).map((item) => ({
+      ...item,
+      isQualified: item.isQualified ?? undefined,
+      reason: item.reason || ''
+    }))
+    nextData.salesLedgerFiles = value?.salesLedgerFiles || []
+    nextData.approverNames = value?.approverNames || []
+    Object.assign(detailData, nextData)
+  },
+  { immediate: true, deep: true }
+)
+
+const handleClose = () => {
+  dialogVisible.value = false
+}
+
+const handleConfirm = async () => {
+  if (!formRef.value) {
+    return
+  }
+  try {
+    await formRef.value.validate()
+    const unqualifiedRows = detailData.productData.filter((item) => item.isQualified === 2)
+    emit('submit', {
+      id: detailData.id,
+      purchaseContractNumber: detailData.purchaseContractNumber,
+      supplierName: detailData.supplierName,
+      projectName: detailData.projectName,
+      productData: detailData.productData.map((item) => ({
+        id: item.id,
+        specificationModel: item.specificationModel,
+        quantity: item.quantity,
+        isQualified: item.isQualified,
+        reason: item.reason || ''
+      })),
+      unqualifiedQuantity: unqualifiedRows.reduce((sum, item) => sum + Number(item.quantity || 0), 0)
+    })
+    dialogVisible.value = false
+  } catch (_error) {
+    ElMessage.warning('璇峰厛瀹屾垚姣忔潯浜у搧鐨勬敹璐у垽鏂�')
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.approver-nodes-container {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 16px;
+  width: 100%;
+}
+
+.approver-node-item {
+  flex: 0 0 calc(33.333% - 12px);
+  min-width: 220px;
+  padding: 12px;
+  background-color: #fff;
+  border-radius: 4px;
+  border: 1px solid #dcdfe6;
+}
+
+.approver-node-header {
+  margin-bottom: 8px;
+}
+
+.approver-node-label {
+  font-size: 13px;
+  font-weight: 500;
+  color: #606266;
+}
+
+.inline-form-item {
+  margin-bottom: 0;
+}
+
+.file-list {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 8px;
+  width: 100%;
+}
+
+.file-tag {
+  margin-right: 0;
+}
+
+@media (max-width: 1200px) {
+  .approver-node-item {
+    flex: 0 0 calc(50% - 8px);
+  }
+}
+
+@media (max-width: 768px) {
+  .approver-node-item {
+    flex: 0 0 100%;
+  }
+}
+</style>

--
Gitblit v1.9.3