From 80367ddf4383493729420bb62aa8c8ebb9616dd9 Mon Sep 17 00:00:00 2001
From: zouyu <2723363702@qq.com>
Date: 星期日, 04 一月 2026 16:54:04 +0800
Subject: [PATCH] 代码调整9

---
 src/views/contractor/compliance/components/formDia.vue |  225 +++++
 src/views/contractor/evaluateTemplate/index.vue        |  235 +++++
 src/views/contractor/assets/Form.vue                   |  215 ++++
 src/views/contractor/evaluateTemplate/Modal.vue        |   71 +
 src/views/contractor/assets/index.vue                  |  864 ++++++-------------
 src/views/contractor/assets/Modal.vue                  |   70 +
 src/views/contractor/evaluateTemplate/Form.vue         |  104 ++
 src/views/contractor/compliance/index.vue              |  843 ++++--------------
 8 files changed, 1,399 insertions(+), 1,228 deletions(-)

diff --git a/src/views/contractor/assets/Form.vue b/src/views/contractor/assets/Form.vue
new file mode 100644
index 0000000..3dd4fbc
--- /dev/null
+++ b/src/views/contractor/assets/Form.vue
@@ -0,0 +1,215 @@
+<template>
+  <el-form :model="form" label-width="120px" :rules="formRules" ref="formRef">
+    <el-row :gutter="20">
+      <el-col :span="12">
+        <el-form-item label="椤圭洰鍚嶇О" prop="deviceName">
+          <el-input v-model="form.deviceName" placeholder="璇疯緭鍏ラ」鐩悕绉�" />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="鍚堝悓缂栧彿" prop="deviceModel">
+          <el-input v-model="form.deviceModel" :disabled="(form.deviceModel != null && operationType === 'edit')" placeholder="璇疯緭鍏ュ悎鍚岀紪鍙�" />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="鎵垮寘鍟�" prop="supplierName">
+          <el-select v-model="form.supplierName" placeholder="璇烽�夋嫨" clearable style="width: 100%">
+            <el-option v-for="item in customerDataList" :key="item.id" :label="item.customerName + '(' + item.taxpayerIdentificationNumber + ')'" :value="item.customerName"/>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="浠樻鏂瑰紡	" prop="unit">
+          <el-select v-model="form.unit" placeholder="璇烽�夋嫨" clearable style="width: 100%">
+            <el-option v-for="item in payMethods" :key="item.id" :label="item.label" :value="item.value"/>
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="鏁伴噺" prop="number">
+          <el-input-number :step="1" :min="0" style="width: 100%"
+                           v-model="form.number"
+                           placeholder="璇疯緭鍏ユ暟閲�"
+                           @change="mathNum"
+          />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="鍚◣鍗曚环" prop="taxIncludingPriceUnit">
+          <el-input-number :step="0.01" :min="0" style="width: 100%"
+                           v-model="form.taxIncludingPriceUnit"
+                           placeholder="璇疯緭鍏ュ惈绋庡崟浠�"
+                           maxlength="10"
+                           @change="mathNum"
+          />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="鍚◣鎬讳环" prop="taxIncludingPriceTotal">
+          <el-input
+              v-model="form.taxIncludingPriceTotal"
+              placeholder="鑷姩鐢熸垚"
+              type="number"
+              disabled
+          />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="绋庣巼(%)" prop="taxRate">
+          <el-select
+              v-model="form.taxRate"
+              placeholder="璇烽�夋嫨"
+              clearable
+              @change="mathNum"
+          >
+            <el-option label="1" :value="1" />
+            <el-option label="6" :value="6" />
+            <el-option label="13" :value="13" />
+          </el-select>
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="涓嶅惈绋庢�讳环" prop="unTaxIncludingPriceTotal">
+          <el-input
+              v-model="form.unTaxIncludingPriceTotal"
+              placeholder="鑷姩鐢熸垚"
+              type="number"
+              disabled
+          />
+        </el-form-item>
+      </el-col>
+      <!-- <el-col :span="12">
+        <el-form-item label="褰曞叆浜�" prop="createUser">
+          <el-input v-model="form.createUser" placeholder="璇疯緭鍏ュ綍鍏ヤ汉" />
+        </el-form-item>
+      </el-col> -->
+      <el-col :span="12">
+        <el-form-item label="褰曞叆鏃ユ湡" prop="createTime">
+          <el-date-picker
+              style="width: 100%"
+              v-model="form.createTime"
+              format="YYYY-MM-DD"
+              value-format="YYYY-MM-DD HH:mm:ss"
+              type="date"
+              placeholder="璇烽�夋嫨褰曞叆鏃ユ湡"
+              clearable
+          />
+        </el-form-item>
+      </el-col>
+    </el-row>
+  </el-form>
+</template>
+
+<script setup>
+import useFormData from "@/hooks/useFormData";
+import {customerList} from "@/api/salesManagement/salesLedger.js";
+import { getLedgerById } from "@/api/equipmentManagement/ledger";
+import dayjs from "dayjs";
+import {
+  calculateTaxIncludeTotalPrice,
+  calculateTaxExclusiveTotalPrice,
+} from "@/utils/summarizeTable";
+import { ElMessage } from "element-plus";
+import {ref,onMounted} from "vue";
+
+defineOptions({
+  name: "璁惧鍙拌处琛ㄥ崟",
+});
+const formRef = ref(null);
+const customerDataList = ref([])
+const operationType = ref('');
+const payMethods = [
+  { value: '鎸夋湀缁撶畻', label: '鎸夋湀缁撶畻' },
+  { value: '鎸夎繘搴︿粯娆�', label: '鎸夎繘搴︿粯娆�' },
+  { value: '涓�娆℃�ф敮浠�', label: '涓�娆℃�ф敮浠�' },
+  { value: '鍏朵粬', label: '鍏朵粬' },
+];
+const formRules = {
+  deviceName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
+  deviceModel: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
+  supplierName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
+  unit: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
+  number: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
+  taxIncludingPriceUnit: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
+  taxRate: [{ required: true, trigger: "change", message: "璇疯緭鍏�" }],
+}
+
+const { form, resetForm } = useFormData({
+  deviceName: undefined, // 璁惧鍚嶇О
+  deviceModel: undefined, // 瑙勬牸鍨嬪彿
+  supplierName: undefined, // 渚涘簲鍟�
+  unit: undefined, // 鍗曚綅
+  number: undefined, // 鏁伴噺
+  taxIncludingPriceUnit: undefined, // 鍚◣鍗曚环
+  taxIncludingPriceTotal: undefined, // 鍚◣鎬讳环
+  taxRate: undefined, // 绋庣巼
+  unTaxIncludingPriceTotal: undefined, // 涓嶅惈绋庢�讳环
+  // createUser: useUserStore().nickName, // 褰曞叆浜�
+  createTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), // 褰曞叆鏃ユ湡
+});
+
+const loadForm = async (id) => {
+  if (id) {
+    operationType.value = 'edit'
+  }
+  const { code, data } = await getLedgerById(id);
+  if (code == 200) {
+    form.deviceName = data.deviceName;
+    form.deviceModel = data.deviceModel;
+    form.supplierName = data.supplierName;
+    form.unit = data.unit;
+    form.number = data.number;
+    form.taxIncludingPriceUnit = data.taxIncludingPriceUnit;
+    form.taxIncludingPriceTotal = data.taxIncludingPriceTotal;
+    form.taxRate = data.taxRate;
+    form.unTaxIncludingPriceTotal = data.unTaxIncludingPriceTotal;
+    form.createTime = data.createTime;
+  }
+};
+
+const mathNum = () => {
+  if (!form.taxIncludingPriceUnit) {
+    ElMessage.error("璇疯緭鍏ュ崟浠�");
+    return;
+  }
+  if (!form.number) {
+    ElMessage.error("璇疯緭鍏ユ暟閲�");
+    return;
+  }
+  form.taxIncludingPriceTotal = calculateTaxIncludeTotalPrice(
+      form.taxIncludingPriceUnit,
+      form.number
+  );
+  if (form.taxRate) {
+    form.unTaxIncludingPriceTotal = calculateTaxExclusiveTotalPrice(
+        form.taxIncludingPriceTotal,
+        form.taxRate
+    );
+  }
+};
+
+// 娓呴櫎琛ㄥ崟鏍¢獙鐘舵��
+const clearValidate = () => {
+  formRef.value?.clearValidate();
+};
+
+// 閲嶇疆琛ㄥ崟鏁版嵁鍜屾牎楠岀姸鎬�
+const resetFormAndValidate = () => {
+  resetForm();
+  clearValidate();
+};
+
+defineExpose({
+  form,
+  loadForm,
+  resetForm,
+  clearValidate,
+  resetFormAndValidate,
+  formRef,
+});
+onMounted(() => {
+  customerList().then(res=>{
+    customerDataList.value = res
+  })
+});
+</script>
diff --git a/src/views/contractor/assets/Modal.vue b/src/views/contractor/assets/Modal.vue
new file mode 100644
index 0000000..f907d4f
--- /dev/null
+++ b/src/views/contractor/assets/Modal.vue
@@ -0,0 +1,70 @@
+<template>
+  <el-dialog :title="modalOptions.title" v-model="visible" @close="close">
+    <Form ref="formRef"></Form>
+    <template #footer>
+      <el-button type="primary" @click="sendForm" :loading="loading">
+        {{ modalOptions.confirmText }}
+      </el-button>
+      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup>
+import { useModal } from "@/hooks/useModal";
+import { addLedger, editLedger } from "@/api/equipmentManagement/ledger";
+import Form from "./Form.vue";
+import { ElMessage } from "element-plus";
+const { proxy } = getCurrentInstance()
+
+defineOptions({
+  name: "璁惧鍙拌处鏂板缂栬緫",
+});
+
+const emits = defineEmits(["success"]);
+
+const formRef = ref();
+const {
+  id,
+  visible,
+  loading,
+  openModal,
+  modalOptions,
+  customOptions,
+  handleConfirm,
+  closeModal,
+} = useModal({ title: "椤圭洰鍙拌处" });
+
+const sendForm = () => {
+  proxy.$refs.formRef.$refs.formRef.validate(async valid => {
+    if (valid) {
+      const {code} = id.value
+          ? await editLedger({id: id.value, ...formRef.value.form})
+          : await addLedger(formRef.value.form);
+      if (code == 200) {
+        emits("success");
+        ElMessage({message: "鎿嶄綔鎴愬姛", type: "success"});
+        close();
+      } else {
+        loading.value = false;
+      }
+    }
+  })
+};
+
+const close = () => {
+  formRef.value.resetFormAndValidate();
+  closeModal();
+};
+
+const loadForm = async (id) => {
+  openModal(id);
+  await nextTick();
+  formRef.value.loadForm(id);
+};
+
+defineExpose({
+  openModal,
+  loadForm,
+});
+</script>
diff --git a/src/views/contractor/assets/index.vue b/src/views/contractor/assets/index.vue
index ad8a641..d4072a9 100644
--- a/src/views/contractor/assets/index.vue
+++ b/src/views/contractor/assets/index.vue
@@ -1,637 +1,301 @@
 <template>
   <div class="app-container">
-    <el-form
-      :model="queryParams"
-      ref="queryRef"
-      :inline="true"
-      v-show="showSearch"
-      label-width="90px"
-    >
-      <el-form-item label="璧勪骇鍚嶇О" prop="assetName">
+    <el-form :model="filters" :inline="true">
+      <el-form-item label="椤圭洰鍚嶇О">
         <el-input
-          v-model="queryParams.assetName"
-          placeholder="璇疯緭鍏ヨ祫浜у悕绉�"
-          clearable
-          style="width: 220px"
-          @keyup.enter="handleQuery"
+            v-model="filters.deviceName"
+            style="width: 240px"
+            placeholder="璇疯緭鍏ラ」鐩悕绉�"
+            clearable
+            :prefix-icon="Search"
+            @change="getTableData"
         />
       </el-form-item>
-      <el-form-item label="璧勪骇缂栧彿" prop="assetCode">
+      <el-form-item label="鍚堝悓缂栧彿">
         <el-input
-          v-model="queryParams.assetCode"
-          placeholder="璇疯緭鍏ヨ祫浜х紪鍙�"
-          clearable
-          style="width: 240px"
-          @keyup.enter="handleQuery"
+            v-model="filters.deviceModel"
+            style="width: 240px"
+            placeholder="璇疯緭鍏ュ悎鍚岀紪鍙�"
+            clearable
+            :prefix-icon="Search"
+            @change="getTableData"
         />
       </el-form-item>
-      <el-form-item label="鎵�灞炴壙鍖呭晢" prop="contractorId">
-        <el-select
-          v-model="queryParams.contractorId"
-          placeholder="璇烽�夋嫨鎵垮寘鍟�"
-          clearable
-          style="width: 240px"
-        >
-          <el-option
-            v-for="contractor in contractorOptions"
-            :key="contractor.contractorId"
-            :label="contractor.contractorName"
-            :value="contractor.contractorId"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="璧勪骇鐘舵��" prop="status">
-        <el-select
-          v-model="queryParams.status"
-          placeholder="璧勪骇鐘舵��"
-          clearable
-          style="width: 240px"
-        >
-          <el-option
-            v-for="dict in asset_status"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
-        </el-select>
+      <el-form-item label="褰曞叆鏃ユ湡:">
+        <el-date-picker v-model="filters.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
+                        placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
       </el-form-item>
       <el-form-item>
-        <el-button type="primary" icon="Search" @click="handleQuery"
-          >鎼滅储</el-button
-        >
-        <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
+        <el-button type="primary" @click="getTableData">鎼滅储</el-button>
+        <el-button @click="resetFilters">閲嶇疆</el-button>
       </el-form-item>
     </el-form>
-
-    <el-row :gutter="10" class="mb8">
-      <el-col :span="1.5">
-        <el-button
-          type="primary"
-          plain
-          icon="Plus"
-          @click="handleAdd"
-          >鏂板</el-button
-        >
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="success"
-          plain
-          icon="Edit"
-          :disabled="single"
-          @click="handleUpdate"
-          >淇敼</el-button
-        >
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="danger"
-          plain
-          icon="Delete"
-          :disabled="multiple"
-          @click="handleDelete"
-          >鍒犻櫎</el-button
-        >
-      </el-col>
-      <right-toolbar
-        v-model:showSearch="showSearch"
-        @queryTable="getList"
-        :columns="columns"
-      ></right-toolbar>
-    </el-row>
-
-    <el-table
-      v-loading="loading"
-      :data="assetList"
-      @selection-change="handleSelectionChange"
-      stripe
-    >
-      <el-table-column type="selection" width="50" align="center" />
-      <el-table-column
-        label="璧勪骇缂栧彿"
-        align="center"
-        key="assetId"
-        prop="assetId"
-        v-if="columns[0].visible"
-      />
-      <el-table-column
-        label="璧勪骇鍚嶇О"
-        align="center"
-        key="assetName"
-        prop="assetName"
-        v-if="columns[1].visible"
-        :show-overflow-tooltip="true"
-      />
-      <el-table-column
-        label="璧勪骇缂栧彿"
-        align="center"
-        key="assetCode"
-        prop="assetCode"
-        v-if="columns[2].visible"
-      />
-      <el-table-column
-        label="鎵�灞炴壙鍖呭晢"
-        align="center"
-        key="contractorName"
-        prop="contractorName"
-        v-if="columns[3].visible"
-        :show-overflow-tooltip="true"
-      />
-      <el-table-column
-        label="璧勪骇绫诲瀷"
-        align="center"
-        key="assetType"
-        prop="assetType"
-        v-if="columns[4].visible"
-      >
-        <template #default="scope">
-          {{ getAssetTypeLabel(scope.row.assetType) }}
-        </template>
-      </el-table-column>
-      <el-table-column
-        label="璧勪骇浠峰��"
-        align="center"
-        key="assetValue"
-        prop="assetValue"
-        v-if="columns[5].visible"
-      >
-        <template #default="scope">
-          {{ scope.row.assetValue.toFixed(2) }}
-        </template>
-      </el-table-column>
-      <el-table-column
-        label="鐘舵��"
-        align="center"
-        key="status"
-        v-if="columns[6].visible"
-      >
-        <template #default="scope">
-          <el-switch
-            v-model="scope.row.status"
-            active-value="0"
-            inactive-value="1"
-            @change="handleStatusChange(scope.row)"
-          ></el-switch>
-        </template>
-      </el-table-column>
-      <el-table-column
-        label="鍒涘缓鏃堕棿"
-        align="center"
-        prop="createTime"
-        v-if="columns[7].visible"
-        width="160"
-      >
-        <template #default="scope">
-          <span>{{ parseTime(scope.row.createTime) }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column
-        label="鎿嶄綔"
-        align="center"
-        width="150"
-        class-name="small-padding fixed-width"
-      >
-        <template #default="scope">
-          <el-tooltip
-            content="淇敼"
-            placement="top"
-          >
-            <el-button
-              link
-              type="primary"
-              icon="Edit"
-              @click="handleUpdate(scope.row)"
-            ></el-button>
-          </el-tooltip>
-          <el-tooltip
-            content="鍒犻櫎"
-            placement="top"
-          >
-            <el-button
-              link
-              type="primary"
+    <div class="table_list">
+      <div class="actions">
+        <div></div>
+        <div>
+          <el-button type="primary" @click="add" icon="Plus"> 鏂板 </el-button>
+          <el-button
+              type="danger"
               icon="Delete"
-              @click="handleDelete(scope.row)"
-            ></el-button>
-          </el-tooltip>
-        </template>
-      </el-table-column>
-    </el-table>
-    <pagination
-      v-show="total > 0"
-      :total="total"
-      v-model:page="queryParams.pageNum"
-      v-model:limit="queryParams.pageSize"
-      @pagination="getList"
-    />
-
-    <!-- 娣诲姞鎴栦慨鏀硅祫浜ч厤缃璇濇 -->
-    <el-dialog :title="title" v-model="open" width="600px" append-to-body>
-      <el-form :model="form" :rules="rules" ref="assetRef" label-width="80px">
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="璧勪骇鍚嶇О" prop="assetName">
-              <el-input
-                v-model="form.assetName"
-                placeholder="璇疯緭鍏ヨ祫浜у悕绉�"
-                maxlength="50"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="璧勪骇缂栧彿" prop="assetCode">
-              <el-input
-                v-model="form.assetCode"
-                placeholder="璇疯緭鍏ヨ祫浜х紪鍙�"
-                maxlength="20"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="鎵�灞炴壙鍖呭晢" prop="contractorId">
-              <el-select
-                v-model="form.contractorId"
-                placeholder="璇烽�夋嫨鎵垮寘鍟�"
-                clearable
-              >
-                <el-option
-                  v-for="contractor in contractorOptions"
-                  :key="contractor.contractorId"
-                  :label="contractor.contractorName"
-                  :value="contractor.contractorId"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="璧勪骇绫诲瀷" prop="assetType">
-              <el-select
-                v-model="form.assetType"
-                placeholder="璇烽�夋嫨璧勪骇绫诲瀷"
-                clearable
-              >
-                <el-option
-                  v-for="type in asset_types"
-                  :key="type.value"
-                  :label="type.label"
-                  :value="type.value"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="璧勪骇浠峰��" prop="assetValue">
-              <el-input
-                v-model="form.assetValue"
-                placeholder="璇疯緭鍏ヨ祫浜т环鍊�"
-                type="number"
-                step="0.01"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鐘舵��">
-              <el-radio-group v-model="form.status">
-                <el-radio
-                  v-for="dict in sys_normal_disable"
-                  :key="dict.value"
-                  :value="dict.value"
-                  >{{ dict.label }}</el-radio
-                >
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="澶囨敞">
-              <el-input
-                v-model="form.remark"
-                type="textarea"
-                placeholder="璇疯緭鍏ュ唴瀹�"
-              ></el-input>
-            </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="cancel">鍙� 娑�</el-button>
+              :disabled="multipleList.length <= 0"
+              @click="deleteRow(multipleList.map((item) => item.id))"
+          >
+            鎵归噺鍒犻櫎
+          </el-button>
         </div>
-      </template>
+      </div>
+      <PIMTable
+          rowKey="id"
+          isSelection
+          :column="columns"
+          :tableData="dataList"
+          :page="{
+          current: pagination.currentPage,
+          size: pagination.pageSize,
+          total: pagination.total,
+        }"
+          :isShowSummary="true"
+          :summaryMethod="summaryMethod"
+          @selection-change="handleSelectionChange"
+          @pagination="changePage"
+      >
+      </PIMTable>
+    </div>
+    <Modal ref="modalRef" @success="getTableData"></Modal>
+    <el-dialog v-model="qrDialogVisible" title="浜岀淮鐮�" width="300px">
+      <div style="text-align:center;">
+        <img :src="qrCodeUrl" alt="浜岀淮鐮�" style="width:200px;height:200px;" />
+        <div style="margin:10px 0;">
+          <el-button type="primary" @click="downloadQRCode">涓嬭浇浜岀淮鐮佸浘鐗�</el-button>
+        </div>
+      </div>
     </el-dialog>
   </div>
 </template>
 
-<script setup name="ContractorAssets">
-import { ref, reactive, toRefs, watch, onMounted } from 'vue';
-import { ElMessage } from 'element-plus';
-import { parseTime } from '@/utils/ruoyi';
+<script setup>
+import { usePaginationApi } from "@/hooks/usePaginationApi";
+import { getLedgerPage, delLedger } from "@/api/equipmentManagement/ledger";
+import { onMounted, getCurrentInstance } from "vue";
+import Modal from "./Modal.vue";
+import { ElMessageBox, ElMessage } from "element-plus";
+import dayjs from "dayjs";
+import QRCode from "qrcode";
+import { ref } from "vue";
+import { summarizeTable } from "@/utils/summarizeTable";
+import {Search} from "@element-plus/icons-vue";
 
-const assetList = ref([]);
-const open = ref(false);
-const loading = ref(true);
-const showSearch = ref(true);
-const ids = ref([]);
-const single = ref(true);
-const multiple = ref(true);
-const total = ref(0);
-const title = ref("");
-
-// 鍒楁樉闅愪俊鎭�
-const columns = ref([
-  { key: 0, label: `璧勪骇缂栧彿`, visible: true },
-  { key: 1, label: `璧勪骇鍚嶇О`, visible: true },
-  { key: 2, label: `璧勪骇缂栧彿`, visible: true },
-  { key: 3, label: `鎵�灞炴壙鍖呭晢`, visible: true },
-  { key: 4, label: `璧勪骇绫诲瀷`, visible: true },
-  { key: 5, label: `璧勪骇浠峰�糮, visible: true },
-  { key: 6, label: `鐘舵�乣, visible: true },
-  { key: 7, label: `鍒涘缓鏃堕棿`, visible: true },
-]);
-
-const data = reactive({
-  form: {
-    assetId: undefined,
-    assetName: undefined,
-    assetCode: undefined,
-    contractorId: undefined,
-    contractorName: undefined,
-    assetType: undefined,
-    assetValue: 0,
-    status: "0",
-    remark: undefined,
-  },
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
-    assetName: undefined,
-    assetCode: undefined,
-    contractorId: undefined,
-    status: undefined,
-  },
-  rules: {
-    assetName: [
-      { required: true, message: "璧勪骇鍚嶇О涓嶈兘涓虹┖", trigger: "blur" },
-    ],
-    assetCode: [
-      { required: true, message: "璧勪骇缂栧彿涓嶈兘涓虹┖", trigger: "blur" },
-    ],
-    contractorId: [
-      { required: true, message: "鎵�灞炴壙鍖呭晢涓嶈兘涓虹┖", trigger: "blur" },
-    ],
-    assetType: [
-      { required: true, message: "璧勪骇绫诲瀷涓嶈兘涓虹┖", trigger: "blur" },
-    ],
-    assetValue: [
-      { required: true, message: "璧勪骇浠峰�间笉鑳戒负绌�", trigger: "blur" },
-      { type: "number", message: "璇疯緭鍏ユ纭殑鏁板瓧", trigger: "blur" },
-    ],
-  },
+defineOptions({
+  name: "璁惧鍙拌处",
 });
 
-const { queryParams, form, rules } = toRefs(data);
+// 琛ㄦ牸澶氶�夋閫変腑椤�
+const multipleList = ref([]);
+const { proxy } = getCurrentInstance();
+const modalRef = ref();
+const qrDialogVisible = ref(false);
+const qrCodeUrl = ref("");
+const qrRowData = ref(null);
 
-// 妯℃嫙鎵垮寘鍟嗘暟鎹�
-const contractorOptions = ref([
-  { contractorId: 1, contractorName: "鍖椾含寤哄伐闆嗗洟" },
-  { contractorId: 2, contractorName: "涓婃捣鍩庡缓闆嗗洟" },
-  { contractorId: 3, contractorName: "骞垮窞寤虹瓚闆嗗洟" },
-  { contractorId: 4, contractorName: "娣卞湷寤哄伐闆嗗洟" },
-  { contractorId: 5, contractorName: "鏉窞寤哄伐闆嗗洟" },
-]);
+const {
+  filters,
+  columns,
+  dataList,
+  pagination,
+  getTableData,
+  resetFilters,
+  onCurrentChange,
+} = usePaginationApi(
+    getLedgerPage,
+    {
+      deviceName: undefined,
+      deviceModel: undefined,
+      supplierName: undefined,
+      unit: undefined,
+      entryDateStart: undefined,
+      entryDateEnd: undefined,
+    },
+    [
+      {
+        label: "椤圭洰鍚嶇О",
+        align: "center",
+        prop: "deviceName",
+      },
+      {
+        label: "鍚堝悓缂栧彿",
+        align: "center",
+        prop: "deviceModel",
+      },
+      {
+        label: "鎵垮寘鍟�",
+        align: "center",
+        prop: "supplierName",
+      },
+      {
+        label: "浠樻鏂瑰紡",
+        align: "center",
+        prop: "unit",
+      },
+      {
+        label: "鏁伴噺",
+        align: "center",
+        prop: "number",
+      },
+      {
+        label: "鍚◣鍗曚环",
+        align: "center",
+        prop: "taxIncludingPriceUnit",
+      },
+      {
+        label: "鍚◣鎬讳环",
+        align: "center",
+        prop: "taxIncludingPriceTotal",
+      },
+      {
+        label: "绋庣巼",
+        align: "center",
+        prop: "taxRate",
+      },
+      {
+        label: "涓嶅惈绋庢�讳环",
+        align: "center",
+        prop: "unTaxIncludingPriceTotal",
+      },
+      {
+        label: "褰曞叆浜�",
+        align: "center",
+        prop: "createUser",
+      },
+      {
+        label: "褰曞叆鏃ユ湡",
+        align: "center",
+        prop: "createTime",
+      },
+      {
+        dataType: "action",
+        label: "鎿嶄綔",
+        align: "center",
+        fixed: 'right',
+        width: 140,
+        operation: [
+          {
+            name: "缂栬緫",
+            type: "text",
+            clickFun: (row) => {
+              edit(row.id)
+            },
+          },
+        ],
+      },
+    ]
+);
 
-// 璧勪骇绫诲瀷瀛楀吀
-const asset_types = ref([
-  { value: "equipment", label: "璁惧" },
-  { value: "material", label: "鏉愭枡" },
-  { value: "vehicle", label: "杞﹁締" },
-  { value: "tool", label: "宸ュ叿" },
-  { value: "other", label: "鍏朵粬" },
-]);
+// 澶氶�夊悗鍋氫粈涔�
+const handleSelectionChange = (selectionList) => {
+  multipleList.value = selectionList;
+};
 
-// 璧勪骇鐘舵�佸瓧鍏�
-const asset_status = ref([
-  { value: "0", label: "姝e父" },
-  { value: "1", label: "绂佺敤" },
-  { value: "2", label: "缁翠慨涓�" },
-  { value: "3", label: "宸叉姤搴�" },
-]);
+const add = () => {
+  modalRef.value.openModal();
+};
+const edit = (id) => {
+  modalRef.value.loadForm(id);
+};
+const changePage = ({ page, limit }) => {
+  pagination.currentPage = page;
+  pagination.pageSize = limit;
+  onCurrentChange(page);
+};
 
-// 姝e父绂佺敤瀛楀吀
-const sys_normal_disable = ref([
-  { value: "0", label: "姝e父" },
-  { value: "1", label: "绂佺敤" },
-]);
+// 鍚堣鏂规硶
+const summaryMethod = (param) => {
+  return summarizeTable(
+      param,
+      ['number', 'taxIncludingPriceTotal', 'unTaxIncludingPriceTotal', 'taxIncludingPriceUnit'],
+      {
+        number: { noDecimal: true },
+        taxIncludingPriceTotal: { decimalPlaces: 2 },
+        unTaxIncludingPriceTotal: { decimalPlaces: 2 }
+      }
+  );
+};
 
-// 妯℃嫙璧勪骇鏁版嵁
-const mockAssets = ref([
-  {
-    assetId: 1,
-    assetName: "鎸栨帢鏈�",
-    assetCode: "ASSET001",
-    contractorId: 1,
-    contractorName: "鍖椾含寤哄伐闆嗗洟",
-    assetType: "equipment",
-    assetValue: 500000.00,
-    status: "0",
-    createTime: "2024-01-01 10:00:00",
-    remark: "澶у瀷鎸栨帢鏈�",
-  },
-  {
-    assetId: 2,
-    assetName: "娣峰嚌鍦熸悈鎷屾満",
-    assetCode: "ASSET002",
-    contractorId: 2,
-    contractorName: "涓婃捣鍩庡缓闆嗗洟",
-    assetType: "equipment",
-    assetValue: 150000.00,
-    status: "0",
-    createTime: "2024-01-02 10:00:00",
-    remark: "娣峰嚌鍦熸悈鎷岃澶�",
-  },
-  {
-    assetId: 3,
-    assetName: "瑁呰浇鏈�",
-    assetCode: "ASSET003",
-    contractorId: 3,
-    contractorName: "骞垮窞寤虹瓚闆嗗洟",
-    assetType: "equipment",
-    assetValue: 300000.00,
-    status: "1",
-    createTime: "2024-01-03 10:00:00",
-    remark: "瑁呰浇鏈鸿澶�",
-  },
-  {
-    assetId: 4,
-    assetName: "杩愯緭鍗¤溅",
-    assetCode: "ASSET004",
-    contractorId: 4,
-    contractorName: "娣卞湷寤哄伐闆嗗洟",
-    assetType: "vehicle",
-    assetValue: 400000.00,
-    status: "0",
-    createTime: "2024-01-04 10:00:00",
-    remark: "閲嶅瀷杩愯緭鍗¤溅",
-  },
-  {
-    assetId: 5,
-    assetName: "閽㈢瓔鍒囨柇鏈�",
-    assetCode: "ASSET005",
-    contractorId: 5,
-    contractorName: "鏉窞寤哄伐闆嗗洟",
-    assetType: "tool",
-    assetValue: 20000.00,
-    status: "0",
-    createTime: "2024-01-05 10:00:00",
-    remark: "閽㈢瓔鍔犲伐璁惧",
-  },
-]);
-
-/** 鑾峰彇璧勪骇绫诲瀷鏍囩 */
-function getAssetTypeLabel(value) {
-  const type = asset_types.value.find(item => item.value === value);
-  return type ? type.label : value;
-}
-
-/** 鏌ヨ璧勪骇鍒楄〃 */
-function getList() {
-  loading.value = true;
-  // 妯℃嫙API璇锋眰寤惰繜
-  setTimeout(() => {
-    let data = [...mockAssets];
-    // 妯℃嫙鎼滅储杩囨护
-    if (queryParams.value.assetName) {
-      data = data.filter(item => item.assetName.includes(queryParams.value.assetName));
+const deleteRow = (id) => {
+  ElMessageBox.confirm("姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ枃浠�, 鏄惁缁х画?", "鎻愮ず", {
+    confirmButtonText: "纭畾",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(async () => {
+    const { code } = await delLedger(id);
+    if (code == 200) {
+      ElMessage({
+        type: "success",
+        message: "鍒犻櫎鎴愬姛",
+      });
+      getTableData();
     }
-    if (queryParams.value.assetCode) {
-      data = data.filter(item => item.assetCode.includes(queryParams.value.assetCode));
-    }
-    if (queryParams.value.contractorId) {
-      data = data.filter(item => item.contractorId === queryParams.value.contractorId);
-    }
-    if (queryParams.value.status) {
-      data = data.filter(item => item.status === queryParams.value.status);
-    }
-    // 妯℃嫙鍒嗛〉
-    const start = (queryParams.value.pageNum - 1) * queryParams.value.pageSize;
-    const end = start + queryParams.value.pageSize;
-    assetList.value = data.slice(start, end);
-    total.value = data.length;
-    loading.value = false;
-  }, 500);
-}
-
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-function handleQuery() {
-  queryParams.value.pageNum = 1;
-  getList();
-}
-
-/** 閲嶇疆鎸夐挳鎿嶄綔 */
-function resetQuery() {
-  Object.assign(queryParams.value, {
-    assetName: undefined,
-    assetCode: undefined,
-    contractorId: undefined,
-    status: undefined,
   });
-  handleQuery();
-}
+};
 
-/** 鍒犻櫎鎸夐挳鎿嶄綔 */
-function handleDelete(row) {
-  const assetIds = row.assetId || ids.value;
-  ElMessage.confirm(`鏄惁纭鍒犻櫎璧勪骇缂栧彿涓�"${assetIds}"鐨勬暟鎹」锛焋).then(() => {
-    // 妯℃嫙鍒犻櫎鎿嶄綔
-    ElMessage.success("鍒犻櫎鎴愬姛");
-    getList();
-  }).catch(() => {});
-}
-
-/** 鐘舵�佷慨鏀� */
-function handleStatusChange(row) {
-  let text = row.status === "0" ? "鍚敤" : "鍋滅敤";
-  ElMessage.confirm(`纭瑕�"${text}""${row.assetName}"璧勪骇鍚�?`).then(() => {
-    // 妯℃嫙鐘舵�佷慨鏀�
-    ElMessage.success(text + "鎴愬姛");
-    getList();
-  }).catch(() => {
-    row.status = row.status === "0" ? "1" : "0";
-  });
-}
-
-/** 閫夋嫨鏉℃暟  */
-function handleSelectionChange(selection) {
-  ids.value = selection.map((item) => item.assetId);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
-}
-
-/** 閲嶇疆鎿嶄綔琛ㄥ崟 */
-function reset() {
-  form.value = {
-    assetId: undefined,
-    assetName: undefined,
-    assetCode: undefined,
-    contractorId: undefined,
-    contractorName: undefined,
-    assetType: undefined,
-    assetValue: 0,
-    status: "0",
-    remark: undefined,
-  };
-}
-
-/** 鍙栨秷鎸夐挳 */
-function cancel() {
-  open.value = false;
-  reset();
-}
-
-/** 鏂板鎸夐挳鎿嶄綔 */
-function handleAdd() {
-  reset();
-  open.value = true;
-  title.value = "娣诲姞璧勪骇";
-}
-
-/** 淇敼鎸夐挳鎿嶄綔 */
-function handleUpdate(row) {
-  reset();
-  const assetId = row.assetId || ids.value;
-  // 妯℃嫙鑾峰彇璇︽儏
-  const asset = mockAssets.find(item => item.assetId === assetId);
-  if (asset) {
-    form.value = { ...asset };
-    open.value = true;
-    title.value = "淇敼璧勪骇";
+const changeDaterange = (value) => {
+  if (value) {
+    filters.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
+    filters.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
+  } else {
+    filters.entryDateStart = undefined;
+    filters.entryDateEnd = undefined;
   }
-}
+  getTableData();
+};
 
-/** 鎻愪氦鎸夐挳 */
-function submitForm() {
-  // 妯℃嫙琛ㄥ崟楠岃瘉
-  const requiredFields = ['assetName', 'assetCode', 'contractorId', 'assetType', 'assetValue'];
-  const isInvalid = requiredFields.some(field => !form.value[field]);
+const handleOut = () => {
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
+      .then(() => {
+        proxy.download(`/device/ledger/export`, {}, "璁惧鍙拌处妗f.xlsx");
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+};
 
-  if (isInvalid) {
-    ElMessage.error("璇峰~鍐欏繀濉瓧娈�");
-    return;
-  }
+const showQRCode = async (row) => {
+  // 浣犲彲浠ヨ嚜瀹氫箟浜岀淮鐮佸唴瀹癸紝姣斿 row.id 鎴� row.deviceName
+  const qrContent = JSON.stringify(row); // 鎴� `${row.id}`
+  qrCodeUrl.value = await QRCode.toDataURL(qrContent);
+  qrRowData.value = row;
+  qrDialogVisible.value = true;
+};
 
-  // 妯℃嫙鎻愪氦鎿嶄綔
-  ElMessage.success(title.value === "娣诲姞璧勪骇" ? "鏂板鎴愬姛" : "淇敼鎴愬姛");
-  open.value = false;
-  getList();
-}
+const downloadQRCode = () => {
+  const a = document.createElement("a");
+  a.href = qrCodeUrl.value;
+  a.download = `${qrRowData.value.deviceName || "浜岀淮鐮�"}.png`;
+  a.click();
+};
 
 onMounted(() => {
-  getList();
+  filters.entryDate = [
+    dayjs().format("YYYY-MM-DD"),
+    dayjs().add(1, "day").format("YYYY-MM-DD"),
+  ]
+  filters.entryDateStart = dayjs().format("YYYY-MM-DD")
+  filters.entryDateEnd = dayjs().add(1, "day").format("YYYY-MM-DD")
+  getTableData();
 });
 </script>
+
+<style lang="scss" scoped>
+.table_list {
+  margin-top: unset;
+}
+.actions {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 10px;
+}
+</style>
diff --git a/src/views/contractor/compliance/components/formDia.vue b/src/views/contractor/compliance/components/formDia.vue
new file mode 100644
index 0000000..4ec1c44
--- /dev/null
+++ b/src/views/contractor/compliance/components/formDia.vue
@@ -0,0 +1,225 @@
+<template>
+  <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="staffName">
+              <el-input v-model="form.staffName" placeholder="璇疯緭鍏�" clearable/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍚堣缂栧彿锛�" prop="staffNo">
+              <el-input v-model="form.staffNo" placeholder="璇疯緭鍏�" clearable :disabled="operationType !== 'add'"/>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鎵�灞炴壙鍖呭晢锛�" prop="nativePlace">
+              <el-select v-model="form.nativePlace" placeholder="璇烽�夋嫨" clearable style="width: 100%">
+                <el-option v-for="item in customerDataList" :key="item.id" :label="item.customerName + '(' + item.taxpayerIdentificationNumber + ')'" :value="item.customerName"/>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍚堣绫诲瀷锛�" prop="postJob">
+              <el-select v-model="form.postJob" placeholder="璇烽�夋嫨" clearable style="width: 100%">
+                <el-option
+                    v-for="item in ruleList"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
+                />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鏈夋晥鏈熷紑濮嬶細" prop="contractStartTime">
+              <el-date-picker
+                  v-model="form.contractStartTime"
+                  type="date"
+                  placeholder="璇烽�夋嫨鏃ユ湡"
+                  value-format="YYYY-MM-DD"
+                  format="YYYY-MM-DD"
+                  clearable
+                  style="width: 100%"
+                  @change="calculateContractTerm"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鏈夋晥鏈熺粨鏉燂細" prop="contractEndTime">
+              <el-date-picker
+                  v-model="form.contractEndTime"
+                  type="date"
+                  placeholder="璇烽�夋嫨鏃ユ湡"
+                  value-format="YYYY-MM-DD"
+                  format="YYYY-MM-DD"
+                  clearable
+                  style="width: 100%"
+                  @change="calculateContractTerm"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="澶囨敞锛�" prop="adress">
+              <el-input type="textarea" :rows="2" v-model="form.adress" placeholder="璇疯緭鍏�" clearable/>
+            </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>
+  </div>
+</template>
+
+<script setup>
+import {ref, reactive, toRefs} from "vue";
+import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
+import {customerList} from "@/api/salesManagement/salesLedger.js";
+const { proxy } = getCurrentInstance()
+const emit = defineEmits(['close'])
+
+const dialogFormVisible = ref(false);
+const operationType = ref('')
+const customerDataList = ref([])
+const data = reactive({
+  form: {
+    staffNo: "",
+    staffName: "",
+    sex: "",
+    nativePlace: "",
+    postJob: "",
+    adress: "",
+    firstStudy: "",
+    profession: "",
+    identityCard: "",
+    age: 0,
+    phone: "",
+    emergencyContact: "",
+    emergencyContactPhone: "",
+    contractTerm: 0,
+    contractStartTime: "",
+    contractEndTime: "",
+    staffState: "",
+    probationPeriod: 3, // 榛樿璇曠敤鏈�3涓湀
+  },
+  ruleList: [
+    {label:'璁稿彲璇�',value:'璁稿彲璇�'},
+    {label:'璇佷功',value:'璇佷功'},
+    {label:'娉曡閬靛惊',value:'娉曡閬靛惊'},
+    {label:'鏍囧噯鍚堣',value:'鏍囧噯鍚堣'},
+    {label:'鍏朵粬',value:'鍏朵粬'},
+  ],
+
+  rules: {
+    staffNo: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
+    staffName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    sex: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    nativePlace: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    postJob: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+    firstStudy: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    profession: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    identityCard: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    age: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    phone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    emergencyContact: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    emergencyContactPhone: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    contractTerm: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    contractStartTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    contractEndTime: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+  },
+});
+const { form,ruleList, rules } = toRefs(data);
+
+// 鎵撳紑寮规
+const openDialog = (type, row) => {
+  customerList().then(res=>{
+    customerDataList.value = res
+  })
+  operationType.value = type;
+  dialogFormVisible.value = true;
+  if (operationType.value === 'edit') {
+    getStaffJoinInfo(row.id).then(res => {
+      form.value = {...res.data}
+      // 缂栬緫鏃朵篃璁$畻涓�娆″悎鍚屽勾闄�
+      calculateContractTerm();
+    })
+  }
+}
+// 鎻愪氦浜у搧琛ㄥ崟
+const submitForm = () => {
+  proxy.$refs.formRef.validate(valid => {
+    if (valid) {
+      form.value.staffState = 1
+      if (operationType.value === "add") {
+        staffJoinAdd(form.value).then(res => {
+          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+          closeDia();
+        })
+      } else {
+        staffJoinUpdate(form.value).then(res => {
+          proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+          closeDia();
+        })
+      }
+    }
+  })
+}
+// 璁$畻鍚堝悓骞撮檺
+const calculateContractTerm = () => {
+  if (form.value.contractStartTime && form.value.contractEndTime) {
+    const startDate = new Date(form.value.contractStartTime);
+    const endDate = new Date(form.value.contractEndTime);
+
+    if (endDate > startDate) {
+      // 璁$畻骞翠唤宸�
+      const yearDiff = endDate.getFullYear() - startDate.getFullYear();
+      const monthDiff = endDate.getMonth() - startDate.getMonth();
+      const dayDiff = endDate.getDate() - startDate.getDate();
+
+      let years = yearDiff;
+
+      // 濡傛灉缁撴潫鏃ユ湡鐨勬湀鏃ュ皬浜庡紑濮嬫棩鏈熺殑鏈堟棩锛屽垯鍑忓幓1骞�
+      if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
+        years = yearDiff - 1;
+      }
+
+      form.value.contractTerm = Math.max(0, years);
+    } else {
+      form.value.contractTerm = 0;
+    }
+  } else {
+    form.value.contractTerm = 0;
+  }
+};
+
+// 鍏抽棴寮规
+const closeDia = () => {
+  proxy.resetForm("formRef");
+  dialogFormVisible.value = false;
+  emit('close')
+};
+defineExpose({
+  openDialog,
+});
+</script>
+
+<style scoped>
+
+</style>
diff --git a/src/views/contractor/compliance/index.vue b/src/views/contractor/compliance/index.vue
index 7fbe1a2..97bdae4 100644
--- a/src/views/contractor/compliance/index.vue
+++ b/src/views/contractor/compliance/index.vue
@@ -1,664 +1,251 @@
 <template>
   <div class="app-container">
-    <el-form
-      :model="queryParams"
-      ref="queryRef"
-      :inline="true"
-      v-show="showSearch"
-      label-width="90px"
-    >
-      <el-form-item label="鍚堣鍚嶇О" prop="complianceName">
+    <div class="search_form">
+      <div>
+        <span class="search_title">鍚堣鍚嶇О锛�</span>
         <el-input
-          v-model="queryParams.complianceName"
-          placeholder="璇疯緭鍏ュ悎瑙勫悕绉�"
-          clearable
-          style="width: 220px"
-          @keyup.enter="handleQuery"
+            v-model="searchForm.staffName"
+            style="width: 240px"
+            placeholder="璇疯緭鍏ュ悎瑙勫悕绉�"
+            @change="handleQuery"
+            clearable
+            :prefix-icon="Search"
         />
-      </el-form-item>
-      <el-form-item label="鍚堣缂栧彿" prop="complianceCode">
-        <el-input
-          v-model="queryParams.complianceCode"
-          placeholder="璇疯緭鍏ュ悎瑙勭紪鍙�"
-          clearable
-          style="width: 240px"
-          @keyup.enter="handleQuery"
+        <span style="margin-left: 10px;"  class="search_title">鏈夋晥鏈熷紑濮嬶細</span>
+        <el-date-picker
+            v-model="searchForm.entryDateStart"
+            type="date"
+            placeholder="璇烽�夋嫨"
+            size="default"
+            @change="(date) => handleDateChange(date,1)"
         />
-      </el-form-item>
-      <el-form-item label="鎵�灞炴壙鍖呭晢" prop="contractorId">
-        <el-select
-          v-model="queryParams.contractorId"
-          placeholder="璇烽�夋嫨鎵垮寘鍟�"
-          clearable
-          style="width: 240px"
+        <span style="margin-left: 10px;" class="search_title">鏈夋晥鏈熺粨鏉燂細</span>
+        <el-date-picker
+            v-model="searchForm.entryDateEnd"
+            type="date"
+            placeholder="璇烽�夋嫨"
+            size="default"
+            @change="(date) => handleDateChange(date,2)"
+        />
+        <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
+        >鎼滅储</el-button
         >
-          <el-option
-            v-for="contractor in contractorOptions"
-            :key="contractor.contractorId"
-            :label="contractor.contractorName"
-            :value="contractor.contractorId"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="鍚堣鐘舵��" prop="status">
-        <el-select
-          v-model="queryParams.status"
-          placeholder="鍚堣鐘舵��"
-          clearable
-          style="width: 240px"
-        >
-          <el-option
-            v-for="dict in compliance_status"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item>
-        <el-button type="primary" icon="Search" @click="handleQuery"
-          >鎼滅储</el-button
-        >
-        <el-button icon="Refresh" @click="resetQuery">閲嶇疆</el-button>
-      </el-form-item>
-    </el-form>
-
-    <el-row :gutter="10" class="mb8">
-      <el-col :span="1.5">
-        <el-button
-          type="primary"
-          plain
-          icon="Plus"
-          @click="handleAdd"
-          >鏂板</el-button
-        >
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="success"
-          plain
-          icon="Edit"
-          :disabled="single"
-          @click="handleUpdate"
-          >淇敼</el-button
-        >
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
-          type="danger"
-          plain
-          icon="Delete"
-          :disabled="multiple"
-          @click="handleDelete"
-          >鍒犻櫎</el-button
-        >
-      </el-col>
-      <right-toolbar
-        v-model:showSearch="showSearch"
-        @queryTable="getList"
-        :columns="columns"
-      ></right-toolbar>
-    </el-row>
-
-    <el-table
-      v-loading="loading"
-      :data="complianceList"
-      @selection-change="handleSelectionChange"
-      stripe
-    >
-      <el-table-column type="selection" width="50" align="center" />
-      <el-table-column
-        label="鍚堣ID"
-        align="center"
-        key="complianceId"
-        prop="complianceId"
-        v-if="columns[0].visible"
-      />
-      <el-table-column
-        label="鍚堣鍚嶇О"
-        align="center"
-        key="complianceName"
-        prop="complianceName"
-        v-if="columns[1].visible"
-        :show-overflow-tooltip="true"
-      />
-      <el-table-column
-        label="鍚堣缂栧彿"
-        align="center"
-        key="complianceCode"
-        prop="complianceCode"
-        v-if="columns[2].visible"
-      />
-      <el-table-column
-        label="鎵�灞炴壙鍖呭晢"
-        align="center"
-        key="contractorName"
-        prop="contractorName"
-        v-if="columns[3].visible"
-        :show-overflow-tooltip="true"
-      />
-      <el-table-column
-        label="鍚堣绫诲瀷"
-        align="center"
-        key="complianceType"
-        prop="complianceType"
-        v-if="columns[4].visible"
-      >
-        <template #default="scope">
-          {{ getComplianceTypeLabel(scope.row.complianceType) }}
-        </template>
-      </el-table-column>
-      <el-table-column
-        label="鏈夋晥鏈熷紑濮�"
-        align="center"
-        key="validStartDate"
-        prop="validStartDate"
-        v-if="columns[5].visible"
-        width="140"
-      />
-      <el-table-column
-        label="鏈夋晥鏈熺粨鏉�"
-        align="center"
-        key="validEndDate"
-        prop="validEndDate"
-        v-if="columns[6].visible"
-        width="140"
-      />
-      <el-table-column
-        label="鐘舵��"
-        align="center"
-        key="status"
-        v-if="columns[7].visible"
-      >
-        <template #default="scope">
-          <el-switch
-            v-model="scope.row.status"
-            active-value="0"
-            inactive-value="1"
-            @change="handleStatusChange(scope.row)"
-          ></el-switch>
-        </template>
-      </el-table-column>
-      <el-table-column
-        label="鍒涘缓鏃堕棿"
-        align="center"
-        prop="createTime"
-        v-if="columns[8].visible"
-        width="160"
-      >
-        <template #default="scope">
-          <span>{{ parseTime(scope.row.createTime) }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column
-        label="鎿嶄綔"
-        align="center"
-        width="150"
-        class-name="small-padding fixed-width"
-      >
-        <template #default="scope">
-          <el-tooltip
-            content="淇敼"
-            placement="top"
-          >
-            <el-button
-              link
-              type="primary"
-              icon="Edit"
-              @click="handleUpdate(scope.row)"
-            ></el-button>
-          </el-tooltip>
-          <el-tooltip
-            content="鍒犻櫎"
-            placement="top"
-          >
-            <el-button
-              link
-              type="primary"
-              icon="Delete"
-              @click="handleDelete(scope.row)"
-            ></el-button>
-          </el-tooltip>
-        </template>
-      </el-table-column>
-    </el-table>
-    <pagination
-      v-show="total > 0"
-      :total="total"
-      v-model:page="queryParams.pageNum"
-      v-model:limit="queryParams.pageSize"
-      @pagination="getList"
-    />
-
-    <!-- 娣诲姞鎴栦慨鏀瑰悎瑙勯厤缃璇濇 -->
-    <el-dialog :title="title" v-model="open" width="600px" append-to-body>
-      <el-form :model="form" :rules="rules" ref="complianceRef" label-width="80px">
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="鍚堣鍚嶇О" prop="complianceName">
-              <el-input
-                v-model="form.complianceName"
-                placeholder="璇疯緭鍏ュ悎瑙勫悕绉�"
-                maxlength="50"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鍚堣缂栧彿" prop="complianceCode">
-              <el-input
-                v-model="form.complianceCode"
-                placeholder="璇疯緭鍏ュ悎瑙勭紪鍙�"
-                maxlength="20"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="鎵�灞炴壙鍖呭晢" prop="contractorId">
-              <el-select
-                v-model="form.contractorId"
-                placeholder="璇烽�夋嫨鎵垮寘鍟�"
-                clearable
-              >
-                <el-option
-                  v-for="contractor in contractorOptions"
-                  :key="contractor.contractorId"
-                  :label="contractor.contractorName"
-                  :value="contractor.contractorId"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鍚堣绫诲瀷" prop="complianceType">
-              <el-select
-                v-model="form.complianceType"
-                placeholder="璇烽�夋嫨鍚堣绫诲瀷"
-                clearable
-              >
-                <el-option
-                  v-for="type in compliance_types"
-                  :key="type.value"
-                  :label="type.label"
-                  :value="type.value"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="鏈夋晥鏈熷紑濮�" prop="validStartDate">
-              <el-date-picker
-                v-model="form.validStartDate"
-                type="date"
-                placeholder="閫夋嫨寮�濮嬫棩鏈�"
-                value-format="YYYY-MM-DD"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鏈夋晥鏈熺粨鏉�" prop="validEndDate">
-              <el-date-picker
-                v-model="form.validEndDate"
-                type="date"
-                placeholder="閫夋嫨缁撴潫鏃ユ湡"
-                value-format="YYYY-MM-DD"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="12">
-            <el-form-item label="鐘舵��">
-              <el-radio-group v-model="form.status">
-                <el-radio
-                  v-for="dict in sys_normal_disable"
-                  :key="dict.value"
-                  :value="dict.value"
-                  >{{ dict.label }}</el-radio
-                >
-              </el-radio-group>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row>
-          <el-col :span="24">
-            <el-form-item label="澶囨敞">
-              <el-input
-                v-model="form.remark"
-                type="textarea"
-                placeholder="璇疯緭鍏ュ唴瀹�"
-              ></el-input>
-            </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="cancel">鍙� 娑�</el-button>
-        </div>
-      </template>
-    </el-dialog>
+      </div>
+      <div>
+        <el-button type="primary" @click="openForm('add')">鏂板</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>
+    </div>
+    <form-dia ref="formDia" @close="handleQuery"></form-dia>
   </div>
 </template>
 
-<script setup name="ContractorCompliance">
-import { ref, reactive, toRefs, watch, onMounted } from 'vue';
-import { ElMessage } from 'element-plus';
-import { parseTime } from '@/utils/ruoyi';
-
-const complianceList = ref([]);
-const open = ref(false);
-const loading = ref(true);
-const showSearch = ref(true);
-const ids = ref([]);
-const single = ref(true);
-const multiple = ref(true);
-const total = ref(0);
-const title = ref("");
-
-// 鍒楁樉闅愪俊鎭�
-const columns = ref([
-  { key: 0, label: `鍚堣ID`, visible: true },
-  { key: 1, label: `鍚堣鍚嶇О`, visible: true },
-  { key: 2, label: `鍚堣缂栧彿`, visible: true },
-  { key: 3, label: `鎵�灞炴壙鍖呭晢`, visible: true },
-  { key: 4, label: `鍚堣绫诲瀷`, visible: true },
-  { key: 5, label: `鏈夋晥鏈熷紑濮媊, visible: true },
-  { key: 6, label: `鏈夋晥鏈熺粨鏉焋, visible: true },
-  { key: 7, label: `鐘舵�乣, visible: true },
-  { key: 8, label: `鍒涘缓鏃堕棿`, visible: true },
-]);
+<script setup>
+import { Search } from "@element-plus/icons-vue";
+import {onMounted, ref} from "vue";
+import FormDia from "@/views/contractor/compliance/components/formDia.vue";
+import {staffJoinDel, staffJoinListPage} from "@/api/personnelManagement/onboarding.js";
+import {ElMessageBox} from "element-plus";
+import dayjs from "dayjs";
 
 const data = reactive({
-  form: {
-    complianceId: undefined,
-    complianceName: undefined,
-    complianceCode: undefined,
-    contractorId: undefined,
-    contractorName: undefined,
-    complianceType: undefined,
-    validStartDate: undefined,
-    validEndDate: undefined,
-    status: "0",
-    remark: undefined,
-  },
-  queryParams: {
-    pageNum: 1,
-    pageSize: 10,
-    complianceName: undefined,
-    complianceCode: undefined,
-    contractorId: undefined,
-    status: undefined,
-  },
-  rules: {
-    complianceName: [
-      { required: true, message: "鍚堣鍚嶇О涓嶈兘涓虹┖", trigger: "blur" },
-    ],
-    complianceCode: [
-      { required: true, message: "鍚堣缂栧彿涓嶈兘涓虹┖", trigger: "blur" },
-    ],
-    contractorId: [
-      { required: true, message: "鎵�灞炴壙鍖呭晢涓嶈兘涓虹┖", trigger: "blur" },
-    ],
-    complianceType: [
-      { required: true, message: "鍚堣绫诲瀷涓嶈兘涓虹┖", trigger: "blur" },
-    ],
-    validStartDate: [
-      { required: true, message: "鏈夋晥鏈熷紑濮嬩笉鑳戒负绌�", trigger: "blur" },
-    ],
-    validEndDate: [
-      { required: true, message: "鏈夋晥鏈熺粨鏉熶笉鑳戒负绌�", trigger: "blur" },
-    ],
+  searchForm: {
+    staffName: "",
   },
 });
-
-const { queryParams, form, rules } = toRefs(data);
-
-// 妯℃嫙鎵垮寘鍟嗘暟鎹�
-const contractorOptions = ref([
-  { contractorId: 1, contractorName: "鍖椾含寤哄伐闆嗗洟" },
-  { contractorId: 2, contractorName: "涓婃捣鍩庡缓闆嗗洟" },
-  { contractorId: 3, contractorName: "骞垮窞寤虹瓚闆嗗洟" },
-  { contractorId: 4, contractorName: "娣卞湷寤哄伐闆嗗洟" },
-  { contractorId: 5, contractorName: "鏉窞寤哄伐闆嗗洟" },
-]);
-
-// 鍚堣绫诲瀷瀛楀吀
-const compliance_types = ref([
-  { value: "license", label: "璁稿彲璇�" },
-  { value: "certificate", label: "璇佷功" },
-  { value: "regulation", label: "娉曡閬靛惊" },
-  { value: "standard", label: "鏍囧噯鍚堣" },
-  { value: "other", label: "鍏朵粬" },
-]);
-
-// 鍚堣鐘舵�佸瓧鍏�
-const compliance_status = ref([
-  { value: "0", label: "姝e父" },
-  { value: "1", label: "绂佺敤" },
-  { value: "2", label: "鍗冲皢杩囨湡" },
-  { value: "3", label: "宸茶繃鏈�" },
-]);
-
-// 姝e父绂佺敤瀛楀吀
-const sys_normal_disable = ref([
-  { value: "0", label: "姝e父" },
-  { value: "1", label: "绂佺敤" },
-]);
-
-// 妯℃嫙鍚堣鏁版嵁
-const mockCompliances = ref([
+const { searchForm } = toRefs(data);
+const tableColumn = ref([
   {
-    complianceId: 1,
-    complianceName: "寤虹瓚鏂藉伐璁稿彲璇�",
-    complianceCode: "COMP001",
-    contractorId: 1,
-    contractorName: "鍖椾含寤哄伐闆嗗洟",
-    complianceType: "license",
-    validStartDate: "2024-01-01",
-    validEndDate: "2025-12-31",
-    status: "0",
-    createTime: "2024-01-01 10:00:00",
-    remark: "寤虹瓚鏂藉伐璁稿彲璇�",
+    label: "鍚堣鍚嶇О",
+    prop: "staffName",
   },
   {
-    complianceId: 2,
-    complianceName: "瀹夊叏鐢熶骇璁稿彲璇�",
-    complianceCode: "COMP002",
-    contractorId: 2,
-    contractorName: "涓婃捣鍩庡缓闆嗗洟",
-    complianceType: "license",
-    validStartDate: "2024-01-02",
-    validEndDate: "2025-12-31",
-    status: "0",
-    createTime: "2024-01-02 10:00:00",
-    remark: "瀹夊叏鐢熶骇璁稿彲璇�",
+    label: "鍚堣缂栧彿",
+    prop: "staffNo",
   },
   {
-    complianceId: 3,
-    complianceName: "璐ㄩ噺绠$悊浣撶郴璁よ瘉",
-    complianceCode: "COMP003",
-    contractorId: 3,
-    contractorName: "骞垮窞寤虹瓚闆嗗洟",
-    complianceType: "certificate",
-    validStartDate: "2024-01-03",
-    validEndDate: "2025-12-31",
-    status: "1",
-    createTime: "2024-01-03 10:00:00",
-    remark: "ISO9001璐ㄩ噺绠$悊浣撶郴璁よ瘉",
+    label: "鎵�灞炴壙鍖呭晢",
+    prop: "nativePlace",
   },
   {
-    complianceId: 4,
-    complianceName: "鐜绠$悊浣撶郴璁よ瘉",
-    complianceCode: "COMP004",
-    contractorId: 4,
-    contractorName: "娣卞湷寤哄伐闆嗗洟",
-    complianceType: "certificate",
-    validStartDate: "2024-01-04",
-    validEndDate: "2025-12-31",
-    status: "0",
-    createTime: "2024-01-04 10:00:00",
-    remark: "ISO14001鐜绠$悊浣撶郴璁よ瘉",
+    label: "鍚堣绫诲瀷",
+    prop: "postJob",
   },
   {
-    complianceId: 5,
-    complianceName: "鑱屼笟鍋ュ悍瀹夊叏绠$悊浣撶郴璁よ瘉",
-    complianceCode: "COMP005",
-    contractorId: 5,
-    contractorName: "鏉窞寤哄伐闆嗗洟",
-    complianceType: "certificate",
-    validStartDate: "2024-01-05",
-    validEndDate: "2025-12-31",
-    status: "0",
-    createTime: "2024-01-05 10:00:00",
-    remark: "ISO45001鑱屼笟鍋ュ悍瀹夊叏绠$悊浣撶郴璁よ瘉",
+    label: "鍚堝悓寮�濮嬫棩鏈�",
+    prop: "contractStartTime",
+    width: 120
+  },
+  {
+    label: "鍚堝悓缁撴潫鏃ユ湡",
+    prop: "contractEndTime",
+    width: 120
+  },
+  {
+    label: "澶囨敞",
+    prop: "postJob",
+  },
+  {
+    dataType: "action",
+    label: "鎿嶄綔",
+    align: "center",
+    fixed: 'right',
+    operation: [
+      {
+        name: "缂栬緫",
+        type: "text",
+        clickFun: (row) => {
+          openForm("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 { proxy } = getCurrentInstance()
 
-/** 鑾峰彇鍚堣绫诲瀷鏍囩 */
-function getComplianceTypeLabel(value) {
-  const type = compliance_types.value.find(item => item.value === value);
-  return type ? type.label : value;
-}
-
-/** 鏌ヨ鍚堣鍒楄〃 */
-function getList() {
-  loading.value = true;
-  // 妯℃嫙API璇锋眰寤惰繜
-  setTimeout(() => {
-    let data = [...mockCompliances.value];
-    // 妯℃嫙鎼滅储杩囨护
-    if (queryParams.value.complianceName) {
-      data = data.filter(item => item.complianceName.includes(queryParams.value.complianceName));
+const handleDateChange = (value,type) => {
+  searchForm.value.entryDateEnd = null
+  searchForm.value.entryDateStart = null
+  if(type === 1){
+    if (value) {
+      searchForm.value.entryDateStart = dayjs(value).format("YYYY-MM-DD");
     }
-    if (queryParams.value.complianceCode) {
-      data = data.filter(item => item.complianceCode.includes(queryParams.value.complianceCode));
+  }else{
+    if (value) {
+      searchForm.value.entryDateEnd = dayjs(value).format("YYYY-MM-DD");
     }
-    if (queryParams.value.contractorId) {
-      data = data.filter(item => item.contractorId === queryParams.value.contractorId);
-    }
-    if (queryParams.value.status) {
-      data = data.filter(item => item.status === queryParams.value.status);
-    }
-    // 妯℃嫙鍒嗛〉
-    const start = (queryParams.value.pageNum - 1) * queryParams.value.pageSize;
-    const end = start + queryParams.value.pageSize;
-    complianceList.value = data.slice(start, end);
-    total.value = data.length;
-    loading.value = false;
-  }, 500);
-}
-
-/** 鎼滅储鎸夐挳鎿嶄綔 */
-function handleQuery() {
-  queryParams.value.pageNum = 1;
-  getList();
-}
-
-/** 閲嶇疆鎸夐挳鎿嶄綔 */
-function resetQuery() {
-  Object.assign(queryParams.value, {
-    complianceName: undefined,
-    complianceCode: undefined,
-    contractorId: undefined,
-    status: undefined,
-  });
-  handleQuery();
-}
-
-/** 鍒犻櫎鎸夐挳鎿嶄綔 */
-function handleDelete(row) {
-  const complianceIds = row.complianceId || ids.value;
-  ElMessage.confirm(`鏄惁纭鍒犻櫎鍚堣缂栧彿涓�"${complianceIds}"鐨勬暟鎹」锛焋).then(() => {
-    // 妯℃嫙鍒犻櫎鎿嶄綔
-    ElMessage.success("鍒犻櫎鎴愬姛");
-    getList();
-  }).catch(() => {});
-}
-
-/** 鐘舵�佷慨鏀� */
-function handleStatusChange(row) {
-  let text = row.status === "0" ? "鍚敤" : "鍋滅敤";
-  ElMessage.confirm(`纭瑕�"${text}""${row.complianceName}"鍚堣璁板綍鍚�?`).then(() => {
-    // 妯℃嫙鐘舵�佷慨鏀�
-    ElMessage.success(text + "鎴愬姛");
-    getList();
-  }).catch(() => {
-    row.status = row.status === "0" ? "1" : "0";
-  });
-}
-
-/** 閫夋嫨鏉℃暟  */
-function handleSelectionChange(selection) {
-  ids.value = selection.map((item) => item.complianceId);
-  single.value = selection.length != 1;
-  multiple.value = !selection.length;
-}
-
-/** 閲嶇疆鎿嶄綔琛ㄥ崟 */
-function reset() {
-  form.value = {
-    complianceId: undefined,
-    complianceName: undefined,
-    complianceCode: undefined,
-    contractorId: undefined,
-    contractorName: undefined,
-    complianceType: undefined,
-    validStartDate: undefined,
-    validEndDate: undefined,
-    status: "0",
-    remark: undefined,
-  };
-}
-
-/** 鍙栨秷鎸夐挳 */
-function cancel() {
-  open.value = false;
-  reset();
-}
-
-/** 鏂板鎸夐挳鎿嶄綔 */
-function handleAdd() {
-  reset();
-  open.value = true;
-  title.value = "娣诲姞鍚堣璁板綍";
-}
-
-/** 淇敼鎸夐挳鎿嶄綔 */
-function handleUpdate(row) {
-  reset();
-  const complianceId = row.complianceId || ids.value;
-  // 妯℃嫙鑾峰彇璇︽儏
-  const compliance = mockCompliances.find(item => item.complianceId === complianceId);
-  if (compliance) {
-    form.value = { ...compliance };
-    open.value = true;
-    title.value = "淇敼鍚堣璁板綍";
   }
-}
+  getList();
+};
+// 鏌ヨ鍒楄〃
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+const handleQuery = () => {
+  page.current = 1;
+  getList();
+};
+const pagination = (obj) => {
+  page.current = obj.page;
+  page.size = obj.limit;
+  getList();
+};
+const getList = () => {
+  tableLoading.value = true;
+  staffJoinListPage({...page, ...searchForm.value, staffState: 1}).then(res => {
+    tableLoading.value = false;
+    tableData.value = res.data.records
+    page.total = res.data.total;
 
-/** 鎻愪氦鎸夐挳 */
-function submitForm() {
-  // 妯℃嫙琛ㄥ崟楠岃瘉
-  const requiredFields = ['complianceName', 'complianceCode', 'contractorId', 'complianceType', 'validStartDate', 'validEndDate'];
-  const isInvalid = requiredFields.some(field => !form.value[field]);
+    // 妫�鏌ユ槸鍚︽湁涓磋繎杞鐨勫憳宸ュ苟鎻愰啋
+    checkProbationEnding(tableData.value);
+  }).catch(err => {
+    tableLoading.value = false;
+  })
+};
+// 妫�鏌ヤ复杩戣浆姝g殑鍛樺伐骞舵彁閱�
+const checkProbationEnding = (data) => {
+  const probationEndingSoon = [];
 
-  if (isInvalid) {
-    ElMessage.error("璇峰~鍐欏繀濉瓧娈�");
+  data.forEach(item => {
+    // 淇敼涓轰娇鐢ㄥ悎鍚屽紑濮嬫棩鏈熸鏌�
+    if (item.contractStartTime && item.probationPeriod) {
+      const probationEndDate = dayjs(item.contractStartTime).add(item.probationPeriod, 'month');
+      const daysUntilProbationEnd = probationEndDate.diff(dayjs(), 'day');
+
+      if (daysUntilProbationEnd >= 0 && daysUntilProbationEnd <= 7) {
+        probationEndingSoon.push({
+          staffName: item.staffName,
+          probationEndDate: probationEndDate.format('YYYY-MM-DD'),
+          daysLeft: daysUntilProbationEnd
+        });
+      }
+    }
+  });
+
+  if (probationEndingSoon.length > 0) {
+    let message = '浠ヤ笅鍛樺伐灏嗗湪7澶╁唴杞锛歕n';
+    probationEndingSoon.forEach(item => {
+      message += `${item.staffName}锛�${item.probationEndDate}锛岃繕鏈�${item.daysLeft}澶╋級\n`;
+    });
+
+    // 鏄剧ず鎻愰啋娑堟伅
+    proxy.$modal.msgInfo(message);
+  }
+};
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+  selectedRows.value = selection;
+};
+
+// 鎵撳紑寮规
+const openForm = (type, row) => {
+  nextTick(() => {
+    formDia.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;
   }
-
-  // 妯℃嫙鎻愪氦鎿嶄綔
-  ElMessage.success(title.value === "娣诲姞鍚堣璁板綍" ? "鏂板鎴愬姛" : "淇敼鎴愬姛");
-  open.value = false;
-  getList();
-}
-
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
+      .then(() => {
+        staffJoinDel(ids).then((res) => {
+          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+          getList();
+        });
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+};
+// 瀵煎嚭
+const handleOut = () => {
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
+      .then(() => {
+        proxy.download("/staff/staffJoinLeaveRecord/export", {staffState: 1}, "浜哄憳鍏ヨ亴.xlsx");
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+};
 onMounted(() => {
   getList();
 });
 </script>
+
+<style scoped></style>
diff --git a/src/views/contractor/evaluateTemplate/Form.vue b/src/views/contractor/evaluateTemplate/Form.vue
new file mode 100644
index 0000000..d92f435
--- /dev/null
+++ b/src/views/contractor/evaluateTemplate/Form.vue
@@ -0,0 +1,104 @@
+<template>
+  <el-form :model="form" label-width="100px" :rules="formRules" ref="formRef">
+    <el-form-item label="妯℃澘绫诲瀷" prop="incomeType">
+      <el-select
+          v-model="form.incomeType"
+          placeholder="璇烽�夋嫨"
+          clearable
+      >
+        <el-option :label="item.label" :value="item.value" v-for="(item,index) in income_types" :key="index" />
+      </el-select>
+    </el-form-item>
+    <el-form-item label="妯℃澘鍚嶇О" prop="customerName">
+      <el-input v-model="form.customerName" placeholder="璇疯緭鍏�" />
+    </el-form-item>
+    <el-form-item label="妯℃澘缂栧彿" prop="incomeDescribed">
+      <el-input v-model="form.incomeDescribed" placeholder="璇疯緭鍏�" />
+    </el-form-item>
+    <el-form-item label="鐗堟湰鍙�" prop="invoiceNumber">
+      <el-input v-model="form.invoiceNumber" placeholder="璇疯緭鍏�" />
+    </el-form-item>
+    <el-form-item label="澶囨敞" prop="note">
+      <el-input
+          v-model="form.note"
+          placeholder="澶囨敞"
+      />
+    </el-form-item>
+
+  </el-form>
+</template>
+
+<script setup>
+import useFormData from "@/hooks/useFormData";
+import { getAccountIncome } from "@/api/financialManagement/revenueManagement";
+import {ref} from "vue";
+const { proxy } = getCurrentInstance();
+
+
+defineOptions({
+  name: "鏂板鏀跺叆",
+});
+const income_types  = ref([
+  { label: "缁煎悎璇勪环", value: "缁煎悎璇勪环" },
+  { label: "瀹夊叏鐢熶骇璇勪环", value: "瀹夊叏鐢熶骇璇勪环" },
+  { label: "灞ョ害鑳藉姏璇勪环", value: "灞ョ害鑳藉姏璇勪环" },
+  { label: "璧勮川鍚堣璇勪环", value: "璧勮川鍚堣璇勪环" },
+  { label: "鐗圭璁惧缁翠繚璇勪环", value: "鐗圭璁惧缁翠繚璇勪环" },
+  { label: "宸ョ▼鏂藉伐瀹夊叏璇勪环", value: "宸ョ▼鏂藉伐瀹夊叏璇勪环" }
+]);
+const { payment_methods } = proxy.useDict("payment_methods");
+const formRef = ref(null);
+const formRules = {
+  customerName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
+  incomeMoney: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
+  incomeDescribed: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
+  incomeDate: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
+  incomeType: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
+  incomeMethod: [{ required: true, trigger: "change", message: "璇烽�夋嫨" }],
+}
+
+const { form, resetForm } = useFormData({
+  incomeDate: undefined, // 鏀跺叆鏃ユ湡
+  incomeType: undefined, // 鏀跺叆绫诲瀷
+  customerName: undefined, // 瀹㈡埛鍚嶇О
+  incomeMoney: undefined, // 鏀跺叆閲戦
+  incomeDescribed: undefined, // 鏀跺叆鎻忚堪
+  incomeMethod: undefined, // 鏀舵鏂瑰紡
+  invoiceNumber: undefined, // 鍙戠エ鍙风爜
+  note: undefined, // 澶囨敞
+});
+
+const loadForm = async (id) => {
+  const { code, data } = await getAccountIncome(id);
+  if (code == 200) {
+    form.incomeDate = data.incomeDate;
+    form.incomeType = data.incomeType;
+    form.customerName = data.customerName;
+    form.incomeMoney = data.incomeMoney;
+    form.incomeDescribed = data.incomeDescribed;
+    form.incomeMethod = data.incomeMethod;
+    form.invoiceNumber = data.invoiceNumber;
+    form.note = data.note;
+  }
+};
+
+// 娓呴櫎琛ㄥ崟鏍¢獙鐘舵��
+const clearValidate = () => {
+  formRef.value?.clearValidate();
+};
+
+// 閲嶇疆琛ㄥ崟鏁版嵁鍜屾牎楠岀姸鎬�
+const resetFormAndValidate = () => {
+  resetForm();
+  clearValidate();
+};
+
+defineExpose({
+  form,
+  loadForm,
+  resetForm,
+  clearValidate,
+  resetFormAndValidate,
+  formRef,
+});
+</script>
diff --git a/src/views/contractor/evaluateTemplate/Modal.vue b/src/views/contractor/evaluateTemplate/Modal.vue
new file mode 100644
index 0000000..7efe4e9
--- /dev/null
+++ b/src/views/contractor/evaluateTemplate/Modal.vue
@@ -0,0 +1,71 @@
+<template>
+  <el-dialog :title="modalOptions.title" v-model="visible" @close="close" width="30%">
+    <Form ref="formRef"></Form>
+    <template #footer>
+      <el-button type="primary" @click="sendForm" :loading="loading">
+        {{ modalOptions.confirmText }}
+      </el-button>
+      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup>
+import { useModal } from "@/hooks/useModal";
+import { add, update } from "@/api/financialManagement/revenueManagement";
+import Form from "./Form.vue";
+import { ElMessage } from "element-plus";
+import dayjs from "dayjs";
+const { proxy } = getCurrentInstance()
+
+defineOptions({
+  name: "鏀跺叆鏂板缂栬緫",
+});
+
+const emits = defineEmits(["success"]);
+
+const formRef = ref();
+const {
+  id,
+  visible,
+  loading,
+  openModal,
+  modalOptions,
+  handleConfirm,
+  closeModal,
+} = useModal({ title: "鏀跺叆" });
+
+const sendForm = () => {
+  proxy.$refs.formRef.$refs.formRef.validate(async valid => {
+    if (valid) {
+      formRef.value.form.incomeDate = dayjs(new Date()).format("YYYY-MM-DD")
+      const {code} = id.value
+          ? await update({id: id.value, ...formRef.value.form})
+          : await add(formRef.value.form);
+      if (code == 200) {
+        emits("success");
+        ElMessage({message: "鎿嶄綔鎴愬姛", type: "success"});
+        close();
+      } else {
+        loading.value = false;
+      }
+    }
+  })
+};
+
+const close = () => {
+  formRef.value.resetFormAndValidate();
+  closeModal();
+};
+
+const loadForm = async (id) => {
+  openModal(id);
+  await nextTick();
+  formRef.value.loadForm(id);
+};
+
+defineExpose({
+  openModal,
+  loadForm,
+});
+</script>
diff --git a/src/views/contractor/evaluateTemplate/index.vue b/src/views/contractor/evaluateTemplate/index.vue
new file mode 100644
index 0000000..6e9499b
--- /dev/null
+++ b/src/views/contractor/evaluateTemplate/index.vue
@@ -0,0 +1,235 @@
+<template>
+  <div class="app-container">
+    <el-form :model="filters" :inline="true">
+      <el-form-item label="褰曞叆鏃ユ湡:">
+        <el-date-picker v-model="filters.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
+                        placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
+      </el-form-item>
+      <el-form-item label="妯℃澘绫诲瀷:">
+        <el-select
+            v-model="filters.incomeMethod"
+            placeholder="璇烽�夋嫨"
+            clearable
+            style="width: 200px;"
+        >
+          <el-option
+              v-for="item in income_types"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="getTableData">鎼滅储</el-button>
+        <el-button @click="resetFilters">閲嶇疆</el-button>
+      </el-form-item>
+    </el-form>
+    <div class="table_list">
+      <div class="actions">
+        <div></div>
+        <div>
+          <el-button type="primary" @click="add" icon="Plus"> 鏂板 </el-button>
+          <el-button
+              type="danger"
+              icon="Delete"
+              :disabled="multipleList.length <= 0"
+              @click="deleteRow(multipleList.map((item) => item.id))"
+          >
+            鎵归噺鍒犻櫎
+          </el-button>
+        </div>
+      </div>
+      <PIMTable
+          rowKey="id"
+          isSelection
+          :column="columns"
+          :tableData="dataList"
+          :page="{
+          current: pagination.currentPage,
+          size: pagination.pageSize,
+          total: pagination.total,
+        }"
+          @selection-change="handleSelectionChange"
+          @pagination="changePage"
+      >
+        <template #operation="{ row }">
+          <el-button type="primary" text @click="edit(row.id)" icon="editPen">
+            缂栬緫
+          </el-button>
+        </template>
+      </PIMTable>
+    </div>
+    <Modal ref="modalRef" @success="getTableData"></Modal>
+  </div>
+</template>
+
+<script setup>
+import { usePaginationApi } from "@/hooks/usePaginationApi";
+import { listPage, delAccountIncome } from "@/api/financialManagement/revenueManagement";
+import { onMounted, getCurrentInstance } from "vue";
+import Modal from "./Modal.vue";
+import { ElMessageBox, ElMessage } from "element-plus";
+import dayjs from "dayjs";
+
+defineOptions({
+  name: "鏀跺叆绠$悊",
+});
+
+// 琛ㄦ牸澶氶�夋閫変腑椤�
+const multipleList = ref([]);
+const { proxy } = getCurrentInstance();
+const modalRef = ref();
+const income_types  = ref([
+  { label: "缁煎悎璇勪环", value: "缁煎悎璇勪环" },
+  { label: "瀹夊叏鐢熶骇璇勪环", value: "瀹夊叏鐢熶骇璇勪环" },
+  { label: "灞ョ害鑳藉姏璇勪环", value: "灞ョ害鑳藉姏璇勪环" },
+  { label: "璧勮川鍚堣璇勪环", value: "璧勮川鍚堣璇勪环" },
+  { label: "鐗圭璁惧缁翠繚璇勪环", value: "鐗圭璁惧缁翠繚璇勪环" },
+  { label: "宸ョ▼鏂藉伐瀹夊叏璇勪环", value: "宸ョ▼鏂藉伐瀹夊叏璇勪环" }
+]);
+
+const {
+  filters,
+  columns,
+  dataList,
+  pagination,
+  getTableData,
+  resetFilters,
+  onCurrentChange,
+} = usePaginationApi(
+    listPage,
+    {
+      incomeMethod: undefined,
+    },
+    [
+      {
+        label: "妯℃澘绫诲瀷",
+        align: "center",
+        prop: "incomeType",
+      },
+      {
+        label: "妯℃澘鍚嶇О",
+        align: "center",
+        prop: "customerName",
+
+      },
+      {
+        label: "妯℃澘缂栧彿",
+        align: "center",
+        prop: "incomeDescribed",
+
+      },
+      {
+        label: "鐗堟湰鍙�",
+        align: "center",
+        prop: "invoiceNumber",
+
+      },
+      {
+        label: "澶囨敞",
+        align: "center",
+        prop: "note",
+
+      },
+      {
+        label: "褰曞叆浜�",
+        align: "center",
+        prop: "inputUser",
+      },
+      {
+        label: "褰曞叆鏃ユ湡",
+        align: "center",
+        prop: "inputTime",
+
+      },
+      {
+        fixed: "right",
+        label: "鎿嶄綔",
+        dataType: "slot",
+        slot: "operation",
+        align: "center",
+        width: "200px",
+      },
+    ]
+);
+
+// 澶氶�夊悗鍋氫粈涔�
+const handleSelectionChange = (selectionList) => {
+  multipleList.value = selectionList;
+};
+
+const add = () => {
+  modalRef.value.openModal();
+};
+const edit = (id) => {
+  modalRef.value.loadForm(id);
+};
+const changePage = ({ page, limit }) => {
+  pagination.currentPage = page;
+  pagination.pageSize = limit;
+  onCurrentChange(page);
+};
+const deleteRow = (id) => {
+  ElMessageBox.confirm("姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹�, 鏄惁缁х画?", "鎻愮ず", {
+    confirmButtonText: "纭畾",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(async () => {
+    const { code } = await delAccountIncome(id);
+    if (code == 200) {
+      ElMessage({
+        type: "success",
+        message: "鍒犻櫎鎴愬姛",
+      });
+      getTableData();
+    }
+  });
+};
+
+const changeDaterange = (value) => {
+  if (value) {
+    filters.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
+    filters.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
+  } else {
+    filters.entryDateStart = undefined;
+    filters.entryDateEnd = undefined;
+  }
+  getTableData();
+};
+
+const handleOut = () => {
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
+      .then(() => {
+        proxy.download(`/account/accountIncome/export`, {}, "鏀跺叆鍙拌处.xlsx");
+      })
+      .catch(() => {
+        proxy.$modal.msg("宸插彇娑�");
+      });
+};
+
+onMounted(() => {
+  filters.entryDate = [
+    dayjs().format("YYYY-MM-DD"),
+    dayjs().add(1, "day").format("YYYY-MM-DD"),
+  ]
+  filters.entryDateStart = dayjs().format("YYYY-MM-DD")
+  filters.entryDateEnd = dayjs().add(1, "day").format("YYYY-MM-DD")
+  getTableData();
+});
+</script>
+
+<style lang="scss" scoped>
+.table_list {
+  margin-top: unset;
+}
+.actions {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 10px;
+}
+</style>

--
Gitblit v1.9.3