From 2d5ff68e16ce08e814df35b226687c8575498a44 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期四, 16 四月 2026 15:19:26 +0800
Subject: [PATCH] 维护审批人功能,以及影响到的模块更改

---
 src/views/collaborativeApproval/approvalProcess/index.vue |  834 ++++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 597 insertions(+), 237 deletions(-)

diff --git a/src/views/collaborativeApproval/approvalProcess/index.vue b/src/views/collaborativeApproval/approvalProcess/index.vue
index 13e155b..a9df154 100644
--- a/src/views/collaborativeApproval/approvalProcess/index.vue
+++ b/src/views/collaborativeApproval/approvalProcess/index.vue
@@ -1,284 +1,589 @@
 <template>
   <div class="app-container">
+    <!-- 鏍囩椤靛垏鎹笉鍚岀殑瀹℃壒绫诲瀷 -->
+    <el-tabs v-model="activeTab"
+             @tab-change="handleTabChange"
+             class="approval-tabs">
+      <el-tab-pane label="鍏嚭绠$悊"
+                   name="1"></el-tab-pane>
+      <el-tab-pane label="璇峰亣绠$悊"
+                   name="2"></el-tab-pane>
+      <el-tab-pane label="鍑哄樊绠$悊"
+                   name="3"></el-tab-pane>
+      <el-tab-pane label="鎶ラ攢绠$悊"
+                   name="4"></el-tab-pane>
+      <el-tab-pane label="閲囪喘瀹℃壒"
+                   name="5"></el-tab-pane>
+      <el-tab-pane label="鎶ヤ环瀹℃壒"
+                   name="6"></el-tab-pane>
+      <el-tab-pane label="鍙戣揣瀹℃壒"
+                   name="7"></el-tab-pane>
+    </el-tabs>
     <div class="search_form">
       <div>
         <span class="search_title">娴佺▼缂栧彿锛�</span>
-        <el-input
-            v-model="searchForm.approveId"
-            style="width: 240px"
-            placeholder="璇疯緭鍏ユ祦绋嬬紪鍙锋悳绱�"
-            @change="handleQuery"
-            clearable
-            :prefix-icon="Search"
-        />
+        <el-input v-model="searchForm.approveId"
+                  style="width: 240px"
+                  placeholder="璇疯緭鍏ユ祦绋嬬紪鍙锋悳绱�"
+                  @change="handleQuery"
+                  clearable
+                  :prefix-icon="Search" />
         <span class="search_title ml10">瀹℃壒鐘舵�侊細</span>
-				<el-select v-model="searchForm.approveStatus" clearable @change="handleQuery" style="width: 240px">
-					<el-option label="寰呭鏍�" :value="0" />
-					<el-option label="瀹℃牳涓�" :value="1" />
-					<el-option label="瀹℃牳瀹屾垚" :value="2" />
-					<el-option label="瀹℃牳鏈�氳繃" :value="3" />
-					<el-option label="宸查噸鏂版彁浜�" :value="4" />
-				</el-select>
-        <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
-        >鎼滅储</el-button
-        >
+        <el-select v-model="searchForm.approveStatus"
+                   clearable
+                   @change="handleQuery"
+                   style="width: 240px">
+          <el-option label="寰呭鏍�"
+                     :value="0" />
+          <el-option label="瀹℃牳涓�"
+                     :value="1" />
+          <el-option label="瀹℃牳瀹屾垚"
+                     :value="2" />
+          <el-option label="瀹℃牳鏈�氳繃"
+                     :value="3" />
+          <el-option label="宸查噸鏂版彁浜�"
+                     :value="4" />
+        </el-select>
+        <el-button type="primary"
+                   @click="handleQuery"
+                   style="margin-left: 10px">鎼滅储</el-button>
       </div>
       <div>
-        <el-button type="primary" @click="openForm('add')">鏂板</el-button>
-        <el-button @click="handleOut">瀵煎嚭</el-button>
-        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+        <el-button @click="handleOut">瀹℃壒浜虹淮鎶�</el-button>
+        <el-button type="primary"
+                   @click="openForm('add')"
+                   v-if="currentApproveType !== 5 && currentApproveType !== 6 && currentApproveType !== 7">鏂板</el-button>
+        <el-button @click="handleExport">瀵煎嚭</el-button>
+        <el-button type="danger"
+                   plain
+                   @click="handleDelete"
+                   v-if="currentApproveType !== 5 && currentApproveType !== 6 && currentApproveType !== 7">鍒犻櫎</el-button>
       </div>
     </div>
     <div class="table_list">
-      <PIMTable
-          rowKey="id"
-          :column="tableColumn"
-          :tableData="tableData"
-          :page="page"
-          :isSelection="true"
-          @selection-change="handleSelectionChange"
-          :tableLoading="tableLoading"
-          @pagination="pagination"
-          :total="page.total"
-      ></PIMTable>
+      <PIMTable rowKey="id"
+                :column="tableColumnCopy"
+                :tableData="tableData"
+                :page="page"
+                :isSelection="true"
+                @selection-change="handleSelectionChange"
+                :tableLoading="tableLoading"
+                @pagination="pagination"
+                :total="page.total"></PIMTable>
     </div>
-    <info-form-dia ref="infoFormDia" @close="handleQuery" :approveType="approveType"></info-form-dia>
-    <approval-dia ref="approvalDia" @close="handleQuery"></approval-dia>
+    <info-form-dia ref="infoFormDia"
+                   @close="handleQuery"
+                   :approveType="currentApproveType"></info-form-dia>
+    <approval-dia ref="approvalDia"
+                  @close="handleQuery"
+                  :approveType="currentApproveType"></approval-dia>
     <FileList ref="fileListRef" />
+    <!-- 瀹℃壒浜虹淮鎶ゅ璇濇 -->
+    <el-dialog v-model="approverDialogVisible"
+               title="瀹℃壒浜虹淮鎶�"
+               width="800px">
+      <div class="approver-dialog">
+        <div class="selected-info"
+             v-if="selectedApprovers.length > 0">
+          <div class="info-title">宸查�夋嫨鐨勫鎵逛汉锛�</div>
+          <div class="selected-list">
+            <el-tag v-for="approver in selectedApprovers"
+                    :key="approver.id"
+                    class="approver-tag">
+              {{ approver.userName }}
+              <el-icon class="el-tag__close el-icon--close"
+                       @click="removeApprover(approver)">
+                <CircleClose />
+              </el-icon>
+            </el-tag>
+          </div>
+        </div>
+        <el-table ref="approverTable"
+                  :data="approverList"
+                  style="width: 100%"
+                  @selection-change="handleApproverSelectionChange"
+                  v-loading="approverLoading">
+          <el-table-column type="selection"
+                           width="55"></el-table-column>
+          <el-table-column prop="userId"
+                           label="ID"></el-table-column>
+          <el-table-column prop="userName"
+                           label="濮撳悕"></el-table-column>
+          <el-table-column prop="createTime"
+                           label="鍒涘缓鏃堕棿"></el-table-column>
+        </el-table>
+      </div>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="approverDialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary"
+                     @click="submitApprovers"
+                     :disabled="selectedApprovers.length === 0">
+            鎻愪氦
+          </el-button>
+        </span>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
 <script setup>
-import FileList from "./fileList.vue";
-import { Search } from "@element-plus/icons-vue";
-import {onMounted, ref} from "vue";
-import {ElMessageBox} from "element-plus";
-import InfoFormDia from "@/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue";
-import ApprovalDia from "@/views/collaborativeApproval/approvalProcess/components/approvalDia.vue";
-import {approveProcessDelete, approveProcessListPage} from "@/api/collaborativeApproval/approvalProcess.js";
-import useUserStore from "@/store/modules/user";
+  import FileList from "./fileList.vue";
+  import { Search } from "@element-plus/icons-vue";
+  import {
+    onMounted,
+    ref,
+    computed,
+    reactive,
+    toRefs,
+    nextTick,
+    getCurrentInstance,
+  } from "vue";
+  import { ElMessageBox } from "element-plus";
+  import { useRoute } from "vue-router";
+  import InfoFormDia from "@/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue";
+  import ApprovalDia from "@/views/collaborativeApproval/approvalProcess/components/approvalDia.vue";
+  import {
+    approveProcessDelete,
+    approveProcessListPage,
+    approveUserList,
+    addApproveUser,
+    deleteApproveUser,
+  } from "@/api/collaborativeApproval/approvalProcess.js";
+  import { userListNoPageByTenantId } from "@/api/system/user.js";
+  import useUserStore from "@/store/modules/user";
 
-// 瀹氫箟缁勪欢鎺ユ敹鐨刾rops
-const props = defineProps({
-  approveType: {
-    type: [Number, String],
-    default: 0
-  }
-});
+  const userStore = useUserStore();
+  const route = useRoute();
 
-const userStore = useUserStore();
+  // 褰撳墠閫変腑鐨勬爣绛鹃〉锛岄粯璁や负鍏嚭绠$悊
+  const activeTab = ref("1");
 
+  // 褰撳墠瀹℃壒绫诲瀷锛屾牴鎹�変腑鐨勬爣绛鹃〉璁$畻
+  const currentApproveType = computed(() => {
+    return Number(activeTab.value);
+  });
 
-const data = reactive({
-  searchForm: {
-		approveId: "",
-		approveStatus: "",
-  },
-});
-const { searchForm } = toRefs(data);
-const tableColumn = ref([
-  {
-    label: "瀹℃壒鐘舵��",
-    prop: "approveStatus",
-    dataType: "tag",
-		width: 100,
-    formatData: (params) => {
-      if (params == 0) {
-        return "寰呭鏍�";
-      } else if (params == 1) {
-        return "瀹℃牳涓�";
-      } else if (params == 2) {
-        return "瀹℃牳瀹屾垚";
-      } else if (params == 4) {
-        return "宸查噸鏂版彁浜�";
-      } else {
-        return '涓嶉�氳繃';
-      }
+  // 鏍囩椤靛垏鎹㈠鐞�
+  const handleTabChange = tabName => {
+    // 鍒囨崲鏍囩椤垫椂閲嶇疆鎼滅储鏉′欢鍜屽垎椤碉紝骞堕噸鏂板姞杞芥暟鎹�
+    searchForm.value.approveId = "";
+    searchForm.value.approveStatus = "";
+    page.current = 1;
+    getList();
+  };
+
+  const data = reactive({
+    searchForm: {
+      approveId: "",
+      approveStatus: "",
     },
-    formatType: (params) => {
-      if (params == 0) {
-        return "warning";
-      } else if (params == 1) {
-        return "primary";
-      } else if (params == 2) {
-        return "success";
-      } else if (params == 4) {
-        return "";
-      } else {
-        return 'danger';
+  });
+  const { searchForm } = toRefs(data);
+
+  // 鍔ㄦ�佽〃鏍煎垪閰嶇疆锛屾牴鎹鎵圭被鍨嬬敓鎴愬垪
+  const tableColumnCopy = computed(() => {
+    const isLeaveType = currentApproveType.value === 2; // 璇峰亣绠$悊
+    const isReimburseType = currentApproveType.value === 4; // 鎶ラ攢绠$悊
+    const isQuotationType = currentApproveType.value === 6; // 鎶ヤ环瀹℃壒
+    const isPurchaseType = currentApproveType.value === 5; // 閲囪喘瀹℃壒
+
+    // 鍩虹鍒楅厤缃�
+    const baseColumns = [
+      {
+        label: "瀹℃壒鐘舵��",
+        prop: "approveStatus",
+        dataType: "tag",
+        width: 100,
+        formatData: params => {
+          if (params == 0) {
+            return "寰呭鏍�";
+          } else if (params == 1) {
+            return "瀹℃牳涓�";
+          } else if (params == 2) {
+            return "瀹℃牳瀹屾垚";
+          } else if (params == 4) {
+            return "宸查噸鏂版彁浜�";
+          } else {
+            return "涓嶉�氳繃";
+          }
+        },
+        formatType: params => {
+          if (params == 0) {
+            return "warning";
+          } else if (params == 1) {
+            return "primary";
+          } else if (params == 2) {
+            return "success";
+          } else if (params == 4) {
+            return "info";
+          } else {
+            return "danger";
+          }
+        },
+      },
+      {
+        label: "娴佺▼缂栧彿",
+        prop: "approveId",
+        width: 170,
+      },
+      {
+        label: "鐢宠閮ㄩ棬",
+        prop: "approveDeptName",
+        width: 220,
+      },
+      {
+        label: isQuotationType
+          ? "鎶ヤ环鍗曞彿"
+          : isPurchaseType
+          ? "閲囪喘鍚堝悓鍙�"
+          : "瀹℃壒浜嬬敱",
+        prop: "approveReason",
+      },
+      {
+        label: "鐢宠浜�",
+        prop: "approveUserName",
+        width: 120,
+      },
+    ];
+
+    // 閲戦鍒楋紙浠呮姤閿�绠$悊鏄剧ず锛�
+    if (isReimburseType) {
+      baseColumns.push({
+        label: "閲戦锛堝厓锛�",
+        prop: "price",
+        width: 120,
+      });
+    }
+
+    // 鏃ユ湡鍒楋紙鏍规嵁绫诲瀷鍔ㄦ�侀厤缃級
+    baseColumns.push(
+      {
+        label: isLeaveType ? "寮�濮嬫棩鏈�" : "鐢宠鏃ユ湡",
+        prop: isLeaveType ? "startDate" : "approveTime",
+        width: 200,
+      },
+      {
+        label: "缁撴潫鏃ユ湡",
+        prop: isLeaveType ? "endDate" : "approveOverTime",
+        width: 120,
       }
-    },
-  },
-  {
-    label: "娴佺▼缂栧彿",
-    prop: "approveId",
-    width: 170
-  },
-  {
-    label: "鐢宠閮ㄩ棬",
-    prop: "approveDeptName",
-		width: 220
-  },
-  {
-    label: "瀹℃壒浜嬬敱",
-    prop: "approveReason",
-		width: 200
-  },
-  {
-    label: "鐢宠浜�",
-    prop: "approveUserName",
-    width: 120
-  },
-  {
-    label: "鐢宠鏃ユ湡",
-    prop: "approveTime",
-		width: 200
-  },
-  {
-    label: "缁撴潫鏃ユ湡",
-    prop: "approveOverTime",
-    width: 120
-  },
-  {
-    label: "褰撳墠瀹℃壒浜�",
-    prop: "approveUserCurrentName",
-    width: 120
-  },
-  {
-    dataType: "action",
-    label: "鎿嶄綔",
-    align: "center",
-    fixed: "right",
-    width: 230,
-    operation: [
+    );
+
+    // 褰撳墠瀹℃壒浜哄垪
+    baseColumns.push({
+      label: "褰撳墠瀹℃壒浜�",
+      prop: "approveUserCurrentName",
+      width: 120,
+    });
+
+    // 鎿嶄綔鍒�
+    const actionOperations = [
       {
         name: "缂栬緫",
         type: "text",
-        clickFun: (row) => {
+        clickFun: row => {
           openForm("edit", row);
         },
-				disabled: (row) => row.approveStatus == 2 || row.approveStatus == 1 || row.approveStatus == 4
+        disabled: row =>
+          currentApproveType.value === 5 ||
+          currentApproveType.value === 6 ||
+          currentApproveType.value === 7 ||
+          row.approveStatus == 2 ||
+          row.approveStatus == 1 ||
+          row.approveStatus == 4,
       },
       {
         name: "瀹℃牳",
         type: "text",
-        clickFun: (row) => {
+        clickFun: row => {
           openApprovalDia("approval", row);
         },
-				disabled: (row) => row.approveUserCurrentId == null || row.approveStatus == 2 || row.approveStatus == 3 || row.approveStatus == 4 || row.approveUserCurrentId !== userStore.id
+        disabled: row =>
+          row.approveUserCurrentId == null ||
+          row.approveStatus == 2 ||
+          row.approveStatus == 3 ||
+          row.approveStatus == 4 ||
+          row.approveUserCurrentId !== userStore.id,
       },
       {
         name: "璇︽儏",
         type: "text",
-        clickFun: (row) => {
-          openApprovalDia('view', row);
+        clickFun: row => {
+          openApprovalDia("view", row);
         },
       },
-      {
+    ];
+
+    // 鎶ヤ环瀹℃壒锛堢被鍨� 6锛変笉灞曠ず鈥滈檮浠垛�濇搷浣�
+    if (!isQuotationType) {
+      actionOperations.push({
         name: "闄勪欢",
         type: "text",
-        clickFun: (row) => {
+        clickFun: row => {
           downLoadFile(row);
         },
-      },
-    ],
-  },
-]);
-const tableData = ref([]);
-const selectedRows = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
-  current: 1,
-  size: 100,
-  total: 0
-});
-const infoFormDia = ref()
-const approvalDia = ref()
-const { proxy } = getCurrentInstance()
+      });
+    }
 
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
-  page.current = 1;
-  getList();
-};
-const fileListRef = ref(null)
-const downLoadFile = (row) => {
-  fileListRef.value.open(row.commonFileList)
+    baseColumns.push({
+      dataType: "action",
+      label: "鎿嶄綔",
+      align: "center",
+      fixed: "right",
+      width: 230,
+      operation: actionOperations,
+    });
 
-}
-const pagination = (obj) => {
-  page.current = obj.page;
-  page.size = obj.limit;
-  getList();
-};
-const getList = () => {
-  tableLoading.value = true;
-  approveProcessListPage({...page, ...searchForm.value,approveType:props.approveType}).then(res => {
-    tableLoading.value = false;
-    tableData.value = res.data.records
-    page.total = res.data.total;
-  }).catch(err => {
-    tableLoading.value = false;
-  })
-};
-// 瀵煎嚭
-const handleOut = () => {
-  const type = Number(props.approveType || 0)
-  const urlMap = {
-    0: "/approveProcess/exportZero",
-    1: "/approveProcess/exportOne",
-    2: "/approveProcess/exportTwo",
-    3: "/approveProcess/exportThree",
-    4: "/approveProcess/exportFour",
-    5: "/approveProcess/exportFive",
-  }
-  const url = urlMap[type] || urlMap[0]
-  const nameMap = {
-    0: "鍗忓悓瀹℃壒绠$悊琛�",
-    1: "鍏嚭绠$悊瀹℃壒琛�",
-    2: "璇峰亣绠$悊瀹℃壒琛�",
-    3: "鍑哄樊绠$悊瀹℃壒琛�",
-    4: "鎶ラ攢绠$悊瀹℃壒琛�",
-    5: "閲囪喘鐢宠瀹℃壒琛�",
-  }
-  const fileName = nameMap[type] || nameMap[0]
-  proxy.download(url, {}, `${fileName}.xlsx`)
-}
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
-  selectedRows.value = selection;
-};
+    return baseColumns;
+  });
+  const tableData = ref([]);
+  const selectedRows = ref([]);
+  const tableLoading = ref(false);
+  const page = reactive({
+    current: 1,
+    size: 100,
+    total: 0,
+  });
+  const infoFormDia = ref();
+  const approvalDia = ref();
+  const { proxy } = getCurrentInstance();
 
-// 鎵撳紑鏂板銆佺紪杈戝脊妗�
-const openForm = (type, row) => {
-  nextTick(() => {
-    infoFormDia.value?.openDialog(type, row)
-  })
-};
-// 鎵撳紑鏂板妫�楠屽脊妗�
-const openApprovalDia = (type, row) => {
-  nextTick(() => {
-    approvalDia.value?.openDialog(type, row)
-  })
-};
+  // 瀹℃壒浜虹淮鎶ゅ璇濇
+  const approverDialogVisible = ref(false);
+  const selectedApprovers = ref([]);
+  const existingApprovers = ref([]); // 宸叉湁鐨勫鎵逛汉鍒楄〃
+  const approverLoading = ref(false); // 鍔犺浇鐘舵��
 
-// 鍒犻櫎
-const handleDelete = () => {
-  let ids = [];
-  if (selectedRows.value.length > 0) {
-    ids = selectedRows.value.map((item) => item.approveId);
-  } else {
-    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
-    return;
-  }
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
+  // 瀹℃壒浜哄垪琛ㄦ暟鎹�
+  const approverList = ref([]);
+  const approverTable = ref(null);
+
+  // 鏌ヨ鍒楄〃
+  /** 鎼滅储鎸夐挳鎿嶄綔 */
+  const handleQuery = () => {
+    page.current = 1;
+    getList();
+  };
+  const fileListRef = ref(null);
+  const downLoadFile = row => {
+    fileListRef.value.open(row.commonFileList);
+  };
+  const pagination = obj => {
+    page.current = obj.page;
+    page.size = obj.limit;
+    getList();
+  };
+  const getList = () => {
+    tableLoading.value = true;
+    approveProcessListPage({
+      ...page,
+      ...searchForm.value,
+      approveType: currentApproveType.value,
+    })
+      .then(res => {
+        tableLoading.value = false;
+        tableData.value = res.data.records;
+        page.total = res.data.total;
+      })
+      .catch(err => {
+        tableLoading.value = false;
+      });
+  };
+  // 瀵煎嚭
+  const handleExport = () => {
+    const type = currentApproveType.value;
+    const urlMap = {
+      0: "/approveProcess/exportZero",
+      1: "/approveProcess/exportOne",
+      2: "/approveProcess/exportTwo",
+      3: "/approveProcess/exportThree",
+      4: "/approveProcess/exportFour",
+      5: "/approveProcess/exportFive",
+      6: "/approveProcess/exportSix",
+      7: "/approveProcess/exportSeven",
+    };
+    const url = urlMap[type] || urlMap[0];
+    const nameMap = {
+      0: "鍗忓悓瀹℃壒绠$悊琛�",
+      1: "鍏嚭绠$悊瀹℃壒琛�",
+      2: "璇峰亣绠$悊瀹℃壒琛�",
+      3: "鍑哄樊绠$悊瀹℃壒琛�",
+      4: "鎶ラ攢绠$悊瀹℃壒琛�",
+      5: "閲囪喘鐢宠瀹℃壒琛�",
+      6: "鎶ヤ环瀹℃壒琛�",
+      7: "鍙戣揣瀹℃壒琛�",
+    };
+    const fileName = nameMap[type] || nameMap[0];
+    proxy.download(url, {}, `${fileName}.xlsx`);
+  };
+
+  // 瀹℃壒浜虹淮鎶�
+  const handleOut = () => {
+    approverLoading.value = true;
+    // 浠� API 鑾峰彇鎵�鏈夌敤鎴峰垪琛�
+    userListNoPageByTenantId()
+      .then(res => {
+        // 杞崲 API 杩斿洖鐨勬暟鎹粨鏋勪负琛ㄦ牸闇�瑕佺殑鏍煎紡
+        approverList.value = res.data.map(user => ({
+          userId: user.userId,
+          userName: user.nickName,
+          createTime: user.createTime || "",
+        }));
+
+        // 鑾峰彇褰撳墠瀹℃壒绫诲瀷宸叉湁鐨勫鎵逛汉鍒楄〃
+        const currentType = currentApproveType.value;
+        approveUserList({ approveType: currentType })
+          .then(approversRes => {
+            existingApprovers.value = approversRes.data || [];
+            // approverList.value = approversRes.data;
+            selectedApprovers.value = existingApprovers.value;
+            // approverList.value = ;
+            // 鏍囪宸叉湁鐨勫鎵逛汉
+
+            // approverList.value = allUsers.map(user => ({
+            //   ...user,
+            //   id:
+            //     existingApprovers.value.find(
+            //       approver => approver.userId === user.userId
+            //     )?.id || 0,
+            //   isExisting: existingApprovers.value.some(
+            //     approver => approver.userId === user.userId
+            //   ),
+            // }));
+            console.log(approverList.value, "==approverList.value==");
+            approverDialogVisible.value = true;
+            approverLoading.value = false;
+
+            // 鏇存柊琛ㄦ牸鍕鹃�夌姸鎬�
+            nextTick(() => {
+              if (approverTable.value) {
+                // 鍏堟竻绌烘墍鏈夊嬀閫�
+                approverList.value.forEach(row => {
+                  approverTable.value.toggleRowSelection(row, false);
+                });
+                // 鍐嶅嬀閫夊凡鏈夌殑瀹℃壒浜�
+                existingApprovers.value.forEach(existingApprover => {
+                  const row = approverList.value.find(
+                    user => user.userId === existingApprover.userId
+                  );
+                  if (row) {
+                    approverTable.value.toggleRowSelection(row, true);
+                  }
+                });
+              }
+            });
+          })
+          .catch(err => {
+            console.error("鑾峰彇宸叉湁瀹℃壒浜哄垪琛ㄥけ璐�:", err);
+            proxy.$modal.msgError("鑾峰彇宸叉湁瀹℃壒浜哄垪琛ㄥけ璐�");
+            approverLoading.value = false;
+          });
+      })
+      .catch(err => {
+        console.error("鑾峰彇鐢ㄦ埛鍒楄〃澶辫触:", err);
+        proxy.$modal.msgError("鑾峰彇鐢ㄦ埛鍒楄〃澶辫触");
+        approverLoading.value = false;
+      });
+  };
+
+  // 澶勭悊瀹℃壒浜洪�夋嫨
+  const handleApproverSelectionChange = selection => {
+    selectedApprovers.value = selection;
+  };
+
+  // 绉婚櫎瀹℃壒浜�
+  const removeApprover = approver => {
+    selectedApprovers.value = selectedApprovers.value.filter(
+      item => item.id !== approver.id
+    );
+    approverTable.value.toggleRowSelection(approver, false);
+  };
+
+  // 鎻愪氦瀹℃壒浜�
+  const submitApprovers = () => {
+    if (selectedApprovers.value.length === 0) {
+      proxy.$modal.msgWarning("璇烽�夋嫨瀹℃壒浜�");
+      return;
+    }
+
+    const currentType = currentApproveType.value;
+    const selectedIds = selectedApprovers.value.map(approver => approver.userId);
+    const existingIds = existingApprovers.value.map(approver => approver.userId);
+    // 闇�瑕佸垹闄ょ殑瀹℃壒浜猴紙鍘熸湁鐨勪絾鏈閫夋嫨鐨勶級
+    const toDelete = existingApprovers.value
+      .filter(approver => !selectedIds.includes(approver.userId))
+      .map(approver => approver.id);
+
+    // 闇�瑕佹坊鍔犵殑瀹℃壒浜猴紙鏂伴�夋嫨鐨勪絾涓嶅湪鐜版湁鍒楄〃涓殑锛�
+    const toAdd = selectedApprovers.value
+      .filter(approver => !existingIds.includes(approver.userId))
+      .map(approver => ({
+        approveType: currentType,
+        id: 0,
+        userId: approver.userId,
+        userName: approver.userName,
+      }));
+    console.log(toDelete, "==鍒犻櫎==");
+    console.log(toAdd, "==娣诲姞==");
+
+    // 鍏堝垹闄や笉闇�瑕佺殑瀹℃壒浜�
+    const deletePromise =
+      toDelete.length > 0 ? deleteApproveUser(toDelete) : Promise.resolve();
+
+    deletePromise
       .then(() => {
-        approveProcessDelete(ids).then((res) => {
+        // 鐒跺悗娣诲姞鏂扮殑瀹℃壒浜�
+        if (toAdd.length === 0) {
+          return Promise.resolve();
+        }
+        // 閫愪釜娣诲姞瀹℃壒浜�
+        return Promise.all(toAdd.map(user => addApproveUser(user)));
+      })
+      .then(() => {
+        proxy.$modal.msgSuccess("瀹℃壒浜虹淮鎶ゆ垚鍔�");
+        approverDialogVisible.value = false;
+        selectedApprovers.value = [];
+      })
+      .catch(err => {
+        console.error("瀹℃壒浜虹淮鎶ゅけ璐�:", err);
+        proxy.$modal.msgError("瀹℃壒浜虹淮鎶ゅけ璐�");
+      });
+  };
+  // 琛ㄦ牸閫夋嫨鏁版嵁
+  const handleSelectionChange = selection => {
+    selectedRows.value = selection;
+  };
+
+  // 鎵撳紑鏂板銆佺紪杈戝脊妗�
+  const openForm = (type, row) => {
+    nextTick(() => {
+      infoFormDia.value?.openDialog(type, row);
+    });
+  };
+  // 鎵撳紑鏂板妫�楠屽脊妗�
+  const openApprovalDia = (type, row) => {
+    nextTick(() => {
+      approvalDia.value?.openDialog(type, row);
+    });
+  };
+
+  // 鍒犻櫎
+  const handleDelete = () => {
+    let ids = [];
+    if (selectedRows.value.length > 0) {
+      ids = selectedRows.value.map(item => item.approveId);
+    } else {
+      proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+      return;
+    }
+    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        approveProcessDelete(ids).then(res => {
           proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
           getList();
         });
@@ -286,10 +591,65 @@
       .catch(() => {
         proxy.$modal.msg("宸插彇娑�");
       });
-};
-onMounted(() => {
-  getList();
-});
+  };
+  onMounted(() => {
+    // 鏍规嵁URL鍙傛暟璁剧疆鏍囩椤靛拰鏌ヨ鏉′欢
+    const approveType = route.query.approveType;
+    const approveId = route.query.approveId;
+
+    if (approveType) {
+      // 璁剧疆鏍囩椤碉紙approveType 瀵瑰簲 activeTab 鐨� name锛�
+      activeTab.value = String(approveType);
+    }
+
+    if (approveId) {
+      // 璁剧疆娴佺▼缂栧彿鏌ヨ鏉′欢
+      searchForm.value.approveId = String(approveId);
+    }
+
+    // 鏌ヨ鍒楄〃
+    getList();
+  });
 </script>
 
-<style scoped></style>
+<style scoped>
+  .approval-tabs {
+    margin-bottom: 10px;
+  }
+
+  /* 瀹℃壒浜虹淮鎶ゅ璇濇鏍峰紡 */
+  .approver-dialog {
+    display: flex;
+    flex-direction: column;
+    gap: 20px;
+  }
+
+  .selected-info {
+    /* margin-top: 20px; */
+    padding: 15px;
+    background: #f5f7fa;
+    border-radius: 4px;
+  }
+
+  .info-title {
+    font-weight: 600;
+    margin-bottom: 10px;
+    color: #303133;
+  }
+
+  .selected-list {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 10px;
+  }
+
+  .approver-tag {
+    margin-right: 10px;
+  }
+
+  .dialog-footer {
+    width: 100%;
+    display: flex;
+    justify-content: flex-end;
+  }
+</style>

--
Gitblit v1.9.3