From 332cfbec0e7dddadc5c5f676d183d06210abc981 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期三, 27 五月 2026 16:46:19 +0800
Subject: [PATCH] 人员台账增加民族筛选、补贴配置页面、人员薪资修改工资表、增加厂家管理页面、库存管理增加来源字段和废品库

---
 src/views/inventoryManagement/manufacturer/index.vue                         |   50 
 src/views/inventoryManagement/stockManagement/New.vue                        |   53 
 src/views/inventoryManagement/manufacturer/components/HomeTab.vue            |  588 ++++++++
 src/views/personnelManagement/employeeRecord/index.vue                       |  689 +++++----
 src/views/inventoryManagement/manufacturer/filesDia.vue                      |  198 ++
 src/views/personnelManagement/employeeRecord/components/BasicInfoSection.vue |  237 +-
 src/views/personnelManagement/monthlyStatistics/components/formDia.vue       | 1430 ++++++++++---------
 src/views/personnelManagement/subsidyConfig/index.vue                        |  437 ++++++
 src/views/inventoryManagement/manufacturer/components/BlacklistTab.vue       |  583 ++++++++
 src/api/personnelManagement/subsidyConfig.js                                 |   19 
 10 files changed, 3,163 insertions(+), 1,121 deletions(-)

diff --git a/src/api/personnelManagement/subsidyConfig.js b/src/api/personnelManagement/subsidyConfig.js
new file mode 100644
index 0000000..f4f9f43
--- /dev/null
+++ b/src/api/personnelManagement/subsidyConfig.js
@@ -0,0 +1,19 @@
+import request from "@/utils/request";
+
+// 鏌ヨ琛ヨ创閰嶇疆鍒楄〃
+export function listSubsidyConfiguration(query) {
+  return request({
+    url: "/subsidyConfiguration/list",
+    method: "get",
+    params: query,
+  });
+}
+
+// 淇濆瓨琛ヨ创閰嶇疆
+export function saveSubsidyConfiguration(data) {
+  return request({
+    url: "/subsidyConfiguration/save",
+    method: "post",
+    data: data,
+  });
+}
diff --git a/src/views/inventoryManagement/manufacturer/components/BlacklistTab.vue b/src/views/inventoryManagement/manufacturer/components/BlacklistTab.vue
new file mode 100644
index 0000000..3c2e01d
--- /dev/null
+++ b/src/views/inventoryManagement/manufacturer/components/BlacklistTab.vue
@@ -0,0 +1,583 @@
+<template>
+  <div class="app-container">
+    <div class="search_form">
+      <div>
+        <span class="search_title">鍘傚妗f锛�</span>
+        <el-input v-model="searchForm.supplierName"
+                  style="width: 240px"
+                  placeholder="杈撳叆鍘傚鍚嶇О鎼滅储"
+                  @change="handleQuery"
+                  clearable
+                  :prefix-icon="Search" />
+        <el-button type="primary"
+                   @click="handleQuery"
+                   style="margin-left: 10px">鎼滅储</el-button>
+      </div>
+      <div>
+        <el-button @click="handleOut">瀵煎嚭</el-button>
+        <el-button type="danger"
+                   plain
+                   @click="handleDelete">鍒犻櫎</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"></PIMTable>
+    </div>
+    <el-dialog v-model="dialogFormVisible"
+               :title="operationType === 'add' ? '鏂板鍘傚淇℃伅' : '缂栬緫鍘傚淇℃伅'"
+               width="70%"
+               @close="closeDia">
+      <el-form :model="form"
+               label-width="140px"
+               label-position="top"
+               :rules="rules"
+               ref="formRef">
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鍘傚鍚嶇О锛�"
+                          prop="supplierName">
+              <el-input v-model="form.supplierName"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="绾崇◣浜鸿瘑鍒彿锛�"
+                          prop="taxpayerIdentificationNum">
+              <el-input v-model="form.taxpayerIdentificationNum"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鍏徃鍦板潃锛�"
+                          prop="companyAddress">
+              <el-input v-model="form.companyAddress"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍏徃鐢佃瘽锛�"
+                          prop="companyPhone">
+              <el-input v-model="form.companyPhone"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="寮�鎴疯锛�"
+                          prop="bankAccountName">
+              <el-input v-model="form.bankAccountName"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="璐﹀彿锛�"
+                          prop="bankAccountNum">
+              <el-input v-model="form.bankAccountNum"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鑱旂郴浜猴細"
+                          prop="contactUserName">
+              <el-input v-model="form.contactUserName"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鑱旂郴鐢佃瘽锛�"
+                          prop="contactUserPhone">
+              <el-input v-model="form.contactUserPhone"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="缁存姢浜猴細"
+                          prop="maintainUserId">
+              <el-select v-model="form.maintainUserId"
+                         placeholder="璇烽�夋嫨"
+                         clearable
+                         disabled>
+                <el-option v-for="item in userList"
+                           :key="item.nickName"
+                           :label="item.nickName"
+                           :value="item.userId" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="缁存姢鏃堕棿锛�"
+                          prop="maintainTime">
+              <el-date-picker style="width: 100%"
+                              v-model="form.maintainTime"
+                              value-format="YYYY-MM-DD"
+                              format="YYYY-MM-DD"
+                              type="date"
+                              placeholder="璇烽�夋嫨"
+                              clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鍘傚绫诲瀷锛�"
+                          prop="supplierType">
+              <el-select v-model="form.supplierType"
+                         placeholder="璇烽�夋嫨"
+                         clearable>
+                <el-option label="鐢�"
+                           value="鐢�" />
+                <el-option label="涔�"
+                           value="涔�" />
+                <el-option label="涓�"
+                           value="涓�" />
+                <el-option label="涓�"
+                           value="涓�" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鏄惁鐧藉悕鍗曪細"
+                          prop="isWhite">
+              <el-select v-model="form.isWhite"
+                         placeholder="璇烽�夋嫨"
+                         clearable>
+                <el-option label="鏄�"
+                           :value="0" />
+                <el-option label="鍚�"
+                           :value="1" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary"
+                     @click="submitForm">纭</el-button>
+          <el-button @click="closeDia">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <!-- 鍘傚瀵煎叆瀵硅瘽妗� -->
+    <el-dialog :title="upload.title"
+               v-model="upload.open"
+               width="400px"
+               append-to-body>
+      <el-upload ref="uploadRef"
+                 :limit="1"
+                 accept=".xlsx, .xls"
+                 :headers="upload.headers"
+                 :action="upload.url + '?updateSupport=' + upload.updateSupport"
+                 :disabled="upload.isUploading"
+                 :on-progress="handleFileUploadProgress"
+                 :on-success="handleFileSuccess"
+                 :on-error="handleFileError"
+                 :auto-upload="false"
+                 drag>
+        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
+        <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+        <template #tip>
+          <div class="el-upload__tip text-center">
+            <span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span>
+            <el-link type="primary"
+                     :underline="false"
+                     style="font-size: 12px; vertical-align: baseline"
+                     @click="importTemplate">涓嬭浇妯℃澘</el-link>
+          </div>
+        </template>
+      </el-upload>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary"
+                     @click="submitFileForm">纭� 瀹�</el-button>
+          <el-button @click="upload.open = false">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <FileList v-if="fileListDialogVisible"
+              v-model:visible="fileListDialogVisible"
+              record-type="supplier_manage"
+              :record-id="recordId" />
+  </div>
+</template>
+
+<script setup>
+  import { onMounted, ref } from "vue";
+  import { Search } from "@element-plus/icons-vue";
+  import { delSupplier } from "@/api/basicData/supplierManageFile.js";
+  import { ElMessageBox } from "element-plus";
+  import { userListNoPage } from "@/api/system/user.js";
+  import {
+    addSupplier,
+    getSupplier,
+    listSupplier,
+    updateSupplier,
+  } from "@/api/basicData/supplierManageFile.js";
+  import useUserStore from "@/store/modules/user";
+  import { getToken } from "@/utils/auth.js";
+  const FileList = defineAsyncComponent(() =>
+    import("@/components/Dialog/FileList.vue")
+  );
+  const { proxy } = getCurrentInstance();
+  const userStore = useUserStore();
+
+  const tableColumn = ref([
+    {
+      label: "鍘傚鍚嶇О",
+      prop: "supplierName",
+      width: 250,
+    },
+    {
+      label: "鍘傚绫诲瀷",
+      prop: "supplierType",
+      width: 120,
+    },
+    {
+      label: "绾崇◣浜鸿瘑鍒彿",
+      prop: "taxpayerIdentificationNum",
+      width: 230,
+    },
+    {
+      label: "鍏徃鍦板潃",
+      prop: "companyAddress",
+      width: 220,
+    },
+    {
+      label: "鑱旂郴鏂瑰紡",
+      prop: "companyPhone",
+      width: 150,
+    },
+    {
+      label: "寮�鎴疯",
+      prop: "bankAccountName",
+      width: 220,
+    },
+    {
+      label: "璐﹀彿",
+      prop: "bankAccountNum",
+      width: 220,
+    },
+    {
+      label: "鑱旂郴浜�",
+      prop: "contactUserName",
+    },
+    {
+      label: "鑱旂郴鐢佃瘽",
+      prop: "contactUserPhone",
+      width: 150,
+    },
+    {
+      label: "缁存姢浜�",
+      prop: "maintainUserName",
+    },
+
+    {
+      label: "缁存姢鏃堕棿",
+      prop: "maintainTime",
+      width: 100,
+    },
+    {
+      dataType: "action",
+      label: "鎿嶄綔",
+      align: "center",
+      fixed: "right",
+      width: 150,
+      operation: [
+        {
+          name: "缂栬緫",
+          type: "text",
+          clickFun: row => {
+            openForm("edit", row);
+          },
+        },
+        {
+          //璧勮川闄勪欢
+          name: "璧勮川鏂囦欢",
+          type: "text",
+          clickFun: row => {
+            openFileDialog(row);
+          },
+        },
+      ],
+    },
+  ]);
+  const tableData = ref([]);
+  const selectedRows = ref([]);
+  const userList = ref([]);
+  const tableLoading = ref(false);
+  const page = reactive({
+    current: 1,
+    size: 100,
+    total: 0,
+  });
+  const fileListDialogVisible = ref(false);
+  const recordId = ref();
+  // 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
+  const operationType = ref("");
+  const dialogFormVisible = ref(false);
+  const data = reactive({
+    searchForm: {
+      supplierName: "",
+    },
+    form: {
+      supplierName: "",
+      taxpayerIdentificationNum: "",
+      companyAddress: "",
+      companyPhone: "",
+      bankAccountName: "",
+      bankAccountNum: "",
+      contactUserName: "",
+      contactUserPhone: "",
+      maintainUserId: "",
+      maintainTime: "",
+      supplierType: "",
+      isWhite: "",
+    },
+    rules: {
+      supplierName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      taxpayerIdentificationNum: [
+        { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+      ],
+      companyAddress: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      companyPhone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      bankAccountName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      bankAccountNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      contactUserName: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
+      contactUserPhone: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
+      maintainUserId: [{ required: false, message: "璇烽�夋嫨", trigger: "change" }],
+      maintainTime: [{ required: false, message: "璇烽�夋嫨", trigger: "change" }],
+      supplierType: [
+        { required: true, message: "璇烽�夋嫨鍘傚绫诲瀷", trigger: "change" },
+      ],
+    },
+  });
+  const { searchForm, form, rules } = toRefs(data);
+
+  // 鏌ヨ鍒楄〃
+  /** 鎼滅储鎸夐挳鎿嶄綔 */
+  const handleQuery = () => {
+    page.current = 1;
+    getList();
+  };
+  const pagination = obj => {
+    page.current = obj.page;
+    page.size = obj.limit;
+    getList();
+  };
+  /** 鎻愪氦涓婁紶鏂囦欢 */
+  function submitFileForm() {
+    upload.isUploading = true;
+    proxy.$refs["uploadRef"].submit();
+  }
+  const getList = () => {
+    tableLoading.value = true;
+    listSupplier({ ...searchForm.value, ...page, isWhite: 1 }).then(res => {
+      tableLoading.value = false;
+      tableData.value = res.data.records;
+      page.total = res.data.total;
+    });
+  };
+  const upload = reactive({
+    // 鏄惁鏄剧ず寮瑰嚭灞傦紙鍘傚瀵煎叆锛�
+    open: false,
+    // 寮瑰嚭灞傛爣棰橈紙鍘傚瀵煎叆锛�
+    title: "",
+    // 鏄惁绂佺敤涓婁紶
+    isUploading: false,
+    // 鏄惁鏇存柊宸茬粡瀛樺湪鐨勭敤鎴锋暟鎹�
+    updateSupport: 1,
+    // 璁剧疆涓婁紶鐨勮姹傚ご閮�
+    headers: { Authorization: "Bearer " + getToken() },
+    // 涓婁紶鐨勫湴鍧�
+    url: import.meta.env.VITE_APP_BASE_API + "/system/supplier/import",
+  });
+  /** 瀵煎叆鎸夐挳鎿嶄綔 */
+  function handleImport() {
+    upload.title = "鍘傚瀵煎叆";
+    upload.open = true;
+  }
+  /** 涓嬭浇妯℃澘 */
+  function importTemplate() {
+    proxy.download("/system/supplier/downloadTemplate", {}, "鍘傚瀵煎叆妯℃澘.xlsx");
+  }
+
+  /**鏂囦欢涓婁紶涓鐞� */
+  const handleFileUploadProgress = (event, file, fileList) => {
+    upload.isUploading = true;
+  };
+
+  /** 鏂囦欢涓婁紶鎴愬姛澶勭悊 */
+  const handleFileSuccess = (response, file, fileList) => {
+    upload.isUploading = false;
+    if (response.code === 200) {
+      proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
+      upload.open = false;
+      proxy.$refs["uploadRef"].clearFiles();
+      getList();
+    } else if (response.code === 500) {
+      proxy.$modal.msgError(response.msg);
+    } else {
+      proxy.$modal.msgWarning(response.msg);
+    }
+  };
+
+  /** 鏂囦欢涓婁紶澶辫触澶勭悊 */
+  const handleFileError = (error, file, fileList) => {
+    upload.isUploading = false;
+    proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+  };
+  // 琛ㄦ牸閫夋嫨鏁版嵁
+  const handleSelectionChange = selection => {
+    selectedRows.value = selection;
+  };
+  // 鎵撳紑寮规
+  const openForm = (type, row) => {
+    operationType.value = type;
+    form.value = {};
+    form.value.maintainUserId = userStore.id;
+    form.value.maintainTime = getCurrentDate();
+    userListNoPage().then(res => {
+      userList.value = res.data;
+    });
+    if (type === "edit") {
+      getSupplier(row.id).then(res => {
+        form.value = { ...res.data };
+      });
+    }
+    dialogFormVisible.value = true;
+  };
+  // 鎻愪氦琛ㄥ崟
+  const submitForm = () => {
+    proxy.$refs["formRef"].validate(valid => {
+      if (valid) {
+        if (operationType.value === "edit") {
+          submitEdit();
+        } else {
+          submitAdd();
+        }
+      }
+    });
+  };
+  // 鎻愪氦鏂板
+  const submitAdd = () => {
+    addSupplier(form.value).then(res => {
+      proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+      closeDia();
+      getList();
+    });
+  };
+  // 鎻愪氦淇敼
+  const submitEdit = () => {
+    updateSupplier(form.value).then(res => {
+      proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+      closeDia();
+      getList();
+    });
+  };
+  // 鍏抽棴寮规
+  const closeDia = () => {
+    proxy.resetForm("formRef");
+    dialogFormVisible.value = false;
+  };
+  // 瀵煎嚭
+  const handleOut = () => {
+    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        proxy.download(
+          "/system/supplier/export",
+          { isWhite: 1 },
+          "鍘傚妗f.xlsx"
+        );
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+  };
+  // 鍒犻櫎
+  const handleDelete = () => {
+    let ids = [];
+    if (selectedRows.value.length > 0) {
+      // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
+      const unauthorizedData = selectedRows.value.filter(
+        item => item.maintainUserName !== userStore.nickName
+      );
+      if (unauthorizedData.length > 0) {
+        proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
+        return;
+      }
+      ids = selectedRows.value.map(item => item.id);
+    } else {
+      proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+      return;
+    }
+    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        tableLoading.value = true;
+        delSupplier(ids)
+          .then(res => {
+            proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+            getList();
+          })
+          .finally(() => {
+            tableLoading.value = false;
+          });
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+  };
+
+  // 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
+  function getCurrentDate() {
+    const today = new Date();
+    const year = today.getFullYear();
+    const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
+    const day = String(today.getDate()).padStart(2, "0");
+    return `${year}-${month}-${day}`;
+  }
+  // 鎵撳紑闄勪欢寮规
+  const openFileDialog = async row => {
+    recordId.value = row.id;
+    fileListDialogVisible.value = true;
+  };
+
+  onMounted(() => {
+    getList();
+  });
+
+  defineExpose({
+    getList,
+  });
+</script>
+
+
diff --git a/src/views/inventoryManagement/manufacturer/components/HomeTab.vue b/src/views/inventoryManagement/manufacturer/components/HomeTab.vue
new file mode 100644
index 0000000..08985ae
--- /dev/null
+++ b/src/views/inventoryManagement/manufacturer/components/HomeTab.vue
@@ -0,0 +1,588 @@
+<template>
+  <div>
+    <div class="search_form">
+      <div style="margin-bottom: 10px;">
+        <span class="search_title">鍘傚妗f锛�</span>
+        <el-input v-model="searchForm.supplierName"
+                  style="width: 240px"
+                  placeholder="杈撳叆鍘傚鍚嶇О鎼滅储"
+                  @change="handleQuery"
+                  clearable
+                  :prefix-icon="Search" />
+        <el-button type="primary"
+                   @click="handleQuery"
+                   style="margin-left: 10px">鎼滅储</el-button>
+      </div>
+      <div style="margin-bottom: 10px;">
+        <el-button type="primary"
+                   @click="openForm('add')">鏂板鍘傚</el-button>
+        <el-button @click="handleOut">瀵煎嚭</el-button>
+        <el-button type="info"
+                   plain
+                   icon="Upload"
+                   @click="handleImport">瀵煎叆</el-button>
+        <el-button type="danger"
+                   plain
+                   @click="handleDelete">鍒犻櫎</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"></PIMTable>
+    </div>
+    <el-dialog v-model="dialogFormVisible"
+               :title="operationType === 'add' ? '鏂板鍘傚淇℃伅' : '缂栬緫鍘傚淇℃伅'"
+               width="70%"
+               @close="closeDia">
+      <el-form :model="form"
+               label-width="140px"
+               label-position="top"
+               :rules="rules"
+               ref="formRef">
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鍘傚鍚嶇О锛�"
+                          prop="supplierName">
+              <el-input v-model="form.supplierName"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="绾崇◣浜鸿瘑鍒彿锛�"
+                          prop="taxpayerIdentificationNum">
+              <el-input v-model="form.taxpayerIdentificationNum"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鍏徃鍦板潃锛�"
+                          prop="companyAddress">
+              <el-input v-model="form.companyAddress"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍏徃鐢佃瘽锛�"
+                          prop="companyPhone">
+              <el-input v-model="form.companyPhone"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="寮�鎴疯锛�"
+                          prop="bankAccountName">
+              <el-input v-model="form.bankAccountName"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="璐﹀彿锛�"
+                          prop="bankAccountNum">
+              <el-input v-model="form.bankAccountNum"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鑱旂郴浜猴細"
+                          prop="contactUserName">
+              <el-input v-model="form.contactUserName"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鑱旂郴鐢佃瘽锛�"
+                          prop="contactUserPhone">
+              <el-input v-model="form.contactUserPhone"
+                        placeholder="璇疯緭鍏�"
+                        clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="缁存姢浜猴細"
+                          prop="maintainUserId">
+              <el-select v-model="form.maintainUserId"
+                         placeholder="璇烽�夋嫨"
+                         clearable
+                         disabled>
+                <el-option v-for="item in userList"
+                           :key="item.nickName"
+                           :label="item.nickName"
+                           :value="item.userId" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="缁存姢鏃堕棿锛�"
+                          prop="maintainTime">
+              <el-date-picker style="width: 100%"
+                              v-model="form.maintainTime"
+                              value-format="YYYY-MM-DD"
+                              format="YYYY-MM-DD"
+                              type="date"
+                              placeholder="璇烽�夋嫨"
+                              clearable />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鍘傚绫诲瀷锛�"
+                          prop="supplierType">
+              <el-select v-model="form.supplierType"
+                         placeholder="璇烽�夋嫨"
+                         clearable>
+                <el-option label="鐢�"
+                           value="鐢�" />
+                <el-option label="涔�"
+                           value="涔�" />
+                <el-option label="涓�"
+                           value="涓�" />
+                <el-option label="涓�"
+                           value="涓�" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鏄惁鐧藉悕鍗曪細"
+                          prop="isWhite">
+              <el-select v-model="form.isWhite"
+                         placeholder="璇烽�夋嫨"
+                         clearable>
+                <el-option label="鏄�"
+                           :value="0" />
+                <el-option label="鍚�"
+                           :value="1" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary"
+                     @click="submitForm">纭</el-button>
+          <el-button @click="closeDia">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <!-- 鍘傚瀵煎叆瀵硅瘽妗� -->
+    <el-dialog :title="upload.title"
+               v-model="upload.open"
+               width="400px"
+               append-to-body>
+      <el-upload ref="uploadRef"
+                 :limit="1"
+                 accept=".xlsx, .xls"
+                 :headers="upload.headers"
+                 :action="upload.url + '?updateSupport=' + upload.updateSupport"
+                 :disabled="upload.isUploading"
+                 :on-progress="handleFileUploadProgress"
+                 :on-success="handleFileSuccess"
+                 :on-error="handleFileError"
+                 :auto-upload="false"
+                 drag>
+        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
+        <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+        <template #tip>
+          <div class="el-upload__tip text-center">
+            <span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span>
+            <el-link type="primary"
+                     :underline="false"
+                     style="font-size: 12px; vertical-align: baseline"
+                     @click="importTemplate">涓嬭浇妯℃澘</el-link>
+          </div>
+        </template>
+      </el-upload>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary"
+                     @click="submitFileForm">纭� 瀹�</el-button>
+          <el-button @click="upload.open = false">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <FileList v-if="fileListDialogVisible"
+              v-model:visible="fileListDialogVisible"
+              record-type="supplier_manage"
+              :record-id="recordId" />
+  </div>
+</template>
+
+<script setup>
+  import { onMounted, ref } from "vue";
+  import { Search } from "@element-plus/icons-vue";
+  import { delSupplier } from "@/api/basicData/supplierManageFile.js";
+  import { ElMessageBox } from "element-plus";
+  import { userListNoPage } from "@/api/system/user.js";
+  import {
+    addSupplier,
+    getSupplier,
+    listSupplier,
+    updateSupplier,
+  } from "@/api/basicData/supplierManageFile.js";
+  import useUserStore from "@/store/modules/user";
+  import { getToken } from "@/utils/auth.js";
+  const FileList = defineAsyncComponent(() =>
+    import("@/components/Dialog/FileList.vue")
+  );
+  const { proxy } = getCurrentInstance();
+  const userStore = useUserStore();
+
+  const tableColumn = ref([
+    {
+      label: "鍘傚鍚嶇О",
+      prop: "supplierName",
+      width: 250,
+    },
+    {
+      label: "鍘傚绫诲瀷",
+      prop: "supplierType",
+      width: 120,
+    },
+    {
+      label: "绾崇◣浜鸿瘑鍒彿",
+      prop: "taxpayerIdentificationNum",
+      width: 230,
+    },
+    {
+      label: "鍏徃鍦板潃",
+      prop: "companyAddress",
+      width: 220,
+    },
+    {
+      label: "鑱旂郴鏂瑰紡",
+      prop: "companyPhone",
+      width: 150,
+    },
+    {
+      label: "寮�鎴疯",
+      prop: "bankAccountName",
+      width: 220,
+    },
+    {
+      label: "璐﹀彿",
+      prop: "bankAccountNum",
+      width: 220,
+    },
+    {
+      label: "鑱旂郴浜�",
+      prop: "contactUserName",
+    },
+    {
+      label: "鑱旂郴鐢佃瘽",
+      prop: "contactUserPhone",
+      width: 150,
+    },
+    {
+      label: "缁存姢浜�",
+      prop: "maintainUserName",
+    },
+
+    {
+      label: "缁存姢鏃堕棿",
+      prop: "maintainTime",
+      width: 100,
+    },
+    {
+      dataType: "action",
+      label: "鎿嶄綔",
+      align: "center",
+      fixed: "right",
+      width: 150,
+      operation: [
+        {
+          name: "缂栬緫",
+          type: "text",
+          clickFun: row => {
+            openForm("edit", row);
+          },
+        },
+        {
+          //璧勮川闄勪欢
+          name: "璧勮川鏂囦欢",
+          type: "text",
+          clickFun: row => {
+            openFileDialog(row);
+          },
+        },
+      ],
+    },
+  ]);
+  const tableData = ref([]);
+  const selectedRows = ref([]);
+  const userList = ref([]);
+  const tableLoading = ref(false);
+  const fileListDialogVisible = ref(false);
+  const recordId = ref();
+  const page = reactive({
+    current: 1,
+    size: 100,
+    total: 0,
+  });
+  // 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
+  const operationType = ref("");
+  const dialogFormVisible = ref(false);
+  const data = reactive({
+    searchForm: {
+      supplierName: "",
+    },
+    form: {
+      supplierName: "",
+      taxpayerIdentificationNum: "",
+      companyAddress: "",
+      companyPhone: "",
+      bankAccountName: "",
+      bankAccountNum: "",
+      contactUserName: "",
+      contactUserPhone: "",
+      maintainUserId: "",
+      maintainTime: "",
+      supplierType: "",
+      isWhite: "",
+    },
+    rules: {
+      supplierName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      taxpayerIdentificationNum: [
+        { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+      ],
+      companyAddress: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      companyPhone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      bankAccountName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      bankAccountNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+      contactUserName: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
+      contactUserPhone: [{ required: false, message: "璇疯緭鍏�", trigger: "blur" }],
+      maintainUserId: [{ required: false, message: "璇烽�夋嫨", trigger: "change" }],
+      maintainTime: [{ required: false, message: "璇烽�夋嫨", trigger: "change" }],
+      supplierType: [
+        { required: true, message: "璇烽�夋嫨鍘傚绫诲瀷", trigger: "change" },
+      ],
+    },
+  });
+  const { searchForm, form, rules } = toRefs(data);
+
+  // 鏌ヨ鍒楄〃
+  /** 鎼滅储鎸夐挳鎿嶄綔 */
+  const handleQuery = () => {
+    page.current = 1;
+    getList();
+  };
+  const pagination = obj => {
+    page.current = obj.page;
+    page.size = obj.limit;
+    getList();
+  };
+  /** 鎻愪氦涓婁紶鏂囦欢 */
+  function submitFileForm() {
+    upload.isUploading = true;
+    proxy.$refs["uploadRef"].submit();
+  }
+  const getList = () => {
+    tableLoading.value = true;
+    listSupplier({ ...searchForm.value, ...page, isWhite: 0 }).then(res => {
+      tableLoading.value = false;
+      tableData.value = res.data.records;
+      page.total = res.data.total;
+    });
+  };
+  const upload = reactive({
+    // 鏄惁鏄剧ず寮瑰嚭灞傦紙鍘傚瀵煎叆锛�
+    open: false,
+    // 寮瑰嚭灞傛爣棰橈紙鍘傚瀵煎叆锛�
+    title: "",
+    // 鏄惁绂佺敤涓婁紶
+    isUploading: false,
+    // 鏄惁鏇存柊宸茬粡瀛樺湪鐨勭敤鎴锋暟鎹�
+    updateSupport: 1,
+    // 璁剧疆涓婁紶鐨勮姹傚ご閮�
+    headers: { Authorization: "Bearer " + getToken() },
+    // 涓婁紶鐨勫湴鍧�
+    url: import.meta.env.VITE_APP_BASE_API + "/system/supplier/import",
+  });
+  /** 瀵煎叆鎸夐挳鎿嶄綔 */
+  function handleImport() {
+    upload.title = "鍘傚瀵煎叆";
+    upload.open = true;
+  }
+  /** 涓嬭浇妯℃澘 */
+  function importTemplate() {
+    proxy.download("/system/supplier/downloadTemplate", {}, "鍘傚瀵煎叆妯℃澘.xlsx");
+  }
+
+  /**鏂囦欢涓婁紶涓鐞� */
+  const handleFileUploadProgress = (event, file, fileList) => {
+    upload.isUploading = true;
+  };
+
+  /** 鏂囦欢涓婁紶鎴愬姛澶勭悊 */
+  const handleFileSuccess = (response, file, fileList) => {
+    upload.isUploading = false;
+    if (response.code === 200) {
+      proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
+      upload.open = false;
+      proxy.$refs["uploadRef"].clearFiles();
+      getList();
+    } else if (response.code === 500) {
+      proxy.$modal.msgError(response.msg);
+    } else {
+      proxy.$modal.msgWarning(response.msg);
+    }
+  };
+
+  /** 鏂囦欢涓婁紶澶辫触澶勭悊 */
+  const handleFileError = (error, file, fileList) => {
+    upload.isUploading = false;
+    proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+  };
+  // 琛ㄦ牸閫夋嫨鏁版嵁
+  const handleSelectionChange = selection => {
+    selectedRows.value = selection;
+  };
+  // 鎵撳紑寮规
+  const openForm = (type, row) => {
+    operationType.value = type;
+    form.value = {};
+    form.value.maintainUserId = userStore.id;
+    form.value.maintainTime = getCurrentDate();
+    userListNoPage().then(res => {
+      userList.value = res.data;
+    });
+    if (type === "edit") {
+      getSupplier(row.id).then(res => {
+        form.value = { ...res.data };
+      });
+    }
+    dialogFormVisible.value = true;
+  };
+  // 鎻愪氦琛ㄥ崟
+  const submitForm = () => {
+    proxy.$refs["formRef"].validate(valid => {
+      if (valid) {
+        if (operationType.value === "edit") {
+          submitEdit();
+        } else {
+          submitAdd();
+        }
+      }
+    });
+  };
+  // 鎻愪氦鏂板
+  const submitAdd = () => {
+    addSupplier(form.value).then(res => {
+      proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+      closeDia();
+      getList();
+    });
+  };
+  // 鎻愪氦淇敼
+  const submitEdit = () => {
+    updateSupplier(form.value).then(res => {
+      proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+      closeDia();
+      getList();
+    });
+  };
+  // 鍏抽棴寮规
+  const closeDia = () => {
+    proxy.resetForm("formRef");
+    dialogFormVisible.value = false;
+  };
+  // 瀵煎嚭
+  const handleOut = () => {
+    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        proxy.download(
+          "/system/supplier/export",
+          { isWhite: 0 },
+          "鍘傚妗f.xlsx"
+        );
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+  };
+  // 鍒犻櫎
+  const handleDelete = () => {
+    let ids = [];
+    if (selectedRows.value.length > 0) {
+      // 妫�鏌ユ槸鍚︽湁浠栦汉缁存姢鐨勬暟鎹�
+      const unauthorizedData = selectedRows.value.filter(
+        item => item.maintainUserName !== userStore.nickName
+      );
+      if (unauthorizedData.length > 0) {
+        proxy.$modal.msgWarning("涓嶅彲鍒犻櫎浠栦汉缁存姢鐨勬暟鎹�");
+        return;
+      }
+      ids = selectedRows.value.map(item => item.id);
+    } else {
+      proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+      return;
+    }
+    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        tableLoading.value = true;
+        delSupplier(ids)
+          .then(res => {
+            proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+            getList();
+          })
+          .finally(() => {
+            tableLoading.value = false;
+          });
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+  };
+
+  // 鑾峰彇褰撳墠鏃ユ湡骞舵牸寮忓寲涓� YYYY-MM-DD
+  function getCurrentDate() {
+    const today = new Date();
+    const year = today.getFullYear();
+    const month = String(today.getMonth() + 1).padStart(2, "0"); // 鏈堜唤浠�0寮�濮�
+    const day = String(today.getDate()).padStart(2, "0");
+    return `${year}-${month}-${day}`;
+  }
+  // 鎵撳紑闄勪欢寮规
+  const openFileDialog = async row => {
+    recordId.value = row.id;
+    fileListDialogVisible.value = true;
+  };
+
+  onMounted(() => {
+    getList();
+  });
+
+  defineExpose({
+    getList,
+  });
+</script>
+
diff --git a/src/views/inventoryManagement/manufacturer/filesDia.vue b/src/views/inventoryManagement/manufacturer/filesDia.vue
new file mode 100644
index 0000000..5b1a72e
--- /dev/null
+++ b/src/views/inventoryManagement/manufacturer/filesDia.vue
@@ -0,0 +1,198 @@
+<template>
+  <div>
+    <el-dialog v-model="dialogFormVisible"
+               title="涓婁紶闄勪欢"
+               width="50%"
+               @close="closeDia">
+      <div style="margin-bottom: 10px;text-align: right">
+        <el-upload v-model:file-list="fileList"
+                   class="upload-demo"
+                   :action="uploadUrl"
+                   :on-success="handleUploadSuccess"
+                   :on-error="handleUploadError"
+                   name="file"
+                   :show-file-list="false"
+                   :headers="headers"
+                   style="display: inline;margin-right: 10px">
+          <el-button type="primary">涓婁紶闄勪欢</el-button>
+        </el-upload>
+        <el-button type="danger"
+                   plain
+                   @click="handleDelete">鍒犻櫎</el-button>
+      </div>
+      <PIMTable rowKey="id"
+                :column="tableColumn"
+                :tableData="tableData"
+                :tableLoading="tableLoading"
+                :isSelection="true"
+                @selection-change="handleSelectionChange"
+                height="500"
+                @pagination-change="paginationSearch"
+                :total="total"
+                :page="page.current"
+                :limit="page.size">
+      </PIMTable>
+      <pagination style="margin: 10px 0"
+                  v-show="total > 0"
+                  @pagination="paginationSearch"
+                  :total="total"
+                  :page="page.current"
+                  :limit="page.size" />
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="closeDia">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <filePreview ref="filePreviewRef" />
+  </div>
+</template>
+
+<script setup>
+  import { ref } from "vue";
+  import { ElMessageBox } from "element-plus";
+  import { getToken } from "@/utils/auth.js";
+  import filePreview from "@/components/filePreview/index.vue";
+  import {
+    fileAdd,
+    fileDel,
+    fileListPage,
+  } from "@/api/basicData/supplierManageFile.js";
+  import Pagination from "@/components/PIMTable/Pagination.vue";
+  const { proxy } = getCurrentInstance();
+  const emit = defineEmits(["close"]);
+
+  const dialogFormVisible = ref(false);
+  const currentId = ref("");
+  const selectedRows = ref([]);
+  const filePreviewRef = ref();
+  const tableColumn = ref([
+    {
+      label: "鏂囦欢鍚嶇О",
+      prop: "name",
+    },
+    {
+      dataType: "action",
+      label: "鎿嶄綔",
+      align: "center",
+      operation: [
+        {
+          name: "涓嬭浇",
+          type: "text",
+          clickFun: row => {
+            downLoadFile(row);
+          },
+        },
+        {
+          name: "棰勮",
+          type: "text",
+          clickFun: row => {
+            lookFile(row);
+          },
+        },
+      ],
+    },
+  ]);
+  const page = reactive({
+    current: 1,
+    size: 100,
+  });
+  const total = ref(0);
+  const tableData = ref([]);
+  const fileList = ref([]);
+  const tableLoading = ref(false);
+  const headers = ref({
+    Authorization: "Bearer " + getToken(),
+  });
+  const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload"); // 涓婁紶鐨勫浘鐗囨湇鍔″櫒鍦板潃
+
+  // 鎵撳紑寮规
+  const openDialog = row => {
+    dialogFormVisible.value = true;
+    currentId.value = row.id;
+    getList();
+  };
+  const paginationSearch = obj => {
+    page.current = obj.page;
+    page.size = obj.limit;
+    getList();
+  };
+  const getList = () => {
+    fileListPage({ supplierId: currentId.value, ...page }).then(res => {
+      tableData.value = res.data.records;
+      total.value = res.data.total;
+    });
+  };
+  // 琛ㄦ牸閫夋嫨鏁版嵁
+  const handleSelectionChange = selection => {
+    selectedRows.value = selection;
+  };
+
+  // 鍏抽棴寮规
+  const closeDia = () => {
+    dialogFormVisible.value = false;
+    emit("close");
+  };
+  // 涓婁紶鎴愬姛澶勭悊
+  function handleUploadSuccess(res, file) {
+    // 濡傛灉涓婁紶鎴愬姛
+    if (res.code == 200) {
+      const fileRow = {};
+      fileRow.name = res.data.originalName;
+      fileRow.url = res.data.tempPath;
+      uploadFile(fileRow);
+    } else {
+      proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+    }
+  }
+  function uploadFile(file) {
+    file.supplierId = currentId.value;
+    fileAdd(file).then(res => {
+      proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
+      getList();
+    });
+  }
+  // 涓婁紶澶辫触澶勭悊
+  function handleUploadError() {
+    proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+  }
+  // 涓嬭浇闄勪欢
+  const downLoadFile = row => {
+    proxy.$download.byUrl(row.url, row.originalFilename);
+  };
+  // 鍒犻櫎
+  const handleDelete = () => {
+    let ids = [];
+    if (selectedRows.value.length > 0) {
+      ids = selectedRows.value.map(item => item.id);
+    } else {
+      proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+      return;
+    }
+    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
+      .then(() => {
+        fileDel(ids).then(res => {
+          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+          getList();
+        });
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+  };
+  // 棰勮闄勪欢
+  const lookFile = row => {
+    filePreviewRef.value.open(row.url);
+  };
+
+  defineExpose({
+    openDialog,
+  });
+</script>
+
+<style scoped>
+</style>
\ No newline at end of file
diff --git a/src/views/inventoryManagement/manufacturer/index.vue b/src/views/inventoryManagement/manufacturer/index.vue
new file mode 100644
index 0000000..cca52ff
--- /dev/null
+++ b/src/views/inventoryManagement/manufacturer/index.vue
@@ -0,0 +1,50 @@
+<!-- 鍦ㄤ綘鐨勪富椤甸潰涓� -->
+<template>
+  <div class="app-container">
+    <el-tabs v-model="activeTab"
+             @tab-change="handleTabChange">
+      <el-tab-pane label="姝e父鍘傚"
+                   name="home">
+        <HomeTab ref="homeTab" />
+      </el-tab-pane>
+      <el-tab-pane label="榛戝悕鍗�"
+                   name="blacklist">
+        <BlacklistTab ref="blacklistTab" />
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script>
+  import HomeTab from "./components/HomeTab.vue";
+  import BlacklistTab from "./components/BlacklistTab.vue";
+
+  export default {
+    name: "MainPage",
+    components: {
+      HomeTab,
+      BlacklistTab,
+    },
+    data() {
+      return {
+        activeTab: "home",
+      };
+    },
+    methods: {
+      handleTabChange(tabName) {
+        this.activeTab = tabName;
+        this.$nextTick(() => {
+          if (tabName === "home") {
+            this.$refs.homeTab &&
+              this.$refs.homeTab.getList &&
+              this.$refs.homeTab.getList();
+          } else if (tabName === "blacklist") {
+            this.$refs.blacklistTab &&
+              this.$refs.blacklistTab.getList &&
+              this.$refs.blacklistTab.getList();
+          }
+        });
+      },
+    },
+  };
+</script>
diff --git a/src/views/inventoryManagement/stockManagement/New.vue b/src/views/inventoryManagement/stockManagement/New.vue
index 2addb95..0b50731 100644
--- a/src/views/inventoryManagement/stockManagement/New.vue
+++ b/src/views/inventoryManagement/stockManagement/New.vue
@@ -32,6 +32,11 @@
           <el-input v-model="formState.unit"
                     disabled />
         </el-form-item>
+        <el-form-item label="鍘傚"
+                      prop="manufacturer">
+          <el-input v-model="formState.manufacturer"
+                    placeholder="璇疯緭鍏ュ巶瀹�" />
+        </el-form-item>
         <el-form-item label="搴撳瓨绫诲瀷"
                       prop="type"
                       :rules="[
@@ -42,11 +47,32 @@
               }
             ]">
           <el-select v-model="formState.type"
-                     placeholder="璇烽�夋嫨搴撳瓨绫诲瀷">
-            <el-option label="鍚堟牸搴撳瓨"
+                     placeholder="璇烽�夋嫨搴撳瓨绫诲瀷"
+                     @change="handleTypeChange">
+            <el-option label="鍚堟牸搴�"
                        value="qualified" />
-            <el-option label="涓嶅悎鏍煎簱瀛�"
+            <el-option label="搴熷搧搴�"
+                       value="waste" />
+            <el-option label="涓嶅悎鏍煎簱"
                        value="unqualified" />
+          </el-select>
+        </el-form-item>
+        <el-form-item v-if="formState.type && formState.type !== 'unqualified'"
+                      label="鏉ユ簮"
+                      prop="source"
+                      :rules="[
+                {
+                required: true,
+                message: '璇烽�夋嫨鏉ユ簮',
+                trigger: 'change',
+              }
+            ]">
+          <el-select v-model="formState.source"
+                     placeholder="璇烽�夋嫨鏉ユ簮">
+            <el-option v-for="item in sourceOptions"
+                       :key="item"
+                       :label="item"
+                       :value="item" />
           </el-select>
         </el-form-item>
         <el-form-item label="搴撳瓨鏁伴噺"
@@ -120,11 +146,30 @@
     productModelName: "",
     unit: "",
     type: undefined,
+    manufacturer: "",
+    source: "",
     qualitity: 0,
     batchNo: null,
     warnNum: 0,
     remark: "",
   });
+
+  const sourceOptions = computed(() => {
+    if (formState.value.type === "qualified") {
+      return ["閲囪喘鍏ュ簱", "鐢熶骇鍏ュ簱", "澶栧崗鍏ュ簱", "淇鍏ュ簱"];
+    } else if (formState.value.type === "waste") {
+      return ["鐢熶骇浜х敓", "杩愯緭浜х敓", "瑁佸壀浜х敓"];
+    }
+    return [];
+  });
+
+  const handleTypeChange = val => {
+    if (val === "unqualified") {
+      formState.value.source = "鑷畾涔�";
+    } else {
+      formState.value.source = "";
+    }
+  };
 
   const isShow = computed({
     get() {
@@ -158,6 +203,8 @@
       productModelName: "",
       unit: "",
       type: undefined,
+      manufacturer: "",
+      source: "",
       qualitity: 0,
       batchNo: null,
       warnNum: 0,
diff --git a/src/views/personnelManagement/employeeRecord/components/BasicInfoSection.vue b/src/views/personnelManagement/employeeRecord/components/BasicInfoSection.vue
index 0aa4f06..4a038ea 100644
--- a/src/views/personnelManagement/employeeRecord/components/BasicInfoSection.vue
+++ b/src/views/personnelManagement/employeeRecord/components/BasicInfoSection.vue
@@ -1,154 +1,149 @@
 <template>
-  <el-card class="form-card" shadow="never">
+  <el-card class="form-card"
+           shadow="never">
     <template #header>
       <span class="card-title">
         <span class="card-title-line">|</span>
         鍩烘湰淇℃伅
       </span>
     </template>
-
     <el-row :gutter="24">
       <el-col :span="5">
-        <el-form-item label="鍛樺伐缂栧彿" prop="staffNo">
-          <el-input
-            v-model="form.staffNo"
-            placeholder="璇疯緭鍏�"
-            clearable
-            maxlength="20"
-            show-word-limit
-            :disabled="operationType !== 'add'"
-          />
+        <el-form-item label="鍛樺伐缂栧彿"
+                      prop="staffNo">
+          <el-input v-model="form.staffNo"
+                    placeholder="璇疯緭鍏�"
+                    clearable
+                    maxlength="20"
+                    show-word-limit
+                    :disabled="operationType !== 'add'" />
         </el-form-item>
       </el-col>
       <el-col :span="5">
-        <el-form-item label="濮撳悕" prop="staffName">
-          <el-input
-            v-model="form.staffName"
-            placeholder="璇疯緭鍏�"
-            clearable
-            maxlength="50"
-            show-word-limit
-          />
+        <el-form-item label="濮撳悕"
+                      prop="staffName">
+          <el-input v-model="form.staffName"
+                    placeholder="璇疯緭鍏�"
+                    clearable
+                    maxlength="50"
+                    show-word-limit />
         </el-form-item>
       </el-col>
       <el-col :span="5">
-        <el-form-item label="鍒悕" prop="alias">
-          <el-input
-            v-model="form.alias"
-            placeholder="璇疯緭鍏�"
-            clearable
-            maxlength="50"
-            show-word-limit
-          />
+        <el-form-item label="鍒悕"
+                      prop="alias">
+          <el-input v-model="form.alias"
+                    placeholder="璇疯緭鍏�"
+                    clearable
+                    maxlength="50"
+                    show-word-limit />
         </el-form-item>
       </el-col>
       <el-col :span="5">
-        <el-form-item label="鎵嬫満" prop="phone">
-          <el-input
-            v-model="form.phone"
-            placeholder="璇疯緭鍏�"
-            clearable
-            maxlength="11"
-            show-word-limit
-          />
+        <el-form-item label="鎵嬫満"
+                      prop="phone">
+          <el-input v-model="form.phone"
+                    placeholder="璇疯緭鍏�"
+                    clearable
+                    maxlength="11"
+                    show-word-limit />
         </el-form-item>
       </el-col>
       <el-col :span="4">
-        <el-form-item label="鎬у埆" prop="sex">
-          <el-select
-            v-model="form.sex"
-            placeholder="璇烽�夋嫨"
-            clearable
-            style="width: 100%"
-          >
-            <el-option label="鐢�" value="鐢�" />
-            <el-option label="濂�" value="濂�" />
+        <el-form-item label="鎬у埆"
+                      prop="sex">
+          <el-select v-model="form.sex"
+                     placeholder="璇烽�夋嫨"
+                     clearable
+                     style="width: 100%">
+            <el-option label="鐢�"
+                       value="鐢�" />
+            <el-option label="濂�"
+                       value="濂�" />
           </el-select>
         </el-form-item>
       </el-col>
     </el-row>
-
     <el-row :gutter="24">
       <el-col :span="5">
-        <el-form-item label="鍑虹敓鏃ユ湡" prop="birthDate">
-          <el-date-picker
-            v-model="form.birthDate"
-            type="date"
-            value-format="YYYY-MM-DD"
-            format="YYYY-MM-DD"
-            placeholder="璇烽�夋嫨"
-            style="width: 100%"
-            clearable
-          />
+        <el-form-item label="鍑虹敓鏃ユ湡"
+                      prop="birthDate">
+          <el-date-picker v-model="form.birthDate"
+                          type="date"
+                          value-format="YYYY-MM-DD"
+                          format="YYYY-MM-DD"
+                          placeholder="璇烽�夋嫨"
+                          style="width: 100%"
+                          clearable />
         </el-form-item>
       </el-col>
       <el-col :span="5">
-        <el-form-item label="骞撮緞" prop="age">
-          <el-input-number
-            v-model="form.age"
-            :min="0"
-            :max="150"
-            :precision="0"
-            :step="1"
-            style="width: 100%"
-          />
+        <el-form-item label="骞撮緞"
+                      prop="age">
+          <el-input-number v-model="form.age"
+                           :min="0"
+                           :max="150"
+                           :precision="0"
+                           :step="1"
+                           style="width: 100%" />
         </el-form-item>
       </el-col>
       <el-col :span="5">
-        <el-form-item label="绫嶈疮" prop="nativePlace">
-          <el-input
-            v-model="form.nativePlace"
-            placeholder="璇疯緭鍏�"
-            clearable
-            maxlength="50"
-            show-word-limit
-          />
+        <el-form-item label="绫嶈疮"
+                      prop="nativePlace">
+          <el-input v-model="form.nativePlace"
+                    placeholder="璇疯緭鍏�"
+                    clearable
+                    maxlength="50"
+                    show-word-limit />
         </el-form-item>
       </el-col>
       <el-col :span="5">
-        <el-form-item label="姘戞棌" prop="nation">
-          <el-input
-            v-model="form.nation"
-            placeholder="璇疯緭鍏�"
-            clearable
-            maxlength="20"
-            show-word-limit
-          />
+        <el-form-item label="姘戞棌"
+                      prop="nation">
+          <el-select v-model="form.nation"
+                     placeholder="璇烽�夋嫨"
+                     clearable
+                     style="width: 100%">
+            <el-option v-for="dict in nation_type"
+                       :key="dict.label"
+                       :label="dict.label"
+                       :value="dict.label" />
+          </el-select>
         </el-form-item>
       </el-col>
       <el-col :span="4">
-        <el-form-item label="濠氬Щ鐘跺喌" prop="maritalStatus">
-          <el-select
-            v-model="form.maritalStatus"
-            placeholder="璇烽�夋嫨"
-            clearable
-            style="width: 100%"
-          >
-            <el-option label="鏈" value="鏈" />
-            <el-option label="宸插" value="宸插" />
-            <el-option label="绂诲紓" value="绂诲紓" />
-            <el-option label="涓у伓" value="涓у伓" />
+        <el-form-item label="濠氬Щ鐘跺喌"
+                      prop="maritalStatus">
+          <el-select v-model="form.maritalStatus"
+                     placeholder="璇烽�夋嫨"
+                     clearable
+                     style="width: 100%">
+            <el-option label="鏈"
+                       value="鏈" />
+            <el-option label="宸插"
+                       value="宸插" />
+            <el-option label="绂诲紓"
+                       value="绂诲紓" />
+            <el-option label="涓у伓"
+                       value="涓у伓" />
           </el-select>
         </el-form-item>
       </el-col>
     </el-row>
-
     <el-row :gutter="24">
       <el-col :span="10">
-        <el-form-item label="瑙掕壊" prop="roleId">
-          <el-select
-            v-model="form.roleId"
-            placeholder="璇烽�夋嫨"
-            clearable
-            style="width: 100%"
-          >
-            <el-option
-              v-for="item in roleOptions"
-              :key="item.roleId"
-              :label="item.roleName"
-              :value="item.roleId"
-              :disabled="item.status == 1"
-            />
+        <el-form-item label="瑙掕壊"
+                      prop="roleId">
+          <el-select v-model="form.roleId"
+                     placeholder="璇烽�夋嫨"
+                     clearable
+                     style="width: 100%">
+            <el-option v-for="item in roleOptions"
+                       :key="item.roleId"
+                       :label="item.roleName"
+                       :value="item.roleId"
+                       :disabled="item.status == 1" />
           </el-select>
         </el-form-item>
       </el-col>
@@ -157,25 +152,27 @@
 </template>
 
 <script setup>
-import { toRefs } from "vue";
+  import { toRefs, getCurrentInstance } from "vue";
 
-const props = defineProps({
-  form: { type: Object, required: true },
-  operationType: { type: String, default: "add" },
-  roleOptions: { type: Array, default: () => [] },
-});
+  const props = defineProps({
+    form: { type: Object, required: true },
+    operationType: { type: String, default: "add" },
+    roleOptions: { type: Array, default: () => [] },
+  });
 
-const { form, operationType, roleOptions } = toRefs(props);
+  const { proxy } = getCurrentInstance();
+  const { nation_type } = proxy.useDict("nation_type");
+  const { form, operationType, roleOptions } = toRefs(props);
 </script>
 
 <style scoped>
-.form-card {
-  margin-bottom: 16px;
-}
+  .form-card {
+    margin-bottom: 16px;
+  }
 
-.card-title-line {
-  color: #f56c6c;
-  margin-right: 4px;
-}
+  .card-title-line {
+    color: #f56c6c;
+    margin-right: 4px;
+  }
 </style>
 
diff --git a/src/views/personnelManagement/employeeRecord/index.vue b/src/views/personnelManagement/employeeRecord/index.vue
index a0699b0..82af109 100644
--- a/src/views/personnelManagement/employeeRecord/index.vue
+++ b/src/views/personnelManagement/employeeRecord/index.vue
@@ -3,90 +3,101 @@
     <div class="search_form mb20">
       <div>
         <span class="search_title">濮撳悕锛�</span>
-        <el-input
-            v-model="searchForm.staffName"
-            style="width: 240px"
-            placeholder="璇疯緭鍏ュ鍚嶆悳绱�"
-            @change="handleQuery"
-            clearable
-            :prefix-icon="Search"
-        />
+        <el-input v-model="searchForm.staffName"
+                  style="width: 240px"
+                  placeholder="璇疯緭鍏ュ鍚嶆悳绱�"
+                  @change="handleQuery"
+                  clearable
+                  :prefix-icon="Search" />
         <span class="search_title search_title2">閮ㄩ棬锛�</span>
-          <el-tree-select
-            v-model="searchForm.sysDeptId"
-            :data="deptOptions"
-            check-strictly
-            :render-after-expand="false"
-            style="width: 240px"
-            placeholder="璇烽�夋嫨"
-          />
-          <span class="search_title search_title2">鍏ヨ亴鏃ユ湡锛�</span>
-          <el-date-picker
-            v-model="searchForm.contractStartTime"
-            value-format="YYYY-MM-DD"
-            format="YYYY-MM-DD"
-            placeholder="璇烽�夋嫨"
-          />
+        <el-tree-select v-model="searchForm.sysDeptId"
+                        :data="deptOptions"
+                        check-strictly
+                        :render-after-expand="false"
+                        style="width: 240px"
+                        placeholder="璇烽�夋嫨" />
+        <span class="search_title search_title2">鍏ヨ亴鏃ユ湡锛�</span>
+        <el-date-picker v-model="searchForm.contractStartTime"
+                        value-format="YYYY-MM-DD"
+                        format="YYYY-MM-DD"
+                        placeholder="璇烽�夋嫨" />
+        <span class="search_title search_title2">姘戞棌锛�</span>
+        <el-select v-model="searchForm.nation"
+                   placeholder="璇烽�夋嫨姘戞棌"
+                   clearable
+                   style="width: 240px"
+                   @change="handleQuery">
+          <el-option v-for="dict in nation_type"
+                     :key="dict.label"
+                     :label="dict.label"
+                     :value="dict.label" />
+        </el-select>
         <!-- <span  style="margin-left: 10px" class="search_title">鍚堝悓缁撴潫鏃ユ湡锛�</span> -->
         <!-- <el-date-picker  v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
                          placeholder="璇烽�夋嫨" clearable @change="changeDaterange" /> -->
-        <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
-        >鎼滅储</el-button
-        >
+        <el-button type="primary"
+                   @click="handleQuery"
+                   style="margin-left: 10px">鎼滅储</el-button>
       </div>
       <div>
-        <el-button type="primary" @click="openFormNewOrEditFormDia('add')">鏂板鍏ヨ亴</el-button>
-        <el-button type="info" @click="handleImport">瀵煎叆</el-button>
+        <el-button type="primary"
+                   @click="openFormNewOrEditFormDia('add')">鏂板鍏ヨ亴</el-button>
+        <el-button type="info"
+                   @click="handleImport">瀵煎叆</el-button>
         <el-button @click="handleOut">瀵煎嚭</el-button>
         <!-- <el-button type="danger" plain @click="handleDelete">鍒犻櫎</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 rowKey="id"
+                :column="tableColumn"
+                :tableData="tableData"
+                :page="page"
+                :isSelection="true"
+                @selection-change="handleSelectionChange"
+                :tableLoading="tableLoading"
+                @pagination="pagination"
+                :total="page.total">
         <template #positiveDate="{ row }">
           <span :class="getPositiveDateClass(row.positiveDate)">{{ row.positiveDate }}</span>
         </template>
       </PIMTable>
     </div>
-    <show-form-dia ref="formDia" @close="handleQuery"></show-form-dia>
-    <new-or-edit-form-dia ref="formDiaNewOrEditFormDia" @close="handleQuery"></new-or-edit-form-dia>
-    
+    <show-form-dia ref="formDia"
+                   @close="handleQuery"></show-form-dia>
+    <new-or-edit-form-dia ref="formDiaNewOrEditFormDia"
+                          @close="handleQuery"></new-or-edit-form-dia>
     <!-- 瀵煎叆瀵硅瘽妗� -->
-    <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
-      <el-upload
-        ref="uploadRef"
-        :limit="1"
-        accept=".xlsx, .xls"
-        :headers="upload.headers"
-        :action="upload.url"
-        :disabled="upload.isUploading"
-        :on-progress="handleFileUploadProgress"
-        :on-success="handleFileSuccess"
-        :auto-upload="false"
-        drag
-      >
+    <el-dialog :title="upload.title"
+               v-model="upload.open"
+               width="400px"
+               append-to-body>
+      <el-upload ref="uploadRef"
+                 :limit="1"
+                 accept=".xlsx, .xls"
+                 :headers="upload.headers"
+                 :action="upload.url"
+                 :disabled="upload.isUploading"
+                 :on-progress="handleFileUploadProgress"
+                 :on-success="handleFileSuccess"
+                 :auto-upload="false"
+                 drag>
         <el-icon class="el-icon--upload"><upload-filled /></el-icon>
         <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
         <template #tip>
           <div class="el-upload__tip text-center">
             <span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span>
-            <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline; margin-left: 5px;" @click="importTemplate">涓嬭浇妯℃澘</el-link>
+            <el-link type="primary"
+                     :underline="false"
+                     style="font-size: 12px; vertical-align: baseline; margin-left: 5px;"
+                     @click="importTemplate">涓嬭浇妯℃澘</el-link>
           </div>
         </template>
       </el-upload>
       <template #footer>
         <div class="dialog-footer">
-          <el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
+          <el-button type="primary"
+                     @click="submitFileForm">纭� 瀹�</el-button>
           <el-button @click="upload.open = false">鍙� 娑�</el-button>
         </div>
       </template>
@@ -95,176 +106,192 @@
 </template>
 
 <script setup>
-import { Search, UploadFilled } from "@element-plus/icons-vue";
-import {onMounted, ref} from "vue";
-import {ElMessageBox} from "element-plus";
-import { deptTreeSelect } from "@/api/system/user.js";
-import {batchDeleteStaffOnJobs, staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
-import { getToken } from "@/utils/auth";
-import dayjs from "dayjs";
+  import { Search, UploadFilled } from "@element-plus/icons-vue";
+  import { onMounted, ref } from "vue";
+  import { ElMessageBox } from "element-plus";
+  import { deptTreeSelect } from "@/api/system/user.js";
+  import {
+    batchDeleteStaffOnJobs,
+    staffOnJobListPage,
+  } from "@/api/personnelManagement/staffOnJob.js";
+  import { getToken } from "@/utils/auth";
+  import dayjs from "dayjs";
 
-const NewOrEditFormDia = defineAsyncComponent(() => import("@/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue"));
-const ShowFormDia = defineAsyncComponent(() => import( "@/views/personnelManagement/employeeRecord/components/Show.vue"));
+  const NewOrEditFormDia = defineAsyncComponent(() =>
+    import(
+      "@/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue"
+    )
+  );
+  const ShowFormDia = defineAsyncComponent(() =>
+    import("@/views/personnelManagement/employeeRecord/components/Show.vue")
+  );
 
-const data = reactive({
-  searchForm: {
-    staffName: "",
-    entryDate: undefined, // 褰曞叆鏃ユ湡
-    entryDateStart: undefined,
-    entryDateEnd: undefined,
-  },
-  deptOptions: [],
-});
-const { searchForm, deptOptions } = toRefs(data);
-const tableColumn = ref([
-  {
-    label: "鐘舵��",
-    prop: "staffState",
-    dataType: "tag",
-    formatData: (params) => {
-      if (params == 0) {
-        return "绂昏亴";
-      } else if (params == 1) {
-        return "鍦ㄨ亴";
-      } else {
-        return null;
-      }
+  const data = reactive({
+    searchForm: {
+      staffName: "",
+      sysDeptId: undefined,
+      contractStartTime: undefined,
+      nation: undefined,
+      entryDate: undefined, // 褰曞叆鏃ユ湡
+      entryDateStart: undefined,
+      entryDateEnd: undefined,
     },
-    formatType: (params) => {
-      if (params == 0) {
-        return "danger";
-      } else if (params == 1) {
-        return "primary";
-      } else {
-        return null;
-      }
-    },
-  },
-  {
-    label: "鍛樺伐缂栧彿",
-    prop: "staffNo",
-  },
-  {
-    label: "濮撳悕",
-    prop: "staffName",
-  },
-  {
-    label: "鍒悕",
-    prop: "alias",
-  },
-  {
-    label: "鎵嬫満",
-    prop: "phone",
-    width: 150,
-  },
-  {
-    label: "鎬у埆",
-    prop: "sex",
-  },
-  {
-    label: "鍑虹敓鏃ユ湡",
-    prop: "birthDate",
-    width: 120,
-  },
-  {
-    label: "鍏ヨ亴鏃ユ湡",
-    prop: "contractStartTime",
-    width: 120,
-  },
-  {
-    label: "杞鏃ユ湡",
-    prop: "positiveDate",
-    width: 120,
-    dataType: "slot",
-    slot: "positiveDate",
-  },
-  {
-    label: "骞撮緞",
-    prop: "age",
-  },
-  {
-    label: "绫嶈疮",
-    prop: "nativePlace",
-  },
-  {
-    label: "姘戞棌",
-    prop: "nation",
-    width: 100,
-  },
-  {
-    label: "濠氬Щ鐘跺喌",
-    prop: "maritalStatus",
-    width: 100,
-  },
-  {
-    dataType: "action",
-    label: "鎿嶄綔",
-    align: "center",
-    fixed: 'right',
-    width: 180,
-    operation: [
-      {
-        name: "缂栬緫",
-        type: "text",
-        clickFun: (row) => {
-          openFormNewOrEditFormDia("edit", row);
-        },
+    deptOptions: [],
+  });
+  const { searchForm, deptOptions } = toRefs(data);
+  const tableColumn = ref([
+    {
+      label: "鐘舵��",
+      prop: "staffState",
+      dataType: "tag",
+      formatData: params => {
+        if (params == 0) {
+          return "绂昏亴";
+        } else if (params == 1) {
+          return "鍦ㄨ亴";
+        } else {
+          return null;
+        }
       },
-    ],
-  },
-]);
-const tableData = ref([]);
-const selectedRows = ref([]);
-const tableLoading = ref(false);
-const page = reactive({
-  current: 1,
-  size: 100,
-  total: 0
-});
-const formDia = ref()
-const formDiaNewOrEditFormDia = ref()
-const { proxy } = getCurrentInstance()
+      formatType: params => {
+        if (params == 0) {
+          return "danger";
+        } else if (params == 1) {
+          return "primary";
+        } else {
+          return null;
+        }
+      },
+    },
+    {
+      label: "鍛樺伐缂栧彿",
+      prop: "staffNo",
+    },
+    {
+      label: "濮撳悕",
+      prop: "staffName",
+    },
+    {
+      label: "鍒悕",
+      prop: "alias",
+    },
+    {
+      label: "鎵嬫満",
+      prop: "phone",
+      width: 150,
+    },
+    {
+      label: "鎬у埆",
+      prop: "sex",
+    },
+    {
+      label: "鍑虹敓鏃ユ湡",
+      prop: "birthDate",
+      width: 120,
+    },
+    {
+      label: "鍏ヨ亴鏃ユ湡",
+      prop: "contractStartTime",
+      width: 120,
+    },
+    {
+      label: "杞鏃ユ湡",
+      prop: "positiveDate",
+      width: 120,
+      dataType: "slot",
+      slot: "positiveDate",
+    },
+    {
+      label: "骞撮緞",
+      prop: "age",
+    },
+    {
+      label: "绫嶈疮",
+      prop: "nativePlace",
+    },
+    {
+      label: "姘戞棌",
+      prop: "nation",
+      width: 100,
+      formatData: params => {
+        return proxy.selectDictLabel(nation_type.value, params);
+      },
+    },
+    {
+      label: "濠氬Щ鐘跺喌",
+      prop: "maritalStatus",
+      width: 100,
+    },
+    {
+      dataType: "action",
+      label: "鎿嶄綔",
+      align: "center",
+      fixed: "right",
+      width: 180,
+      operation: [
+        {
+          name: "缂栬緫",
+          type: "text",
+          clickFun: row => {
+            openFormNewOrEditFormDia("edit", row);
+          },
+        },
+      ],
+    },
+  ]);
+  const tableData = ref([]);
+  const selectedRows = ref([]);
+  const tableLoading = ref(false);
+  const page = reactive({
+    current: 1,
+    size: 100,
+    total: 0,
+  });
+  const formDia = ref();
+  const formDiaNewOrEditFormDia = ref();
+  const { proxy } = getCurrentInstance();
+  const { nation_type } = proxy.useDict("nation_type");
 
-// 瀵煎叆鐩稿叧
-const uploadRef = ref(null)
-const upload = reactive({
-  // 鏄惁鏄剧ず寮瑰嚭灞�
-  open: false,
-  // 寮瑰嚭灞傛爣棰�
-  title: "",
-  // 鏄惁绂佺敤涓婁紶
-  isUploading: false,
-  // 璁剧疆涓婁紶鐨勮姹傚ご閮�
-  headers: { Authorization: "Bearer " + getToken() },
-  // 涓婁紶鐨勫湴鍧�
-  url: import.meta.env.VITE_APP_BASE_API + "/staff/staffOnJob/import"
-})
+  // 瀵煎叆鐩稿叧
+  const uploadRef = ref(null);
+  const upload = reactive({
+    // 鏄惁鏄剧ず寮瑰嚭灞�
+    open: false,
+    // 寮瑰嚭灞傛爣棰�
+    title: "",
+    // 鏄惁绂佺敤涓婁紶
+    isUploading: false,
+    // 璁剧疆涓婁紶鐨勮姹傚ご閮�
+    headers: { Authorization: "Bearer " + getToken() },
+    // 涓婁紶鐨勫湴鍧�
+    url: import.meta.env.VITE_APP_BASE_API + "/staff/staffOnJob/import",
+  });
 
-// 鍒ゆ柇杞鏃ユ湡鏄惁鍦�7澶╁唴
-const getPositiveDateClass = (positiveDate) => {
-  if (!positiveDate) return '';
-  const today = new Date();
-  today.setHours(0, 0, 0, 0);
-  const positive = new Date(positiveDate);
-  positive.setHours(0, 0, 0, 0);
-  const diffTime = positive - today;
-  const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
-  // 7澶╁唴杞锛堝寘鎷粖澶╋級鏄剧ず璀﹀憡鑹�
-  if (diffDays >= 0 && diffDays <= 7) {
-    return 'positive-date-warning';
-  }
-  return '';
-};
+  // 鍒ゆ柇杞鏃ユ湡鏄惁鍦�7澶╁唴
+  const getPositiveDateClass = positiveDate => {
+    if (!positiveDate) return "";
+    const today = new Date();
+    today.setHours(0, 0, 0, 0);
+    const positive = new Date(positiveDate);
+    positive.setHours(0, 0, 0, 0);
+    const diffTime = positive - today;
+    const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
+    // 7澶╁唴杞锛堝寘鎷粖澶╋級鏄剧ず璀﹀憡鑹�
+    if (diffDays >= 0 && diffDays <= 7) {
+      return "positive-date-warning";
+    }
+    return "";
+  };
 
-const fetchDeptOptions = () => {
+  const fetchDeptOptions = () => {
     deptTreeSelect().then(response => {
-      console.log(response.data)
+      console.log(response.data);
       deptOptions.value = filterDisabledDept(
         JSON.parse(JSON.stringify(response.data))
       );
     });
   };
-const filterDisabledDept = deptList => {
+  const filterDisabledDept = deptList => {
     return deptList.filter(dept => {
       if (dept.disabled) {
         return false;
@@ -275,72 +302,74 @@
       return true;
     });
   };
-const changeDaterange = (value) => {
-  searchForm.value.entryDateStart = undefined;
-  searchForm.value.entryDateEnd = undefined;
-  if (value) {
-    searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
-    searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
-  }
-  getList();
-};
-// 鏌ヨ鍒楄〃
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-const handleQuery = () => {
-  page.current = 1;
-  getList();
-};
-const pagination = (obj) => {
-  page.current = obj.page;
-  page.size = obj.limit;
-  getList();
-};
-const getList = () => {
-  fetchDeptOptions();
-  tableLoading.value = true;
-  const params = { ...searchForm.value, ...page };
-  params.entryDate = undefined
-  staffOnJobListPage({...params}).then(res => {
-    tableLoading.value = false;
-    tableData.value = res.data.records
-    page.total = res.data.total;
-  }).catch(err => {
-    tableLoading.value = false;
-  })
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
-  selectedRows.value = selection;
-};
+  const changeDaterange = value => {
+    searchForm.value.entryDateStart = undefined;
+    searchForm.value.entryDateEnd = undefined;
+    if (value) {
+      searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
+      searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
+    }
+    getList();
+  };
+  // 鏌ヨ鍒楄〃
+  /** 鎼滅储鎸夐挳鎿嶄綔 */
+  const handleQuery = () => {
+    page.current = 1;
+    getList();
+  };
+  const pagination = obj => {
+    page.current = obj.page;
+    page.size = obj.limit;
+    getList();
+  };
+  const getList = () => {
+    fetchDeptOptions();
+    tableLoading.value = true;
+    const params = { ...searchForm.value, ...page };
+    params.entryDate = undefined;
+    staffOnJobListPage({ ...params })
+      .then(res => {
+        tableLoading.value = false;
+        tableData.value = res.data.records;
+        page.total = res.data.total;
+      })
+      .catch(err => {
+        tableLoading.value = false;
+      });
+  };
+  // 琛ㄦ牸閫夋嫨鏁版嵁
+  const handleSelectionChange = selection => {
+    selectedRows.value = selection;
+  };
 
-// 鎵撳紑寮规
-const openForm = (type, row) => {
-  nextTick(() => {
-    formDia.value?.openDialog(type, row)
-  })
-};
-const openFormNewOrEditFormDia = (type, row) => {
-  nextTick(() => {
-    formDiaNewOrEditFormDia.value?.openDialog(type, row)
-  })
-};
+  // 鎵撳紑寮规
+  const openForm = (type, row) => {
+    nextTick(() => {
+      formDia.value?.openDialog(type, row);
+    });
+  };
+  const openFormNewOrEditFormDia = (type, row) => {
+    nextTick(() => {
+      formDiaNewOrEditFormDia.value?.openDialog(type, row);
+    });
+  };
 
-// 鍒犻櫎
-const handleDelete = () => {
-  let ids = [];
-  if (selectedRows.value.length > 0) {
-    ids = selectedRows.value.map((item) => item.id);
-  } else {
-    proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
-    return;
-  }
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
+  // 鍒犻櫎
+  const handleDelete = () => {
+    let ids = [];
+    if (selectedRows.value.length > 0) {
+      ids = selectedRows.value.map(item => item.id);
+    } else {
+      proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+      return;
+    }
+    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
       .then(() => {
-        batchDeleteStaffOnJobs(ids).then((res) => {
+        batchDeleteStaffOnJobs(ids).then(res => {
           proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
           getList();
         });
@@ -348,69 +377,77 @@
       .catch(() => {
         proxy.$modal.msg("宸插彇娑�");
       });
-};
+  };
 
-// 瀵煎嚭
-const handleOut = () => {
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-    confirmButtonText: "纭",
-    cancelButtonText: "鍙栨秷",
-    type: "warning",
-  })
+  // 瀵煎嚭
+  const handleOut = () => {
+    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+      confirmButtonText: "纭",
+      cancelButtonText: "鍙栨秷",
+      type: "warning",
+    })
       .then(() => {
-        proxy.download("/staff/staffOnJob/export", {staffState: 1}, "鍛樺伐鍙拌处.xlsx");
+        proxy.download(
+          "/staff/staffOnJob/export",
+          { staffState: 1 },
+          "鍛樺伐鍙拌处.xlsx"
+        );
       })
       .catch(() => {
         proxy.$modal.msg("宸插彇娑�");
       });
-};
+  };
 
-// 瀵煎叆鎸夐挳鎿嶄綔
-const handleImport = () => {
-  upload.title = "鍛樺伐瀵煎叆"
-  upload.open = true
-}
+  // 瀵煎叆鎸夐挳鎿嶄綔
+  const handleImport = () => {
+    upload.title = "鍛樺伐瀵煎叆";
+    upload.open = true;
+  };
 
-// 涓嬭浇妯℃澘鎿嶄綔
-const importTemplate = () => {
-  proxy.download("/staff/staffOnJob/downloadTemplate", {}, `鍛樺伐瀵煎叆妯℃澘_${new Date().getTime()}.xlsx`)
-}
+  // 涓嬭浇妯℃澘鎿嶄綔
+  const importTemplate = () => {
+    proxy.download(
+      "/staff/staffOnJob/downloadTemplate",
+      {},
+      `鍛樺伐瀵煎叆妯℃澘_${new Date().getTime()}.xlsx`
+    );
+  };
 
-// 鏂囦欢涓婁紶涓鐞�
-const handleFileUploadProgress = (event, file, fileList) => {
-  upload.isUploading = true
-}
+  // 鏂囦欢涓婁紶涓鐞�
+  const handleFileUploadProgress = (event, file, fileList) => {
+    upload.isUploading = true;
+  };
 
-// 鏂囦欢涓婁紶鎴愬姛澶勭悊
-const handleFileSuccess = (response, file, fileList) => {
-  upload.open = false
-  upload.isUploading = false
-  proxy.$refs["uploadRef"].handleRemove(file)
-  if (response.code !== 200) {
-    proxy.$modal.msgError(response.msg)
-  } else {
-    proxy.$modal.msgSuccess(response.msg)
-  }
-  getList()
-}
+  // 鏂囦欢涓婁紶鎴愬姛澶勭悊
+  const handleFileSuccess = (response, file, fileList) => {
+    upload.open = false;
+    upload.isUploading = false;
+    proxy.$refs["uploadRef"].handleRemove(file);
+    if (response.code !== 200) {
+      proxy.$modal.msgError(response.msg);
+    } else {
+      proxy.$modal.msgSuccess(response.msg);
+    }
+    getList();
+  };
 
-// 鎻愪氦涓婁紶鏂囦欢
-const submitFileForm = () => {
-  proxy.$refs["uploadRef"].submit()
-}
+  // 鎻愪氦涓婁紶鏂囦欢
+  const submitFileForm = () => {
+    proxy.$refs["uploadRef"].submit();
+  };
 
-onMounted(() => {
-  getList();
-});
+  onMounted(() => {
+    getList();
+  });
 </script>
 
 <style scoped>
-.search_title2 {
-  margin-left: 10px;
-}
+  .search_title2 {
+    margin-left: 10px;
+  }
 
-.positive-date-warning {
-  color: #f56c6c;
-  font-weight: bold;
-}
+  .positive-date-warning {
+    color: #f56c6c;
+    font-weight: bold;
+  }
 </style>
diff --git a/src/views/personnelManagement/monthlyStatistics/components/formDia.vue b/src/views/personnelManagement/monthlyStatistics/components/formDia.vue
index 36c2ec3..35ae756 100644
--- a/src/views/personnelManagement/monthlyStatistics/components/formDia.vue
+++ b/src/views/personnelManagement/monthlyStatistics/components/formDia.vue
@@ -1,505 +1,456 @@
 <template>
-  <FormDialog
-    v-model="dialogVisible"
-    :title="operationType === 'add' ? '鏂板缓宸ヨ祫琛�' : '缂栬緫宸ヨ祫琛�'"
-    width="90%"
-    @close="closeDia"
-  >
+  <FormDialog v-model="dialogVisible"
+              :title="operationType === 'add' ? '鏂板缓宸ヨ祫琛�' : '缂栬緫宸ヨ祫琛�'"
+              width="90%"
+              @close="closeDia">
     <template #footer>
-      <el-button type="info" @click="saveDraft">淇濆瓨鑽夌</el-button>
-      <el-button type="primary" @click="submitForm">纭鎻愪氦</el-button>
+      <el-button type="info"
+                 @click="saveDraft">淇濆瓨鑽夌</el-button>
+      <el-button type="primary"
+                 @click="submitForm">纭鎻愪氦</el-button>
       <el-button @click="closeDia">鍙栨秷</el-button>
     </template>
     <div class="form-dia-body">
       <!-- 鍩虹璧勬枡 -->
-      <el-card class="form-card" shadow="never">
+      <el-card class="form-card"
+               shadow="never">
         <template #header>
           <span class="card-title"><span class="card-title-line">|</span> 鍩虹璧勬枡</span>
-          <el-icon class="card-collapse"><ArrowUp /></el-icon>
+          <el-icon class="card-collapse">
+            <ArrowUp />
+          </el-icon>
         </template>
-        <el-form ref="formRef" :model="form" :rules="rules" label-position="top">
+        <el-form ref="formRef"
+                 :model="form"
+                 :rules="rules"
+                 label-position="top">
           <el-row :gutter="24">
             <el-col :span="6">
-              <el-form-item label="宸ヨ祫涓婚" prop="salaryTitle">
-                <el-input
-                  v-model="form.salaryTitle"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-                  maxlength="20"
-                  show-word-limit
-                />
+              <el-form-item label="宸ヨ祫涓婚"
+                            prop="salaryTitle">
+                <el-input v-model="form.salaryTitle"
+                          placeholder="璇疯緭鍏�"
+                          clearable
+                          maxlength="20"
+                          show-word-limit />
               </el-form-item>
             </el-col>
             <el-col :span="6">
-              <el-form-item label="閫夋嫨閮ㄩ棬" prop="deptIds">
-                <el-select
-                  v-model="form.deptIds"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-                  multiple
-                  collapse-tags-tooltip
-                  style="width: 100%"
-                >
-                  <el-option
-                    v-for="item in deptOptions"
-                    :key="item.deptId"
-                    :label="item.deptName"
-                    :value="item.deptId"
-                  />
+              <el-form-item label="閫夋嫨閮ㄩ棬"
+                            prop="deptIds">
+                <el-select v-model="form.deptIds"
+                           placeholder="璇烽�夋嫨"
+                           clearable
+                           multiple
+                           collapse-tags-tooltip
+                           style="width: 100%">
+                  <el-option v-for="item in deptOptions"
+                             :key="item.deptId"
+                             :label="item.deptName"
+                             :value="item.deptId" />
                 </el-select>
               </el-form-item>
             </el-col>
             <el-col :span="6">
-              <el-form-item label="閫夋嫨宸ヨ祫鏈堜唤" prop="salaryMonth">
-                <el-date-picker
-                  v-model="form.salaryMonth"
-                  type="month"
-                  value-format="YYYY-MM"
-                  format="YYYY-MM"
-                  placeholder="璇烽�夋嫨宸ヨ祫鏈堜唤"
-                  style="width: 100%"
-                  clearable
-                />
+              <el-form-item label="閫夋嫨宸ヨ祫鏈堜唤"
+                            prop="salaryMonth">
+                <el-date-picker v-model="form.salaryMonth"
+                                type="month"
+                                value-format="YYYY-MM"
+                                format="YYYY-MM"
+                                placeholder="璇烽�夋嫨宸ヨ祫鏈堜唤"
+                                style="width: 100%"
+                                clearable />
               </el-form-item>
             </el-col>
             <el-col :span="6">
-              <el-form-item label="澶囨敞" prop="remark">
-                <el-input
-                  v-model="form.remark"
-                  placeholder="璇疯緭鍏�"
-                  clearable
-                />
+              <el-form-item label="澶囨敞"
+                            prop="remark">
+                <el-input v-model="form.remark"
+                          placeholder="璇疯緭鍏�"
+                          clearable />
               </el-form-item>
             </el-col>
           </el-row>
           <el-row :gutter="24">
             <el-col :span="6">
-              <el-form-item label="鏀粯閾惰" prop="payBank">
-                <el-select
-                  v-model="form.payBank"
-                  placeholder="璇烽�夋嫨"
-                  clearable
-                  filterable
-                  style="width: 100%"
-                >
-                  <el-option
-                    v-for="b in bankOptions"
-                    :key="b"
-                    :label="b"
-                    :value="b"
-                  />
+              <el-form-item label="鏀粯閾惰"
+                            prop="payBank">
+                <el-select v-model="form.payBank"
+                           placeholder="璇烽�夋嫨"
+                           clearable
+                           filterable
+                           style="width: 100%">
+                  <el-option v-for="b in bankOptions"
+                             :key="b"
+                             :label="b"
+                             :value="b" />
                 </el-select>
               </el-form-item>
             </el-col>
             <el-col :span="6">
-              <el-form-item label="瀹℃牳浜�" prop="auditUserId">
-                <el-select
-                  v-model="form.auditUserId"
-                  placeholder="璇烽�夋嫨瀹℃牳浜�"
-                  clearable
-                  filterable
-                  style="width: 100%"
-                >
-                  <el-option
-                    v-for="item in userList"
-                    :key="item.userId"
-                    :label="item.nickName"
-                    :value="item.userId"
-                  />
+              <el-form-item label="瀹℃牳浜�"
+                            prop="auditUserId">
+                <el-select v-model="form.auditUserId"
+                           placeholder="璇烽�夋嫨瀹℃牳浜�"
+                           clearable
+                           filterable
+                           style="width: 100%">
+                  <el-option v-for="item in userList"
+                             :key="item.userId"
+                             :label="item.nickName"
+                             :value="item.userId" />
                 </el-select>
               </el-form-item>
             </el-col>
           </el-row>
         </el-form>
       </el-card>
-
       <!-- 鎿嶄綔鎸夐挳 -->
       <div class="toolbar">
-        <el-button type="primary" @click="handleGenerate">鐢熸垚宸ヨ祫琛�</el-button>
+        <el-button type="primary"
+                   @click="handleGenerate">鐢熸垚宸ヨ祫琛�</el-button>
         <el-button @click="handleClear">娓呯┖</el-button>
         <el-button @click="handleBatchDelete">鍒犻櫎</el-button>
         <el-button @click="handleTaxForm">涓◣琛�</el-button>
       </div>
-
       <!-- 鍛樺伐宸ヨ祫璇︽儏琛ㄦ牸 -->
       <div class="employee-table-wrap">
-        <el-table
-          ref="employeeTableRef"
-          :data="employeeList"
-          border
-          max-height="400"
-          @selection-change="onEmployeeSelectionChange"
-        >
-          <el-table-column type="selection" width="55" align="center" />
-          <el-table-column label="鍛樺伐濮撳悕" prop="staffName" minWidth="100" />
-          <el-table-column label="閮ㄩ棬" prop="deptName" minWidth="100" />
-          <el-table-column label="鍩烘湰宸ヨ祫" minWidth="110">
+        <el-table ref="employeeTableRef"
+                  :data="employeeList"
+                  border
+                  max-height="400"
+                  @selection-change="onEmployeeSelectionChange">
+          <el-table-column type="selection"
+                           width="55"
+                           align="center" />
+          <el-table-column label="閮ㄩ棬"
+                           prop="deptName"
+                           minWidth="120" />
+          <el-table-column label="鍛樺伐濮撳悕"
+                           prop="staffName"
+                           minWidth="100" />
+          <el-table-column label="姘戞棌"
+                           prop="nation"
+                           width="80"
+                           align="center" />
+          <el-table-column label="鍩烘湰宸ヨ祫"
+                           minWidth="110">
             <template #default="{ row }">
-              <el-input
-                v-model.number="row.basicSalary"
-                type="number"
-                placeholder="0"
-                size="small"
-                @input="row.basicSalary = parseNum(row.basicSalary)"
-              />
+              <el-input v-model.number="row.basicSalary"
+                        type="number"
+                        placeholder="0"
+                        size="small"
+                        @input="row.basicSalary = parseNum(row.basicSalary)" />
             </template>
           </el-table-column>
-          <el-table-column label="璁′欢宸ヨ祫" minWidth="110">
+          <el-table-column label="鐧界彮澶╂暟"
+                           minWidth="100">
             <template #default="{ row }">
-              <el-input
-                v-model.number="row.pieceSalary"
-                type="number"
-                placeholder="0"
-                size="small"
-                @input="row.pieceSalary = parseNum(row.pieceSalary)"
-              />
+              <el-input v-model.number="row.dayDays"
+                        type="number"
+                        placeholder="0"
+                        size="small"
+                        @input="handleDaysChange(row)" />
             </template>
           </el-table-column>
-          <el-table-column label="璁℃椂宸ヨ祫" minWidth="110">
+          <el-table-column label="澶滅彮澶╂暟"
+                           minWidth="100">
             <template #default="{ row }">
-              <el-input
-                v-model.number="row.hourlySalary"
-                type="number"
-                placeholder="0"
-                size="small"
-                @input="row.hourlySalary = parseNum(row.hourlySalary)"
-              />
+              <el-input v-model.number="row.nightDays"
+                        type="number"
+                        placeholder="0"
+                        size="small"
+                        @input="handleDaysChange(row)" />
             </template>
           </el-table-column>
-          <el-table-column label="鍏朵粬鏀跺叆" minWidth="110">
+          <el-table-column label="椁愯ˉ"
+                           minWidth="110">
             <template #default="{ row }">
-              <el-input
-                v-model.number="row.otherIncome"
-                type="number"
-                placeholder="0"
-                size="small"
-                @input="row.otherIncome = parseNum(row.otherIncome)"
-              />
+              <el-input v-model.number="row.mealAmount"
+                        type="number"
+                        placeholder="0"
+                        size="small"
+                        disabled />
             </template>
           </el-table-column>
-          <el-table-column label="绀句繚涓汉" minWidth="110">
+          <el-table-column label="澶滅彮琛ュ姪"
+                           minWidth="110">
             <template #default="{ row }">
-              <el-input
-                v-model.number="row.socialPersonal"
-                type="number"
-                placeholder="0"
-                size="small"
-                @input="row.socialPersonal = parseNum(row.socialPersonal)"
-              />
+              <el-input v-model.number="row.nightAmount"
+                        type="number"
+                        placeholder="0"
+                        size="small"
+                        disabled />
             </template>
           </el-table-column>
-          <el-table-column label="鍏Н閲戜釜浜�" minWidth="120">
+          <el-table-column label="鍏朵粬鏀跺叆"
+                           minWidth="110">
             <template #default="{ row }">
-              <el-input
-                v-model.number="row.fundPersonal"
-                type="number"
-                placeholder="0"
-                size="small"
-                @input="row.fundPersonal = parseNum(row.fundPersonal)"
-              />
+              <el-input v-model.number="row.otherIncome"
+                        type="number"
+                        placeholder="0"
+                        size="small"
+                        @input="row.otherIncome = parseNum(row.otherIncome)" />
             </template>
           </el-table-column>
-          <el-table-column label="鍏朵粬鏀嚭" minWidth="110">
+          <el-table-column label="绀句繚涓汉"
+                           minWidth="110">
             <template #default="{ row }">
-              <el-input
-                v-model.number="row.otherDeduct"
-                type="number"
-                placeholder="0"
-                size="small"
-                @input="row.otherDeduct = parseNum(row.otherDeduct)"
-              />
+              <el-input v-model.number="row.socialPersonal"
+                        type="number"
+                        placeholder="0"
+                        size="small"
+                        @input="row.socialPersonal = parseNum(row.socialPersonal)" />
             </template>
           </el-table-column>
-          <el-table-column label="宸ヨ祫涓◣" minWidth="110">
+          <el-table-column label="鍏Н閲戜釜浜�"
+                           minWidth="120">
             <template #default="{ row }">
-              <el-input
-                v-model.number="row.salaryTax"
-                type="number"
-                placeholder="0"
-                size="small"
-                @input="row.salaryTax = parseNum(row.salaryTax)"
-              />
+              <el-input v-model.number="row.fundPersonal"
+                        type="number"
+                        placeholder="0"
+                        size="small"
+                        @input="row.fundPersonal = parseNum(row.fundPersonal)" />
             </template>
           </el-table-column>
-          <el-table-column label="搴斿彂宸ヨ祫" minWidth="110">
+          <el-table-column label="鍏朵粬鏀嚭"
+                           minWidth="110">
             <template #default="{ row }">
-              <el-input
-                v-model.number="row.grossSalary"
-                type="number"
-                placeholder="0"
-                size="small"
-                @input="row.grossSalary = parseNum(row.grossSalary)"
-              />
+              <el-input v-model.number="row.otherDeduct"
+                        type="number"
+                        placeholder="0"
+                        size="small"
+                        @input="row.otherDeduct = parseNum(row.otherDeduct)" />
             </template>
           </el-table-column>
-          <el-table-column label="搴旀墸宸ヨ祫" minWidth="110">
+          <el-table-column label="绀句繚琛ョ即"
+                           minWidth="110">
             <template #default="{ row }">
-              <el-input
-                v-model.number="row.deductSalary"
-                type="number"
-                placeholder="0"
-                size="small"
-                @input="row.deductSalary = parseNum(row.deductSalary)"
-              />
+              <el-input v-model.number="row.socialSecurityRetroactive"
+                        type="number"
+                        placeholder="0"
+                        size="small"
+                        @input="row.socialSecurityRetroactive = parseNum(row.socialSecurityRetroactive)" />
             </template>
           </el-table-column>
-          <el-table-column label="瀹炲彂宸ヨ祫" minWidth="110">
+          <el-table-column label="宸ヨ祫涓◣"
+                           minWidth="110">
             <template #default="{ row }">
-              <el-input
-                v-model.number="row.netSalary"
-                type="number"
-                placeholder="0"
-                size="small"
-                @input="row.netSalary = parseNum(row.netSalary)"
-              />
+              <el-input v-model.number="row.salaryTax"
+                        type="number"
+                        placeholder="0"
+                        size="small"
+                        @input="row.salaryTax = parseNum(row.salaryTax)" />
             </template>
           </el-table-column>
-          <el-table-column label="澶囨敞" minWidth="120">
+          <el-table-column label="搴斿彂宸ヨ祫"
+                           minWidth="110">
             <template #default="{ row }">
-              <el-input
-                v-model="row.remark"
-                placeholder="璇疯緭鍏�"
-                size="small"
-              />
+              <el-input v-model.number="row.grossSalary"
+                        type="number"
+                        placeholder="0"
+                        size="small"
+                        @input="row.grossSalary = parseNum(row.grossSalary)" />
             </template>
           </el-table-column>
-          <el-table-column label="鎿嶄綔" width="80" align="center" fixed="right">
+          <el-table-column label="搴旀墸宸ヨ祫"
+                           minWidth="110">
             <template #default="{ row }">
-              <el-button type="primary" link @click="removeEmployee(row)">鍒犻櫎</el-button>
+              <el-input v-model.number="row.deductSalary"
+                        type="number"
+                        placeholder="0"
+                        size="small"
+                        @input="row.deductSalary = parseNum(row.deductSalary)" />
+            </template>
+          </el-table-column>
+          <el-table-column label="瀹炲彂宸ヨ祫"
+                           minWidth="110">
+            <template #default="{ row }">
+              <el-input v-model.number="row.netSalary"
+                        type="number"
+                        placeholder="0"
+                        size="small"
+                        @input="row.netSalary = parseNum(row.netSalary)" />
+            </template>
+          </el-table-column>
+          <el-table-column label="澶囨敞"
+                           minWidth="120">
+            <template #default="{ row }">
+              <el-input v-model="row.remark"
+                        placeholder="璇疯緭鍏�"
+                        size="small" />
+            </template>
+          </el-table-column>
+          <el-table-column label="鎿嶄綔"
+                           width="80"
+                           align="center"
+                           fixed="right">
+            <template #default="{ row }">
+              <el-button type="primary"
+                         link
+                         @click="removeEmployee(row)">鍒犻櫎</el-button>
             </template>
           </el-table-column>
         </el-table>
-        <div v-if="!employeeList.length" class="table-empty">鏆傛棤鏁版嵁</div>
-        <div v-else class="salary-total">
+        <div v-if="!employeeList.length"
+             class="table-empty">鏆傛棤鏁版嵁</div>
+        <div v-else
+             class="salary-total">
           <span class="total-label">宸ヨ祫鎬婚锛�</span>
           <span class="total-value">楼 {{ totalSalary.toFixed(2) }}</span>
         </div>
       </div>
     </div>
-
-
-
     <!-- 鏂板浜哄憳寮圭獥 -->
-    <el-dialog
-      v-model="addPersonVisible"
-      title="鏂板浜哄憳"
-      width="400px"
-      append-to-body
-      @close="addPersonClose"
-    >
+    <el-dialog v-model="addPersonVisible"
+               title="鏂板浜哄憳"
+               width="400px"
+               append-to-body
+               @close="addPersonClose">
       <div class="add-person-tree">
-        <el-tree
-          ref="personTreeRef"
-          :data="deptStaffTree"
-          show-checkbox
-          node-key="id"
-          :props="{ label: 'label', children: 'children' }"
-          default-expand-all
-        />
+        <el-tree ref="personTreeRef"
+                 :data="deptStaffTree"
+                 show-checkbox
+                 node-key="id"
+                 :props="{ label: 'label', children: 'children' }"
+                 default-expand-all />
       </div>
       <template #footer>
         <el-button @click="addPersonVisible = false">鍙栨秷</el-button>
-        <el-button type="primary" @click="confirmAddPerson">纭畾</el-button>
+        <el-button type="primary"
+                   @click="confirmAddPerson">纭畾</el-button>
       </template>
     </el-dialog>
-
     <!-- 涓◣琛ㄥ脊绐� -->
-    <el-dialog
-      v-model="taxDialogVisible"
-      title="涓◣琛�"
-      width="700px"
-      append-to-body
-    >
+    <el-dialog v-model="taxDialogVisible"
+               title="涓◣琛�"
+               width="700px"
+               append-to-body>
       <div class="tax-desc">涓汉鎵�寰楃◣鍏嶅緛棰濓細5000鍏�</div>
-      <el-table :data="taxTableData" border style="width: 100%;margin-bottom: 20px;">
-        <el-table-column prop="level" label="绾ф暟" width="80" align="center" />
-        <el-table-column
-          prop="range"
-          label="鍏ㄥ勾搴旂撼绋庢墍寰楅/鍏�"
-          min-width="220"
-        />
-        <el-table-column
-          prop="rate"
-          label="绋庣巼(%)"
-          width="100"
-          align="center"
-        />
-        <el-table-column
-          prop="quickDeduction"
-          label="閫熺畻鎵i櫎鏁�/鍏�"
-          width="160"
-          align="center"
-        />
+      <el-table :data="taxTableData"
+                border
+                style="width: 100%;margin-bottom: 20px;">
+        <el-table-column prop="level"
+                         label="绾ф暟"
+                         width="80"
+                         align="center" />
+        <el-table-column prop="range"
+                         label="鍏ㄥ勾搴旂撼绋庢墍寰楅/鍏�"
+                         min-width="220" />
+        <el-table-column prop="rate"
+                         label="绋庣巼(%)"
+                         width="100"
+                         align="center" />
+        <el-table-column prop="quickDeduction"
+                         label="閫熺畻鎵i櫎鏁�/鍏�"
+                         width="160"
+                         align="center" />
       </el-table>
     </el-dialog>
   </FormDialog>
 </template>
 
 <script setup>
-import { ref, reactive, toRefs, computed, getCurrentInstance, nextTick } from "vue";
-import { ArrowUp } from "@element-plus/icons-vue";
-import FormDialog from "@/components/Dialog/FormDialog.vue";
-import { listDept } from "@/api/system/dept.js";
-import { staffOnJobList } from "@/api/personnelManagement/monthlyStatistics.js";
-import { bankList } from "@/api/personnelManagement/bank.js";
-import {
-  staffSalaryMainAdd,
-  staffSalaryMainUpdate,
-  staffSalaryMainCalculateSalary,
-} from "@/api/personnelManagement/staffSalaryMain.js";
-import { userListNoPageByTenantId } from "@/api/system/user.js";
+  import {
+    ref,
+    reactive,
+    toRefs,
+    computed,
+    getCurrentInstance,
+    nextTick,
+  } from "vue";
+  import { ArrowUp } from "@element-plus/icons-vue";
+  import FormDialog from "@/components/Dialog/FormDialog.vue";
+  import { listDept } from "@/api/system/dept.js";
+  import { staffOnJobList } from "@/api/personnelManagement/monthlyStatistics.js";
+  import { bankList } from "@/api/personnelManagement/bank.js";
+  import {
+    staffSalaryMainAdd,
+    staffSalaryMainUpdate,
+    staffSalaryMainCalculateSalary,
+  } from "@/api/personnelManagement/staffSalaryMain.js";
+  import { userListNoPageByTenantId } from "@/api/system/user.js";
+  import { listSubsidyConfiguration } from "@/api/personnelManagement/subsidyConfig.js";
 
-
-const emit = defineEmits(["update:modelValue", "close"]);
-const props = defineProps({
-  modelValue: { type: Boolean, default: false },
-  operationType: { type: String, default: "add" },
-  row: { type: Object, default: () => ({}) },
-});
-
-const { proxy } = getCurrentInstance();
-
-const dialogVisible = computed({
-  get: () => props.modelValue,
-  set: (val) => emit("update:modelValue", val),
-});
-
-const formRef = ref(null);
-const employeeTableRef = ref(null);
-const personTreeRef = ref(null);
-const addPersonVisible = ref(false);
-const taxDialogVisible = ref(false);
-const deptOptions = ref([]);
-const deptStaffTree = ref([]);
-const employeeList = ref([]);
-const selectedEmployees = ref([]);
-const bankOptions = ref([]);
-const userList = ref([]);
-const taxTableData = ref([
-  { level: 1, range: "涓嶈秴杩�36000鍏�", rate: 3, quickDeduction: 0 },
-  { level: 2, range: "瓒呰繃36000-144000鍏�", rate: 10, quickDeduction: 2520 },
-  { level: 3, range: "瓒呰繃144000-300000鍏�", rate: 20, quickDeduction: 16920 },
-  { level: 4, range: "瓒呰繃300000-420000鍏�", rate: 25, quickDeduction: 31920 },
-  { level: 5, range: "瓒呰繃420000-660000鍏�", rate: 30, quickDeduction: 52920 },
-  { level: 6, range: "瓒呰繃660000-960000鍏�", rate: 35, quickDeduction: 85920 },
-  { level: 7, range: "瓒呰繃960000鍏�", rate: 45, quickDeduction: 181920 },
-]);
-
-function parseNum(v) {
-  if (v === "" || v == null) return 0;
-  const n = Number(v);
-  return isNaN(n) ? 0 : n;
-}
-
-// 鍩虹璧勬枡琛ㄥ崟
-const data = reactive({
-  form: {
-    id: undefined,
-    salaryTitle: "",
-    deptIds: [],
-    salaryMonth: "",
-    remark: "",
-    payBank: "",
-    auditUserId: undefined,
-  },
-  rules: {
-    salaryTitle: [{ required: true, message: "璇疯緭鍏ュ伐璧勪富棰�", trigger: "blur" }],
-    deptIds: [{ required: true, message: "璇烽�夋嫨閮ㄩ棬", trigger: "change" }],
-    salaryMonth: [{ required: true, message: "璇烽�夋嫨宸ヨ祫鏈堜唤", trigger: "change" }],
-    auditUserId: [{ required: true, message: "璇烽�夋嫨瀹℃牳浜�", trigger: "change" }],
-  },
-});
-const { form, rules } = toRefs(data);
-
-// 璁$畻宸ヨ祫鎬婚锛堟墍鏈夊憳宸ュ疄鍙戝伐璧勪箣鍜岋級
-const totalSalary = computed(() => {
-  return employeeList.value.reduce((sum, e) => sum + parseNum(e.netSalary), 0);
-});
-
-// 鏍规嵁瀹℃牳浜篒D鑾峰彇瀹℃牳浜哄悕绉�
-const auditUserName = computed(() => {
-  if (!form.value.auditUserId) return "";
-  const user = userList.value.find(u => u.userId === form.value.auditUserId);
-  return user ? user.nickName : "";
-});
-
-const loadBankOptions = () => {
-  return bankList().then((res) => {
-    const list = Array.isArray(res?.data) ? res.data : [];
-    bankOptions.value = list
-      .map((b) => (b?.bankName == null ? "" : String(b.bankName).trim()))
-      .filter((v) => v !== "");
+  const emit = defineEmits(["update:modelValue", "close"]);
+  const props = defineProps({
+    modelValue: { type: Boolean, default: false },
+    operationType: { type: String, default: "add" },
+    row: { type: Object, default: () => ({}) },
   });
-};
 
-const loadUserList = () => {
-  return userListNoPageByTenantId().then((res) => {
-    userList.value = res.data || [];
+  const { proxy } = getCurrentInstance();
+
+  const dialogVisible = computed({
+    get: () => props.modelValue,
+    set: val => emit("update:modelValue", val),
   });
-};
 
-// 鎵佸钩鍖栭儴闂ㄦ爲渚涗笅鎷変娇鐢�
-function flattenDept(tree, list = []) {
-  if (!tree?.length) return list;
-  tree.forEach((node) => {
-    list.push({ deptId: node.deptId, deptName: node.deptName });
-    if (node.children?.length) flattenDept(node.children, list);
+  const formRef = ref(null);
+  const employeeTableRef = ref(null);
+  const personTreeRef = ref(null);
+  const addPersonVisible = ref(false);
+  const taxDialogVisible = ref(false);
+  const deptOptions = ref([]);
+  const deptStaffTree = ref([]);
+  const employeeList = ref([]);
+  const selectedEmployees = ref([]);
+  const bankOptions = ref([]);
+  const userList = ref([]);
+  const subsidyStandard = ref({
+    mealAmount: 0,
+    nightAmount: 0,
   });
-  return list;
-}
 
-const loadDeptOptions = () => {
-  listDept().then((res) => {
-    const tree = res.data ?? [];
-    deptOptions.value = flattenDept(tree);
-  });
-};
-
-// 鏋勫缓 閮ㄩ棬-浜哄憳 鏍戯紙鐢ㄤ簬鏂板浜哄憳寮圭獥锛�
-const loadDeptStaffTree = () => {
-  Promise.all([listDept(), staffOnJobList()]).then(([deptRes, staffRes]) => {
-    const tree = deptRes.data ?? [];
-    const staffList = staffRes.data ?? [];
-    const deptMap = new Map();
-    function walk(nodes) {
-      nodes.forEach((node) => {
-        deptMap.set(node.deptId, {
-          id: "dept_" + node.deptId,
-          deptId: node.deptId,
-          label: node.deptName,
-          type: "dept",
-          children: [],
-        });
-        if (node.children?.length) walk(node.children);
-      });
-    }
-    walk(tree);
-    staffList.forEach((s) => {
-      const deptId = s.deptId ?? s.dept_id;
-      const node = deptMap.get(deptId);
-      if (node) {
-        node.children.push({
-          id: s.id ?? s.staffId,
-          staffId: s.id ?? s.staffId,
-          label: s.staffName ?? s.name,
-          type: "staff",
-          ...s,
-        });
+  const loadSubsidyStandard = () => {
+    listSubsidyConfiguration().then(res => {
+      if (res.data && res.data.length > 0) {
+        subsidyStandard.value = {
+          mealAmount: res.data[0].mealAmount || 0,
+          nightAmount: res.data[0].nightAmount || 0,
+        };
       }
     });
-    deptStaffTree.value = Array.from(deptMap.values()).filter(
-      (n) => n.children && n.children.length > 0
-    );
-  });
-};
+  };
 
-const openDialog = (type, row) => {
-  nextTick(() => {
-    loadDeptOptions();
-    loadBankOptions();
-    loadUserList();
-    employeeList.value = [];
-    Object.assign(form.value, {
+  const handleDaysChange = row => {
+    row.dayDays = parseNum(row.dayDays);
+    row.nightDays = parseNum(row.nightDays);
+
+    // 澶滅彮琛ヨ创璁$畻锛氬鐝ぉ鏁� * 鏍囧噯
+    row.nightAmount = row.nightDays * subsidyStandard.value.nightAmount;
+
+    // 椁愯ˉ璁$畻锛氫粎闄愬洖鏃忥紝(鐧界彮 + 澶滅彮) * 鏍囧噯
+    // 娉ㄦ剰锛歯ation 鍙兘鏄瓧鍏稿�硷紝杩欓噷鍋囪 "鍥炴棌" 鏄洿鎺ュ瓨鍌ㄧ殑瀛楃涓叉垨闇�瑕佹牴鎹瓧鍏稿垽鏂�
+    // 涔嬪墠鐨� BasicInfoSection.vue 涓皯鏃忔槸涓嬫媺妗嗭紝閫氬父瀛樺偍鐨勬槸瀛楀吀鐨� value 鎴� label
+    // 杩欓噷鍏堢畝鍗曞垽鏂寘鍚� "鍥�" 瀛楋紝鎴栬�呮偍鍙互鏍规嵁鍏蜂綋瀛楀吀鍊艰皟鏁�
+    if (row.nation && (row.nation === "鍥炴棌" || row.nation.includes("鍥�"))) {
+      row.mealAmount =
+        (row.dayDays + row.nightDays) * subsidyStandard.value.mealAmount;
+    } else {
+      row.mealAmount = 0;
+    }
+  };
+  const taxTableData = ref([
+    { level: 1, range: "涓嶈秴杩�36000鍏�", rate: 3, quickDeduction: 0 },
+    { level: 2, range: "瓒呰繃36000-144000鍏�", rate: 10, quickDeduction: 2520 },
+    { level: 3, range: "瓒呰繃144000-300000鍏�", rate: 20, quickDeduction: 16920 },
+    { level: 4, range: "瓒呰繃300000-420000鍏�", rate: 25, quickDeduction: 31920 },
+    { level: 5, range: "瓒呰繃420000-660000鍏�", rate: 30, quickDeduction: 52920 },
+    { level: 6, range: "瓒呰繃660000-960000鍏�", rate: 35, quickDeduction: 85920 },
+    { level: 7, range: "瓒呰繃960000鍏�", rate: 45, quickDeduction: 181920 },
+  ]);
+
+  function parseNum(v) {
+    if (v === "" || v == null) return 0;
+    const n = Number(v);
+    return isNaN(n) ? 0 : n;
+  }
+
+  // 鍩虹璧勬枡琛ㄥ崟
+  const data = reactive({
+    form: {
       id: undefined,
       salaryTitle: "",
       deptIds: [],
@@ -507,298 +458,433 @@
       remark: "",
       payBank: "",
       auditUserId: undefined,
+    },
+    rules: {
+      salaryTitle: [
+        { required: true, message: "璇疯緭鍏ュ伐璧勪富棰�", trigger: "blur" },
+      ],
+      deptIds: [{ required: true, message: "璇烽�夋嫨閮ㄩ棬", trigger: "change" }],
+      salaryMonth: [
+        { required: true, message: "璇烽�夋嫨宸ヨ祫鏈堜唤", trigger: "change" },
+      ],
+      auditUserId: [
+        { required: true, message: "璇烽�夋嫨瀹℃牳浜�", trigger: "change" },
+      ],
+    },
+  });
+  const { form, rules } = toRefs(data);
+
+  // 璁$畻宸ヨ祫鎬婚锛堟墍鏈夊憳宸ュ疄鍙戝伐璧勪箣鍜岋級
+  const totalSalary = computed(() => {
+    return employeeList.value.reduce((sum, e) => sum + parseNum(e.netSalary), 0);
+  });
+
+  // 鏍规嵁瀹℃牳浜篒D鑾峰彇瀹℃牳浜哄悕绉�
+  const auditUserName = computed(() => {
+    if (!form.value.auditUserId) return "";
+    const user = userList.value.find(u => u.userId === form.value.auditUserId);
+    return user ? user.nickName : "";
+  });
+
+  const loadBankOptions = () => {
+    return bankList().then(res => {
+      const list = Array.isArray(res?.data) ? res.data : [];
+      bankOptions.value = list
+        .map(b => (b?.bankName == null ? "" : String(b.bankName).trim()))
+        .filter(v => v !== "");
     });
-    // 缂栬緫锛氬垪琛ㄩ〉宸茶繑鍥炰富琛ㄥ瓧娈碉紱杩欓噷鍙仛鍥炴樉锛堟槑缁嗙敱鈥滅敓鎴愬伐璧勮〃/璁$畻宸ヨ祫鈥濆緱鍒帮級
-    if (type === "edit" && row?.id) {
-      form.value.id = row.id;
-      form.value.salaryTitle = row.salaryTitle ?? "";
-      // deptIds 鍚庣鏄瓧绗︿覆锛堝涓敤閫楀彿鍒嗛殧锛夛紱褰撳墠琛ㄥ崟浠嶆槸鍗曢�� deptId
-      form.value.deptIds = row.deptIds
-        ? String(row.deptIds).split(",").map((id) => Number(id.trim())).filter(Boolean)
-        : [];
-      form.value.salaryMonth = row.salaryMonth ?? "";
-      form.value.remark = row.remark ?? "";
-      form.value.payBank = row.payBank ?? "";
-      form.value.auditUserId = row.auditUserId ?? undefined;
-      
-      // 濡傛灉鏈夊憳宸ユ槑缁嗘暟鎹紝鐩存帴鍙嶆樉
-      if (row.staffSalaryDetailList && row.staffSalaryDetailList.length > 0) {
-        employeeList.value = row.staffSalaryDetailList.map((e) => ({
-          staffOnJobId: e.staffOnJobId ?? e.staffId ?? e.id,
-          id: e.staffOnJobId ?? e.staffId ?? e.id,
-          staffName: e.staffName ?? "",
-          postName: e.postName ?? "",
-          deptName: e.deptName ?? "",
-          basicSalary: parseNum(e.basicSalary),
-          pieceSalary: parseNum(e.pieceSalary),
-          hourlySalary: parseNum(e.hourlySalary),
-          otherIncome: parseNum(e.otherIncome),
-          socialPersonal: parseNum(e.socialPersonal),
-          fundPersonal: parseNum(e.fundPersonal),
-          otherDeduct: parseNum(e.otherDeduct),
-          salaryTax: parseNum(e.salaryTax),
-          grossSalary: parseNum(e.grossSalary),
-          deductSalary: parseNum(e.deductSalary),
-          netSalary: parseNum(e.netSalary),
-          remark: e.remark ?? "",
-        }));
-      }
-    }
-  });
-};
-
-const openAddPerson = () => {
-  loadDeptStaffTree();
-  addPersonVisible.value = true;
-  nextTick(() => {
-    personTreeRef.value?.setCheckedKeys([]);
-  });
-};
-
-const addPersonClose = () => {};
-
-const confirmAddPerson = () => {
-  const tree = personTreeRef.value;
-  if (!tree) {
-    addPersonVisible.value = false;
-    return;
-  }
-  const checked = tree.getCheckedNodes();
-  const staffNodes = checked.filter((n) => n.type === "staff");
-  const existIds = new Set(employeeList.value.map((e) => e.staffId || e.id));
-  staffNodes.forEach((node) => {
-    const id = node.staffId ?? node.id;
-    if (existIds.has(id)) return;
-    existIds.add(id);
-    employeeList.value.push({
-      staffOnJobId: id,
-      id,
-      staffName: node.label,
-      postName: node.postName ?? node.post ?? "",
-      deptName: node.deptName ?? "",
-      basicSalary: 0,
-      pieceSalary: 0,
-      hourlySalary: 0,
-      otherIncome: 0,
-      socialPersonal: 0,
-      fundPersonal: 0,
-      otherDeduct: 0,
-      salaryTax: 0,
-      grossSalary: 0,
-      deductSalary: 0,
-      netSalary: 0,
-      remark: "",
-    });
-  });
-  addPersonVisible.value = false;
-};
-
-const removeEmployee = (row) => {
-  employeeList.value = employeeList.value.filter(
-    (e) => (e.staffOnJobId || e.id) !== (row.staffOnJobId || row.id)
-  );
-};
-
-const onEmployeeSelectionChange = (selection) => {
-  selectedEmployees.value = selection;
-};
-
-const handleBatchDelete = () => {
-  if (!selectedEmployees.value?.length) {
-    proxy.$modal.msgWarning("璇峰厛鍕鹃�夎鍒犻櫎鐨勫憳宸�");
-    return;
-  }
-  const ids = new Set(selectedEmployees.value.map((e) => e.staffOnJobId || e.id));
-  employeeList.value = employeeList.value.filter(
-    (e) => !ids.has(e.staffOnJobId || e.id)
-  );
-};
-
-const handleGenerate = () => {
-  if (!form.value.deptIds?.length) {
-    proxy.$modal.msgWarning("璇峰厛閫夋嫨閮ㄩ棬");
-    return;
-  }
-  if (!form.value.salaryMonth) {
-    proxy.$modal.msgWarning("璇峰厛閫夋嫨宸ヨ祫鏈堜唤");
-    return;
-  }
-  const payload = {
-    ids: form.value.deptIds,
-    date: form.value.salaryMonth,
   };
-  staffSalaryMainCalculateSalary(payload).then((res) => {
-    const list = Array.isArray(res?.data) ? res.data : [];
-    if (!list.length) {
-      proxy.$modal.msgWarning("鏈绠楀埌宸ヨ祫鏁版嵁");
+
+  const loadUserList = () => {
+    return userListNoPageByTenantId().then(res => {
+      userList.value = res.data || [];
+    });
+  };
+
+  // 鎵佸钩鍖栭儴闂ㄦ爲渚涗笅鎷変娇鐢�
+  function flattenDept(tree, list = []) {
+    if (!tree?.length) return list;
+    tree.forEach(node => {
+      list.push({ deptId: node.deptId, deptName: node.deptName });
+      if (node.children?.length) flattenDept(node.children, list);
+    });
+    return list;
+  }
+
+  const loadDeptOptions = () => {
+    listDept().then(res => {
+      const tree = res.data ?? [];
+      deptOptions.value = flattenDept(tree);
+    });
+  };
+
+  // 鏋勫缓 閮ㄩ棬-浜哄憳 鏍戯紙鐢ㄤ簬鏂板浜哄憳寮圭獥锛�
+  const loadDeptStaffTree = () => {
+    Promise.all([listDept(), staffOnJobList()]).then(([deptRes, staffRes]) => {
+      const tree = deptRes.data ?? [];
+      const staffList = staffRes.data ?? [];
+      const deptMap = new Map();
+      function walk(nodes) {
+        nodes.forEach(node => {
+          deptMap.set(node.deptId, {
+            id: "dept_" + node.deptId,
+            deptId: node.deptId,
+            label: node.deptName,
+            type: "dept",
+            children: [],
+          });
+          if (node.children?.length) walk(node.children);
+        });
+      }
+      walk(tree);
+      staffList.forEach(s => {
+        const deptId = s.deptId ?? s.dept_id;
+        const node = deptMap.get(deptId);
+        if (node) {
+          node.children.push({
+            id: s.id ?? s.staffId,
+            staffId: s.id ?? s.staffId,
+            label: s.staffName ?? s.name,
+            type: "staff",
+            ...s,
+          });
+        }
+      });
+      deptStaffTree.value = Array.from(deptMap.values()).filter(
+        n => n.children && n.children.length > 0
+      );
+    });
+  };
+
+  const openDialog = (type, row) => {
+    nextTick(() => {
+      loadDeptOptions();
+      loadBankOptions();
+      loadUserList();
+      loadSubsidyStandard();
+      employeeList.value = [];
+      Object.assign(form.value, {
+        id: undefined,
+        salaryTitle: "",
+        deptIds: [],
+        salaryMonth: "",
+        remark: "",
+        payBank: "",
+        auditUserId: undefined,
+      });
+      // 缂栬緫锛氬垪琛ㄩ〉宸茶繑鍥炰富琛ㄥ瓧娈碉紱杩欓噷鍙仛鍥炴樉锛堟槑缁嗙敱鈥滅敓鎴愬伐璧勮〃/璁$畻宸ヨ祫鈥濆緱鍒帮級
+      if (type === "edit" && row?.id) {
+        form.value.id = row.id;
+        form.value.salaryTitle = row.salaryTitle ?? "";
+        // deptIds 鍚庣鏄瓧绗︿覆锛堝涓敤閫楀彿鍒嗛殧锛夛紱褰撳墠琛ㄥ崟浠嶆槸鍗曢�� deptId
+        form.value.deptIds = row.deptIds
+          ? String(row.deptIds)
+              .split(",")
+              .map(id => Number(id.trim()))
+              .filter(Boolean)
+          : [];
+        form.value.salaryMonth = row.salaryMonth ?? "";
+        form.value.remark = row.remark ?? "";
+        form.value.payBank = row.payBank ?? "";
+        form.value.auditUserId = row.auditUserId ?? undefined;
+
+        // 濡傛灉鏈夊憳宸ユ槑缁嗘暟鎹紝鐩存帴鍙嶆樉
+        if (row.staffSalaryDetailList && row.staffSalaryDetailList.length > 0) {
+          employeeList.value = row.staffSalaryDetailList.map(e => ({
+            staffOnJobId: e.staffOnJobId ?? e.staffId ?? e.id,
+            id: e.staffOnJobId ?? e.staffId ?? e.id,
+            staffName: e.staffName ?? "",
+            postName: e.postName ?? "",
+            deptName: e.deptName ?? "",
+            nation: e.nation ?? "",
+            basicSalary: parseNum(e.basicSalary),
+            dayDays: parseNum(e.dayDays ?? e.dayShiftDays),
+            nightDays: parseNum(e.nightDays ?? e.nightShiftDays),
+            mealAmount: parseNum(e.mealAmount ?? e.mealSubsidy),
+            nightAmount: parseNum(e.nightAmount ?? e.nightSubsidy),
+            otherIncome: parseNum(e.otherIncome),
+            socialPersonal: parseNum(e.socialPersonal),
+            fundPersonal: parseNum(e.fundPersonal),
+            otherDeduct: parseNum(e.otherDeduct),
+            socialSecurityRetroactive: parseNum(e.socialSecurityRetroactive),
+            salaryTax: parseNum(e.salaryTax),
+            grossSalary: parseNum(e.grossSalary),
+            deductSalary: parseNum(e.deductSalary),
+            netSalary: parseNum(e.netSalary),
+            remark: e.remark ?? "",
+          }));
+        }
+      }
+    });
+  };
+
+  const openAddPerson = () => {
+    loadDeptStaffTree();
+    addPersonVisible.value = true;
+    nextTick(() => {
+      personTreeRef.value?.setCheckedKeys([]);
+    });
+  };
+
+  const addPersonClose = () => {};
+
+  const confirmAddPerson = () => {
+    const tree = personTreeRef.value;
+    if (!tree) {
+      addPersonVisible.value = false;
       return;
     }
-    employeeList.value = list.map((e) => ({
-      ...e,
-      staffOnJobId: e.staffOnJobId ?? e.staffId ?? e.id,
-      staffName: e.staffName,
-      postName: e.postName,
-      deptName: e.deptName,
-      basicSalary: parseNum(e.basicSalary),
-      pieceSalary: parseNum(e.pieceSalary),
-      hourlySalary: parseNum(e.hourlySalary),
-      otherIncome: parseNum(e.otherIncome),
-      socialPersonal: parseNum(e.socialPersonal),
-      fundPersonal: parseNum(e.fundPersonal),
-      otherDeduct: parseNum(e.otherDeduct),
-      salaryTax: parseNum(e.salaryTax),
-      grossSalary: parseNum(e.grossSalary),
-      deductSalary: parseNum(e.deductSalary),
-      netSalary: parseNum(e.netSalary),
-      remark: e.remark ?? "",
-    }));
-    proxy.$modal.msgSuccess("鐢熸垚鎴愬姛");
-  });
-};
-
-const handleClear = () => {
-  proxy.$modal.confirm("纭畾娓呯┖褰撳墠鍛樺伐鍒楄〃鍚楋紵").then(() => {
-    employeeList.value = [];
-  }).catch(() => {});
-};
-
-const handleTaxForm = () => {
-  taxDialogVisible.value = true;
-};
-
-const submitForm = () => {
-  formRef.value?.validate((valid) => {
-    if (!valid) return;
-    saveData(3); // 纭鎻愪氦锛岀姸鎬佷负3锛堝緟瀹℃牳锛�
-  });
-};
-
-const saveDraft = () => {
-  formRef.value?.validate((valid) => {
-    if (!valid) return;
-    saveData(1); // 淇濆瓨鑽夌锛岀姸鎬佷负1锛堣崏绋匡級
-  });
-};
-
-const saveData = (status) => {
-  const payload = {
-    id: form.value.id,
-    salaryTitle: form.value.salaryTitle,
-    deptIds: form.value.deptIds?.length ? form.value.deptIds.join(",") : "",
-    salaryMonth: form.value.salaryMonth,
-    remark: form.value.remark,
-    payBank: form.value.payBank,
-    auditUserId: form.value.auditUserId,
-    auditUserName: auditUserName.value,
-    totalSalary: totalSalary.value,
-    staffSalaryDetailList: employeeList.value.map((e) => ({
-      staffOnJobId: e.staffOnJobId ?? e.staffId ?? e.id,
-      staffName: e.staffName,
-      postName: e.postName ?? "",
-      deptName: e.deptName ?? "",
-      basicSalary: parseNum(e.basicSalary),
-      pieceSalary: parseNum(e.pieceSalary),
-      hourlySalary: parseNum(e.hourlySalary),
-      otherIncome: parseNum(e.otherIncome),
-      socialPersonal: parseNum(e.socialPersonal),
-      fundPersonal: parseNum(e.fundPersonal),
-      otherDeduct: parseNum(e.otherDeduct),
-      salaryTax: parseNum(e.salaryTax),
-      grossSalary: parseNum(e.grossSalary),
-      deductSalary: parseNum(e.deductSalary),
-      netSalary: parseNum(e.netSalary),
-      remark: e.remark ?? "",
-    })),
+    const checked = tree.getCheckedNodes();
+    const staffNodes = checked.filter(n => n.type === "staff");
+    const existIds = new Set(employeeList.value.map(e => e.staffId || e.id));
+    staffNodes.forEach(node => {
+      const id = node.staffId ?? node.id;
+      if (existIds.has(id)) return;
+      existIds.add(id);
+      employeeList.value.push({
+        staffOnJobId: id,
+        id,
+        staffName: node.label,
+        postName: node.postName ?? node.post ?? "",
+        deptName: node.deptName ?? "",
+        nation: node.nation ?? "",
+        basicSalary: parseNum(node.basicSalary),
+        dayDays: 0,
+        nightDays: 0,
+        mealAmount: 0,
+        nightAmount: 0,
+        otherIncome: 0,
+        socialPersonal: 0,
+        fundPersonal: 0,
+        otherDeduct: 0,
+        socialSecurityRetroactive: 0,
+        salaryTax: 0,
+        grossSalary: 0,
+        deductSalary: 0,
+        netSalary: 0,
+        remark: "",
+      });
+    });
+    addPersonVisible.value = false;
   };
-  if (props.operationType === "add") {
-    staffSalaryMainAdd({ ...payload, status }).then(() => {
-      proxy.$modal.msgSuccess(status === 1 ? "鑽夌淇濆瓨鎴愬姛" : "鎻愪氦鎴愬姛");
-      closeDia();
-    });
-  } else {
-    staffSalaryMainUpdate({ ...payload, status }).then(() => {
-      proxy.$modal.msgSuccess(status === 1 ? "鑽夌淇濆瓨鎴愬姛" : "鎻愪氦鎴愬姛");
-      closeDia();
-    });
-  }
-};
 
-const closeDia = () => {
-  dialogVisible.value = false;
-  emit("close");
-};
+  const removeEmployee = row => {
+    employeeList.value = employeeList.value.filter(
+      e => (e.staffOnJobId || e.id) !== (row.staffOnJobId || row.id)
+    );
+  };
 
-defineExpose({ openDialog });
+  const onEmployeeSelectionChange = selection => {
+    selectedEmployees.value = selection;
+  };
+
+  const handleBatchDelete = () => {
+    if (!selectedEmployees.value?.length) {
+      proxy.$modal.msgWarning("璇峰厛鍕鹃�夎鍒犻櫎鐨勫憳宸�");
+      return;
+    }
+    const ids = new Set(selectedEmployees.value.map(e => e.staffOnJobId || e.id));
+    employeeList.value = employeeList.value.filter(
+      e => !ids.has(e.staffOnJobId || e.id)
+    );
+  };
+
+  const handleGenerate = () => {
+    if (!form.value.deptIds?.length) {
+      proxy.$modal.msgWarning("璇峰厛閫夋嫨閮ㄩ棬");
+      return;
+    }
+    if (!form.value.salaryMonth) {
+      proxy.$modal.msgWarning("璇峰厛閫夋嫨宸ヨ祫鏈堜唤");
+      return;
+    }
+    const payload = {
+      ids: form.value.deptIds,
+      date: form.value.salaryMonth,
+    };
+    staffSalaryMainCalculateSalary(payload).then(res => {
+      const list = Array.isArray(res?.data) ? res.data : [];
+      if (!list.length) {
+        proxy.$modal.msgWarning("鏈绠楀埌宸ヨ祫鏁版嵁");
+        return;
+      }
+      employeeList.value = list.map(e => ({
+        ...e,
+        staffOnJobId: e.staffOnJobId ?? e.staffId ?? e.id,
+        staffName: e.staffName,
+        postName: e.postName,
+        deptName: e.deptName,
+        nation: e.nation ?? "",
+        basicSalary: parseNum(e.basicSalary),
+        dayDays: parseNum(e.dayDays ?? e.dayShiftDays),
+        nightDays: parseNum(e.nightDays ?? e.nightShiftDays),
+        mealAmount: parseNum(e.mealAmount ?? e.mealSubsidy),
+        nightAmount: parseNum(e.nightAmount ?? e.nightSubsidy),
+        otherIncome: parseNum(e.otherIncome),
+        socialPersonal: parseNum(e.socialPersonal),
+        fundPersonal: parseNum(e.fundPersonal),
+        otherDeduct: parseNum(e.otherDeduct),
+        socialSecurityRetroactive: parseNum(e.socialSecurityRetroactive),
+        salaryTax: parseNum(e.salaryTax),
+        grossSalary: parseNum(e.grossSalary),
+        deductSalary: parseNum(e.deductSalary),
+        netSalary: parseNum(e.netSalary),
+        remark: e.remark ?? "",
+      }));
+      proxy.$modal.msgSuccess("鐢熸垚鎴愬姛");
+    });
+  };
+
+  const handleClear = () => {
+    proxy.$modal
+      .confirm("纭畾娓呯┖褰撳墠鍛樺伐鍒楄〃鍚楋紵")
+      .then(() => {
+        employeeList.value = [];
+      })
+      .catch(() => {});
+  };
+
+  const handleTaxForm = () => {
+    taxDialogVisible.value = true;
+  };
+
+  const submitForm = () => {
+    formRef.value?.validate(valid => {
+      if (!valid) return;
+      saveData(3); // 纭鎻愪氦锛岀姸鎬佷负3锛堝緟瀹℃牳锛�
+    });
+  };
+
+  const saveDraft = () => {
+    formRef.value?.validate(valid => {
+      if (!valid) return;
+      saveData(1); // 淇濆瓨鑽夌锛岀姸鎬佷负1锛堣崏绋匡級
+    });
+  };
+
+  const saveData = status => {
+    const payload = {
+      id: form.value.id,
+      salaryTitle: form.value.salaryTitle,
+      deptIds: form.value.deptIds?.length ? form.value.deptIds.join(",") : "",
+      salaryMonth: form.value.salaryMonth,
+      remark: form.value.remark,
+      payBank: form.value.payBank,
+      auditUserId: form.value.auditUserId,
+      auditUserName: auditUserName.value,
+      totalSalary: totalSalary.value,
+      staffSalaryDetailList: employeeList.value.map(e => ({
+        staffOnJobId: e.staffOnJobId ?? e.staffId ?? e.id,
+        staffName: e.staffName,
+        postName: e.postName ?? "",
+        deptName: e.deptName ?? "",
+        nation: e.nation ?? "",
+        basicSalary: parseNum(e.basicSalary),
+        dayDays: parseNum(e.dayDays),
+        nightDays: parseNum(e.nightDays),
+        mealAmount: parseNum(e.mealAmount),
+        nightAmount: parseNum(e.nightAmount),
+        otherIncome: parseNum(e.otherIncome),
+        socialPersonal: parseNum(e.socialPersonal),
+        fundPersonal: parseNum(e.fundPersonal),
+        otherDeduct: parseNum(e.otherDeduct),
+        socialSecurityRetroactive: parseNum(e.socialSecurityRetroactive),
+        salaryTax: parseNum(e.salaryTax),
+        grossSalary: parseNum(e.grossSalary),
+        deductSalary: parseNum(e.deductSalary),
+        netSalary: parseNum(e.netSalary),
+        remark: e.remark ?? "",
+      })),
+    };
+    if (props.operationType === "add") {
+      staffSalaryMainAdd({ ...payload, status }).then(() => {
+        proxy.$modal.msgSuccess(status === 1 ? "鑽夌淇濆瓨鎴愬姛" : "鎻愪氦鎴愬姛");
+        closeDia();
+      });
+    } else {
+      staffSalaryMainUpdate({ ...payload, status }).then(() => {
+        proxy.$modal.msgSuccess(status === 1 ? "鑽夌淇濆瓨鎴愬姛" : "鎻愪氦鎴愬姛");
+        closeDia();
+      });
+    }
+  };
+
+  const closeDia = () => {
+    dialogVisible.value = false;
+    emit("close");
+  };
+
+  defineExpose({ openDialog });
 </script>
 
 <style scoped>
-.form-dia-body {
-  padding: 0;
-}
-.card-title-line {
-  color: #f56c6c;
-  margin-right: 4px;
-}
-.form-card {
-  margin-bottom: 16px;
-}
-.form-card :deep(.el-card__header) {
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  padding: 12px 16px;
-}
-.card-title {
-  font-weight: 500;
-}
-.card-collapse {
-  color: #999;
-  cursor: pointer;
-}
-.toolbar {
-  margin-bottom: 16px;
-  display: flex;
-  flex-wrap: wrap;
-  gap: 10px;
-}
-.employee-table-wrap {
-  position: relative;
-  min-height: 120px;
-}
-.table-empty {
-  text-align: center;
-  padding: 24px;
-  color: #999;
-  font-size: 14px;
-}
-.add-person-tree {
-  max-height: 360px;
-  overflow-y: auto;
-  padding: 8px 0;
-}
-.tax-desc {
-  margin-bottom: 12px;
-  font-size: 14px;
-  color: #606266;
-}
-.dialog-footer {
-  text-align: right;
-}
-.salary-total {
-  margin-top: 16px;
-  padding: 12px 16px;
-  background-color: #f5f7fa;
-  border-radius: 4px;
-  text-align: right;
-  font-size: 16px;
-}
-.salary-total .total-label {
-  color: #606266;
-  margin-right: 8px;
-}
-.salary-total .total-value {
-  color: #f56c6c;
-  font-weight: bold;
-  font-size: 18px;
-}
+  .form-dia-body {
+    padding: 0;
+  }
+  .card-title-line {
+    color: #f56c6c;
+    margin-right: 4px;
+  }
+  .form-card {
+    margin-bottom: 16px;
+  }
+  .form-card :deep(.el-card__header) {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 12px 16px;
+  }
+  .card-title {
+    font-weight: 500;
+  }
+  .card-collapse {
+    color: #999;
+    cursor: pointer;
+  }
+  .toolbar {
+    margin-bottom: 16px;
+    display: flex;
+    flex-wrap: wrap;
+    gap: 10px;
+  }
+  .employee-table-wrap {
+    position: relative;
+    min-height: 120px;
+  }
+  .table-empty {
+    text-align: center;
+    padding: 24px;
+    color: #999;
+    font-size: 14px;
+  }
+  .add-person-tree {
+    max-height: 360px;
+    overflow-y: auto;
+    padding: 8px 0;
+  }
+  .tax-desc {
+    margin-bottom: 12px;
+    font-size: 14px;
+    color: #606266;
+  }
+  .dialog-footer {
+    text-align: right;
+  }
+  .salary-total {
+    margin-top: 16px;
+    padding: 12px 16px;
+    background-color: #f5f7fa;
+    border-radius: 4px;
+    text-align: right;
+    font-size: 16px;
+  }
+  .salary-total .total-label {
+    color: #606266;
+    margin-right: 8px;
+  }
+  .salary-total .total-value {
+    color: #f56c6c;
+    font-weight: bold;
+    font-size: 18px;
+  }
 </style>
diff --git a/src/views/personnelManagement/subsidyConfig/index.vue b/src/views/personnelManagement/subsidyConfig/index.vue
new file mode 100644
index 0000000..17aae49
--- /dev/null
+++ b/src/views/personnelManagement/subsidyConfig/index.vue
@@ -0,0 +1,437 @@
+<template>
+  <div class="app-container subsidy-config-container">
+    <el-row :gutter="20">
+      <!-- 宸︿晶閰嶇疆琛ㄥ崟 -->
+      <el-col :span="16">
+        <el-card class="config-card"
+                 shadow="hover">
+          <template #header>
+            <div class="card-header">
+              <div class="header-title">
+                <el-icon class="header-icon">
+                  <Setting />
+                </el-icon>
+                <span>琛ヨ创鏍囧噯閰嶇疆</span>
+              </div>
+              <div class="header-ops">
+                <el-button type="primary"
+                           :loading="loading"
+                           @click="submitForm">
+                  <el-icon>
+                    <Check />
+                  </el-icon> 淇濆瓨閰嶇疆
+                </el-button>
+              </div>
+            </div>
+          </template>
+          <el-form ref="formRef"
+                   :model="form"
+                   :rules="rules"
+                   label-position="top"
+                   class="subsidy-form">
+            <div class="config-section">
+              <div class="section-title">
+                <el-icon>
+                  <Food />
+                </el-icon> 椁愯ˉ璁剧疆
+              </div>
+              <el-row :gutter="40">
+                <el-col :span="12">
+                  <el-form-item label="琛ヨ创鏍囧噯閲戦"
+                                style="margin-right:20px"
+                                prop="mealAmount">
+                    <el-input-number v-model="form.mealAmount"
+                                     :precision="2"
+                                     :step="1"
+                                     :min="0"
+                                     controls-position="right"
+                                     class="full-width-input" />
+                    <span class="input-unit">鍏�/澶�</span>
+                  </el-form-item>
+                </el-col>
+                <el-col :span="12">
+                  <div class="quick-info">
+                    <div class="info-item">
+                      <span class="label">閫傜敤瀵硅薄锛�</span>
+                      <el-tag size="small"
+                              type="warning">鍥炴棌鍛樺伐</el-tag>
+                    </div>
+                    <div class="info-item">
+                      <span class="label">璁$畻鑼冨洿锛�</span>
+                      <span>鐧界彮 + 澶滅彮</span>
+                    </div>
+                  </div>
+                </el-col>
+              </el-row>
+            </div>
+            <el-divider />
+            <div class="config-section">
+              <div class="section-title">
+                <el-icon>
+                  <Moon />
+                </el-icon> 澶滅彮琛ュ姪璁剧疆
+              </div>
+              <el-row :gutter="40">
+                <el-col :span="12">
+                  <el-form-item label="琛ュ姪鏍囧噯閲戦"
+                                style="margin-right:20px"
+                                prop="nightAmount">
+                    <el-input-number v-model="form.nightAmount"
+                                     :precision="2"
+                                     :step="1"
+                                     :min="0"
+                                     controls-position="right"
+                                     class="full-width-input" />
+                    <span class="input-unit">鍏�/澶�</span>
+                  </el-form-item>
+                </el-col>
+                <el-col :span="12">
+                  <div class="quick-info">
+                    <div class="info-item">
+                      <span class="label">閫傜敤瀵硅薄锛�</span>
+                      <el-tag size="small">鍏ㄥ憳锛堟帓鐝负澶滅彮锛�</el-tag>
+                    </div>
+                    <div class="info-item">
+                      <span class="label">璁$畻鑼冨洿锛�</span>
+                      <span>浠呴檺澶滅彮</span>
+                    </div>
+                  </div>
+                </el-col>
+              </el-row>
+            </div>
+          </el-form>
+        </el-card>
+        <!-- 璁$畻绀轰緥鍗$墖 -->
+        <el-card class="example-card"
+                 shadow="never">
+          <template #header>
+            <div class="card-header-small">
+              <el-icon>
+                <InfoFilled />
+              </el-icon>
+              <span>钖祫璁$畻閫昏緫璇存槑</span>
+            </div>
+          </template>
+          <div class="example-content">
+            <el-row :gutter="20">
+              <el-col :span="12">
+                <div class="example-box meal">
+                  <h5>椁愯ˉ璁$畻绀轰緥</h5>
+                  <p>鑻ユ爣鍑嗕负 <strong>{{ form.mealAmount }}鍏�/澶�</strong></p>
+                  <p>鏌愬洖鏃忓憳宸ワ細鐧界彮10澶╋紝澶滅彮10澶�</p>
+                  <div class="formula">
+                    璁$畻锛�(10 + 10) * {{ form.mealAmount }} = <span>{{ (20 * form.mealAmount).toFixed(2) }}鍏�</span>
+                  </div>
+                </div>
+              </el-col>
+              <el-col :span="12">
+                <div class="example-box night">
+                  <h5>澶滅彮琛ュ姪璁$畻绀轰緥</h5>
+                  <p>鑻ユ爣鍑嗕负 <strong>{{ form.nightAmount }}鍏�/澶�</strong></p>
+                  <p>鏌愬憳宸ワ細褰撴湀澶滅彮10澶�</p>
+                  <div class="formula">
+                    璁$畻锛�10 * {{ form.nightAmount }} = <span>{{ (10 * form.nightAmount).toFixed(2) }}鍏�</span>
+                  </div>
+                </div>
+              </el-col>
+            </el-row>
+          </div>
+        </el-card>
+      </el-col>
+      <!-- 鍙充晶瑙勫垯璇存槑 -->
+      <el-col :span="8">
+        <el-card class="rule-card"
+                 shadow="hover">
+          <template #header>
+            <div class="card-header">
+              <span>涓氬姟瑙勫垯璇︽儏</span>
+            </div>
+          </template>
+          <el-scrollbar height="500px">
+            <div class="rule-item">
+              <div class="rule-header">
+                <span class="dot warning"></span>
+                <h6>鍏充簬椁愯ˉ鐨勬爣鍑嗕笌鍙戞斁</h6>
+              </div>
+              <p>1. 绯荤粺灏嗚嚜鍔ㄨ瘑鍒憳宸ユ。妗堜腑鐨勩�愭皯鏃忋�戝瓧娈碉紝浠呭鏍囨敞涓衡�滃洖鏃忊�濈殑鍛樺伐璁$畻姝ら」琛ヨ创銆�</p>
+              <p>2. 鍙戞斁渚濇嵁浠ヨ�冨嫟绯荤粺涓殑瀹為檯鍑哄嫟澶╂暟涓哄噯锛屽寘鍚墍鏈夋甯哥彮娆★紙鐧界彮銆佸鐝級銆�</p>
+              <p>3. 璇峰亣銆佹椃宸ョ瓑闈炲嚭鍕ゅぉ鏁颁笉璁″叆璁$畻鑼冨洿銆�</p>
+            </div>
+            <el-divider />
+            <div class="rule-item">
+              <div class="rule-header">
+                <span class="dot primary"></span>
+                <h6>鍏充簬澶滅彮琛ュ姪鐨勬爣鍑嗕笌鍙戞斁</h6>
+              </div>
+              <p>1. 鍙鍛樺伐鐨勬帓鐝彮娆¤瀹氫箟涓衡�滃鐝�濓紝涓旀湁瀹為檯鍑哄嫟璁板綍锛屽嵆鍙韩鍙楁琛ュ姪銆�</p>
+              <p>2. 琛ュ姪鎸夊ぉ璁$畻锛屼笉鍖哄垎宀椾綅鑱岀骇锛岀粺涓�鎵ц姝ゆ爣鍑嗛厤缃��</p>
+              <p>3. 姝よˉ鍔╀笌椁愯ˉ鍙悓鏃朵韩鍙楋紙鑻ョ鍚堥琛ユ潯浠讹級銆�</p>
+            </div>
+            <el-alert title="閰嶇疆鐢熸晥璇存槑"
+                      type="info"
+                      :closable="false"
+                      show-icon
+                      style="margin-top: 20px">
+              淇敼鍚庣殑鏍囧噯灏嗗湪涓嬩竴娆℃墽琛屸�滃伐璧勭粨绠椻�濅换鍔℃椂姝e紡鐢熸晥锛屼笉浼氬奖鍝嶅凡缁撶畻鐨勫巻鍙茶柂璧勬暟鎹��
+            </el-alert>
+          </el-scrollbar>
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup name="SubsidyConfig">
+  import { ref, onMounted } from "vue";
+  import {
+    Setting,
+    Check,
+    RefreshRight,
+    Food,
+    Moon,
+    InfoFilled,
+  } from "@element-plus/icons-vue";
+  import {
+    listSubsidyConfiguration,
+    saveSubsidyConfiguration,
+  } from "@/api/personnelManagement/subsidyConfig.js";
+  import { ElMessage, ElMessageBox } from "element-plus";
+
+  const formRef = ref(null);
+  const loading = ref(false);
+
+  const form = ref({
+    id: undefined,
+    mealAmount: 0,
+    nightAmount: 0,
+    tenantId: undefined,
+    createTime: undefined,
+  });
+
+  const rules = {
+    mealAmount: [{ required: true, message: "璇疯緭鍏ラ琛ユ爣鍑�", trigger: "blur" }],
+    nightAmount: [
+      { required: true, message: "璇疯緭鍏ュ鐝ˉ鍔╂爣鍑�", trigger: "blur" },
+    ],
+  };
+
+  /** 鏌ヨ閰嶇疆 */
+  const getConfig = async () => {
+    try {
+      const res = await listSubsidyConfiguration();
+      if (res.data && res.data.length > 0) {
+        const config = res.data[0];
+        form.value = {
+          id: config.id,
+          mealAmount: config.mealAmount || 0,
+          nightAmount: config.nightAmount || 0,
+          tenantId: config.tenantId,
+          createTime: config.createTime,
+        };
+      }
+    } catch (error) {
+      console.error("鑾峰彇閰嶇疆澶辫触", error);
+    }
+  };
+
+  /** 鎻愪氦琛ㄥ崟 */
+  const submitForm = async () => {
+    if (!formRef.value) return;
+
+    await formRef.value.validate(async valid => {
+      if (valid) {
+        loading.value = true;
+        try {
+          await saveSubsidyConfiguration(form.value);
+          ElMessage.success("鏍囧噯閰嶇疆宸叉洿鏂�");
+          getConfig(); // 閲嶆柊鍔犺浇浠ヨ幏鍙栧彲鑳界殑鏇存柊锛堝id锛�
+        } catch (error) {
+          console.error("淇濆瓨澶辫触", error);
+        } finally {
+          loading.value = false;
+        }
+      }
+    });
+  };
+
+  onMounted(() => {
+    getConfig();
+  });
+</script>
+
+<style scoped lang="scss">
+  .subsidy-config-container {
+    padding: 20px;
+    background-color: #f5f7fa;
+    min-height: calc(100vh - 84px);
+
+    .config-card {
+      margin-bottom: 20px;
+      border-radius: 8px;
+
+      .card-header {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+
+        .header-title {
+          display: flex;
+          align-items: center;
+          font-size: 18px;
+          font-weight: 600;
+          color: #303133;
+
+          .header-icon {
+            margin-right: 8px;
+            color: #409eff;
+          }
+        }
+      }
+    }
+
+    .subsidy-form {
+      padding: 10px 20px;
+
+      .config-section {
+        .section-title {
+          display: flex;
+          align-items: center;
+          gap: 8px;
+          font-size: 16px;
+          font-weight: 500;
+          margin-bottom: 20px;
+          color: #606266;
+
+          .el-icon {
+            color: #409eff;
+          }
+        }
+      }
+
+      .full-width-input {
+        width: 100% !important;
+      }
+
+      .input-unit {
+        position: absolute;
+        right: -45px;
+        top: 0;
+        color: #909399;
+        font-size: 14px;
+      }
+
+      .quick-info {
+        background: #fdf6ec;
+        border-radius: 4px;
+        padding: 15px;
+        height: 100%;
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        gap: 10px;
+
+        .info-item {
+          font-size: 14px;
+          color: #666;
+          .label {
+            font-weight: 500;
+          }
+        }
+      }
+    }
+
+    .example-card {
+      background: #fff;
+      border: 1px dashed #dcdfe6;
+
+      .card-header-small {
+        display: flex;
+        align-items: center;
+        gap: 6px;
+        font-size: 14px;
+        color: #909399;
+      }
+
+      .example-box {
+        padding: 15px;
+        border-radius: 6px;
+
+        h5 {
+          margin: 0 0 10px 0;
+          font-size: 14px;
+          color: #303133;
+        }
+
+        p {
+          margin: 5px 0;
+          font-size: 13px;
+          color: #606266;
+        }
+
+        .formula {
+          margin-top: 10px;
+          padding-top: 10px;
+          border-top: 1px solid rgba(0, 0, 0, 0.05);
+          font-size: 13px;
+          font-weight: bold;
+
+          span {
+            color: #f56c6c;
+            font-size: 16px;
+          }
+        }
+
+        &.meal {
+          background-color: #f0f9eb;
+        }
+        &.night {
+          background-color: #ecf5ff;
+        }
+      }
+    }
+
+    .rule-card {
+      height: 100%;
+
+      .rule-item {
+        padding: 5px 0;
+
+        .rule-header {
+          display: flex;
+          align-items: center;
+          gap: 8px;
+          margin-bottom: 10px;
+
+          .dot {
+            width: 8px;
+            height: 8px;
+            border-radius: 50%;
+            &.warning {
+              background: #e6a23c;
+            }
+            &.primary {
+              background: #409eff;
+            }
+          }
+
+          h6 {
+            margin: 0;
+            font-size: 15px;
+            color: #303133;
+          }
+        }
+
+        p {
+          font-size: 13px;
+          line-height: 1.8;
+          color: #606266;
+          margin: 5px 0 5px 16px;
+        }
+      }
+    }
+  }
+
+  :deep(.el-divider--horizontal) {
+    margin: 24px 0;
+  }
+</style>

--
Gitblit v1.9.3