From a686251b73f616532d6a9518faad49c7693a6e1c Mon Sep 17 00:00:00 2001
From: lishenao <3065849776@qq.com>
Date: 星期二, 01 七月 2025 14:31:53 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev

---
 src/views/equipmentManagement/upkeep/index.vue                     |  213 ++++++++++++++
 src/views/procurementManagement/procurementInvoiceLedger/index.vue |    7 
 src/views/reportAnalysis/projectProfit/index.vue                   |    7 
 src/views/system/user/profile/userAvatar.vue                       |   30 -
 src/views/equipmentManagement/repair/index.vue                     |    6 
 src/views/inventoryManagement/issueManagement/index.vue            |   42 +-
 src/views/procurementManagement/invoiceEntry/index.vue             |    7 
 src/api/equipmentManagement/upkeep.js                              |   72 ++++
 src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue    |   60 ++++
 src/views/salesManagement/salesLedger/index.vue                    |   25 +
 src/views/salesManagement/invoiceRegistration/index.vue            |    8 
 src/api/procurementManagement/paymentEntry.js                      |   98 +++---
 src/views/equipmentManagement/ledger/Form.vue                      |   46 ++
 src/views/salesManagement/invoiceLedger/index.vue                  |   14 
 src/views/equipmentManagement/repair/Form/MaintainForm.vue         |   16 
 src/views/equipmentManagement/upkeep/Form/MaintenanceForm.vue      |   64 ++++
 src/views/reportAnalysis/taxComparison/index.vue                   |    7 
 src/views/equipmentManagement/upkeep/Form/PlanForm.vue             |   96 ++++++
 src/views/equipmentManagement/upkeep/Modal/PlanModal.vue           |   76 +++++
 19 files changed, 778 insertions(+), 116 deletions(-)

diff --git a/src/api/equipmentManagement/upkeep.js b/src/api/equipmentManagement/upkeep.js
new file mode 100644
index 0000000..c091670
--- /dev/null
+++ b/src/api/equipmentManagement/upkeep.js
@@ -0,0 +1,72 @@
+import request from "@/utils/request";
+
+/**
+ * @desc 璁惧淇濆吇鍒楄〃鍒嗛〉鏌ヨ
+ * @param {鍒嗛〉鏌ヨ鍏ュ弬} params
+ * @returns
+ */
+export const getUpkeepPage = (params) => {
+  return request({
+    url: "/device/maintenance/page",
+    method: "get",
+    params,
+  });
+};
+
+/**
+ * @desc 璁惧淇濆吇璇︽儏
+ * @param {淇濆吇浣嗙紪鍙穧 id
+ * @returns
+ */
+export const getUpkeepById = (id) => {
+  return request({
+    url: `/device/maintenance/${id}`,
+    method: "get",
+  });
+};
+
+/**
+ * @desc 璁惧淇濆吇鏂板
+ * @param {鏂板淇濆吇琛ㄥ崟} data
+ * @returns
+ */
+export const addUpkeep = (data) => {
+  return request({
+    url: "/device/maintenance",
+    method: "post",
+    data,
+  });
+};
+
+/**
+ * @desc 璁惧淇濆吇缂栬緫
+ * @param {缂栬緫淇濆吇琛ㄥ崟} data
+ * @returns
+ */
+export const editUpkeep = (data) => {
+  return request({
+    url: "/device/maintenance",
+    method: "put",
+    data,
+  });
+};
+
+/**
+ * @desc 鏂板淇濆吇琛ㄥ崟
+ * @param {鏂板淇濆吇琛ㄥ崟} data
+ * @returns
+ */
+export const addMaintenance = (data) => {
+  return request({
+    url: "/device/maintenance/maintenance",
+    method: "post",
+    data,
+  });
+};
+
+export const delUpkeep = (id) => {
+  return request({
+    url: `/device/maintenance/${id}`,
+    method: "delete",
+  });
+};
diff --git a/src/api/procurementManagement/paymentEntry.js b/src/api/procurementManagement/paymentEntry.js
index 7725779..6ef0eb9 100644
--- a/src/api/procurementManagement/paymentEntry.js
+++ b/src/api/procurementManagement/paymentEntry.js
@@ -1,81 +1,81 @@
 // 閲囪喘浠樻鐧昏椤甸潰鎺ュ彛
-import request from '@/utils/request'
+import request from "@/utils/request";
 
 // 鍒嗛〉鏌ヨ
 export function registrationList(query) {
-    return request({
-        url: '/purchase/paymentRegistration/list',
-        method: 'get',
-        params: query
-    })
+  return request({
+    url: "/purchase/paymentRegistration/list",
+    method: "get",
+    params: query,
+  });
 }
 // 鏌ヨ璇︽儏
 export function registrationInfo(query) {
-    return request({
-        url: '/purchase/paymentRegistration/' + query,
-        method: 'get',
-    })
+  return request({
+    url: "/purchase/paymentRegistration/" + query,
+    method: "get",
+  });
 }
 // 鏍规嵁閲囪喘鍚堝悓鍙锋煡璇㈣鎯�
 export function byPurchaseId(query) {
-    return request({
-        url: '/purchase/paymentRegistration/byPurchaseId/' + query,
-        method: 'get',
-    })
+  return request({
+    url: "/purchase/paymentRegistration/byPurchaseId/" + query,
+    method: "get",
+  });
 }
 // 鏌ヨ閲囪喘鍚堝悓鍙�
 export function getPurchaseNo() {
-    return request({
-        url: '/purchase/ledger/getPurchaseNo',
-        method: 'get',
-    })
+  return request({
+    url: "/purchase/ledger/getPurchaseNo",
+    method: "get",
+  });
 }
 // 鏂板
 export function paymentRegistrationAdd(query) {
-    return request({
-        url: '/purchase/paymentRegistration',
-        method: 'post',
-        data: query
-    })
+  return request({
+    url: "/purchase/paymentRegistration",
+    method: "post",
+    data: query,
+  });
 }
 // 淇敼
 export function paymentRegistrationEdit(query) {
-    return request({
-        url: '/purchase/paymentRegistration',
-        method: 'put',
-        data: query
-    })
+  return request({
+    url: "/purchase/paymentRegistration",
+    method: "put",
+    data: query,
+  });
 }
 // 鍒犻櫎
 export function paymentRegistrationDel(query) {
-    return request({
-        url: '/purchase/paymentRegistration/del',
-        method: 'delete',
-        data: query
-    })
+  return request({
+    url: "/purchase/paymentRegistration/delete",
+    method: "delete",
+    data: query,
+  });
 }
 // 鑾峰彇鍙戠エ鍙峰拰鍙戠エ閲戦
-export function getTicketNo(query){
-    return request({
-        url: "/purchase/registration/getTicketNo",
-        method: "get",
-        params: query
-    })
+export function getTicketNo(query) {
+  return request({
+    url: "/purchase/registration/getTicketNo",
+    method: "get",
+    params: query,
+  });
 }
 // 鍒嗛〉鏌ヨ
 export function paymentHistoryList(query) {
-    return request({
-        url: '/purchase/paymentRegistration/paymentHistoryList',
-        method: 'get',
-        params: query
-    })
+  return request({
+    url: "/purchase/paymentRegistration/paymentHistoryList",
+    method: "get",
+    params: query,
+  });
 }
 
 // 鍒嗛〉鏌ヨ
 export function paymentHistoryListPage(query) {
-    return request({
-        url: '/purchase/paymentRegistration/paymentHistoryListPage',
-        method: 'get',
-        params: query
-    })
+  return request({
+    url: "/purchase/paymentRegistration/paymentHistoryListPage",
+    method: "get",
+    params: query,
+  });
 }
diff --git a/src/views/equipmentManagement/ledger/Form.vue b/src/views/equipmentManagement/ledger/Form.vue
index f6cc2cb..4b5308b 100644
--- a/src/views/equipmentManagement/ledger/Form.vue
+++ b/src/views/equipmentManagement/ledger/Form.vue
@@ -27,6 +27,7 @@
             v-model="form.number"
             placeholder="璇疯緭鍏ユ暟閲�"
             type="number"
+            @change="mathNum"
           />
         </el-form-item>
       </el-col>
@@ -36,6 +37,7 @@
             v-model="form.taxIncludingPriceUnit"
             placeholder="璇疯緭鍏ュ惈绋庡崟浠�"
             type="number"
+            @change="mathNum"
           />
         </el-form-item>
       </el-col>
@@ -45,18 +47,29 @@
             v-model="form.taxIncludingPriceTotal"
             placeholder="璇疯緭鍏ュ惈绋庢�讳环"
             type="number"
+            disabled
           />
         </el-form-item>
       </el-col>
       <el-col :span="12">
-        <el-form-item label="绋庣巼" prop="taxRate">
-          <el-input
+        <el-form-item label="绋庣巼(%)" prop="taxRate">
+          <!-- <el-input
             v-model="form.taxRate"
             placeholder="璇疯緭鍏ョ◣鐜�"
             type="number"
           >
             <template #append> % </template>
-          </el-input>
+          </el-input> -->
+          <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">
@@ -65,6 +78,7 @@
             v-model="form.unTaxIncludingPriceTotal"
             placeholder="璇疯緭鍏ヤ笉鍚◣鎬讳环"
             type="number"
+            disabled
           />
         </el-form-item>
       </el-col>
@@ -95,6 +109,11 @@
 // import useUserStore from "@/store/modules/user";
 import { getLedgerById } from "@/api/equipmentManagement/ledger";
 import dayjs from "dayjs";
+import {
+  calculateTaxIncludeTotalPrice,
+  calculateTaxExclusiveTotalPrice,
+} from "@/utils/summarizeTable";
+import { ElMessage } from "element-plus";
 
 defineOptions({
   name: "璁惧鍙拌处琛ㄥ崟",
@@ -130,6 +149,27 @@
   }
 };
 
+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
+    );
+  }
+};
+
 defineExpose({
   form,
   loadForm,
diff --git a/src/views/equipmentManagement/repair/Form/MaintainForm.vue b/src/views/equipmentManagement/repair/Form/MaintainForm.vue
index f946e7e..75e97dd 100644
--- a/src/views/equipmentManagement/repair/Form/MaintainForm.vue
+++ b/src/views/equipmentManagement/repair/Form/MaintainForm.vue
@@ -6,13 +6,13 @@
     <el-form-item label="缁翠慨缁撴灉">
       <el-input v-model="form.maintenanceResult" placeholder="璇疯緭鍏ョ淮淇粨鏋�" />
     </el-form-item>
-    <el-form-item label="缁翠慨缁撴灉">
+    <el-form-item label="缁翠慨鏃ユ湡">
       <el-date-picker
         v-model="form.maintenanceTime"
         placeholder="璇烽�夋嫨缁翠慨鏃ユ湡"
-        format="YYYY-MM-DD"
-        value-format="YYYY-MM-DD"
-        type="date"
+        format="YYYY-MM-DD HH:mm:ss"
+        value-format="YYYY-MM-DD HH:mm:ss"
+        type="datetime"
         clearable
         style="width: 100%"
       />
@@ -22,11 +22,14 @@
 
 <script setup>
 import useFormData from "@/hooks/useFormData";
+import useUserStore from "@/store/modules/user";
+import dayjs from "dayjs";
 
 defineOptions({
   name: "璁惧缁翠慨琛ㄥ崟",
 });
 
+const userStore = useUserStore();
 const { form, resetForm } = useFormData({
   maintenanceName: undefined, // 缁翠慨鍚嶇О
   maintenanceResult: undefined, // 缁翠慨缁撴灉
@@ -34,9 +37,10 @@
 });
 
 const setForm = (data) => {
-  form.maintenanceName = data.maintenanceName;
+  form.maintenanceName = data.maintenanceName ?? userStore.nickName;
   form.maintenanceResult = data.maintenanceResult;
-  form.maintenanceTime = data.maintenanceTime;
+  form.maintenanceTime =
+    data.maintenanceTime ?? dayjs().format("YYYY-MM-DD HH:mm:ss");
 };
 
 const getForm = () => {
diff --git a/src/views/equipmentManagement/repair/index.vue b/src/views/equipmentManagement/repair/index.vue
index 96fb91b..2e75914 100644
--- a/src/views/equipmentManagement/repair/index.vue
+++ b/src/views/equipmentManagement/repair/index.vue
@@ -15,14 +15,14 @@
           <el-button type="success" icon="Van" @click="addRepair">
             鏂板鎶ヤ慨
           </el-button>
-          <el-button
+          <!-- <el-button
             type="danger"
             icon="Delete"
             :disabled="multipleList.length <= 0"
             @click="delRepairByIds(multipleList.map((item) => item.id))"
           >
             鎵归噺鍒犻櫎
-          </el-button>
+          </el-button> -->
         </div>
       </div>
       <PIMTable
@@ -39,7 +39,7 @@
       >
         <template #statusRef="{ row }">
           <el-tag v-if="row.status === 1" type="success">瀹岀粨</el-tag>
-          <el-tag v-if="row.status === 0" type="error">寰呯淮淇�</el-tag>
+          <el-tag v-if="row.status === 0" type="danger">寰呯淮淇�</el-tag>
         </template>
         <template #operation="{ row }">
           <el-button
diff --git a/src/views/equipmentManagement/upkeep/Form/MaintenanceForm.vue b/src/views/equipmentManagement/upkeep/Form/MaintenanceForm.vue
new file mode 100644
index 0000000..4ff0237
--- /dev/null
+++ b/src/views/equipmentManagement/upkeep/Form/MaintenanceForm.vue
@@ -0,0 +1,64 @@
+<template>
+  <el-form :model="form" label-width="100px">
+    <el-form-item label="瀹為檯淇濆吇浜�">
+      <el-input
+        v-model="form.maintenanceActuallyName"
+        placeholder="璇疯緭鍏ュ疄闄呬繚鍏讳汉"
+      ></el-input>
+    </el-form-item>
+    <el-form-item label="瀹為檯淇濆吇鏃ユ湡">
+      <el-date-picker
+        v-model="form.maintenanceActuallyTime"
+        placeholder="璇烽�夋嫨瀹為檯淇濆吇鏃ユ湡"
+        format="YYYY-MM-DD HH:mm:ss"
+        value-format="YYYY-MM-DD HH:mm:ss"
+        type="datetime"
+        clearable
+        style="width: 100%"
+      />
+    </el-form-item>
+    <el-form-item label="淇濆吇缁撴灉">
+      <el-select v-model="form.maintenanceResult" placeholder="璇烽�夋嫨淇濆吇缁撴灉">
+        <el-option label="瀹屽ソ" :value="1"></el-option>
+        <el-option label="缁翠慨" :value="0"></el-option>
+      </el-select>
+    </el-form-item>
+  </el-form>
+</template>
+
+<script setup>
+import useFormData from "@/hooks/useFormData";
+import dayjs from "dayjs";
+import useUserStore from "@/store/modules/user";
+
+defineOptions({
+  name: "淇濆吇琛ㄥ崟",
+});
+
+const userStore = useUserStore();
+const { form, resetForm } = useFormData({
+  maintenanceActuallyName: undefined, // 瀹為檯淇濆吇浜�
+  maintenanceActuallyTime: undefined, // 瀹為檯淇濆吇鏃ユ湡
+  maintenanceResult: undefined, // 淇濆吇缁撴灉
+});
+
+const setForm = (data) => {
+  form.maintenanceActuallyName =
+    data.maintenanceActuallyName ?? userStore.nickName;
+  form.maintenanceActuallyTime =
+    data.maintenanceActuallyTime ?? dayjs().format("YYYY-MM-DD HH:mm:ss");
+  form.maintenanceResult = data.maintenanceResult;
+};
+
+const getForm = () => {
+  return form;
+};
+
+defineExpose({
+  getForm,
+  setForm,
+  resetForm,
+});
+</script>
+
+<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Form/PlanForm.vue b/src/views/equipmentManagement/upkeep/Form/PlanForm.vue
new file mode 100644
index 0000000..a2bd2ce
--- /dev/null
+++ b/src/views/equipmentManagement/upkeep/Form/PlanForm.vue
@@ -0,0 +1,96 @@
+<template>
+  <el-form :model="form" label-width="100px">
+    <el-form-item label="璁惧鍚嶇О">
+      <el-select
+        v-model="form.deviceLedgerId"
+        @change="setDeviceModel"
+        placeholder="璇烽�夋嫨璁惧"
+      >
+        <el-option
+          v-for="(item, index) in deviceOptions"
+          :key="index"
+          :label="item.deviceName"
+          :value="item.id"
+        ></el-option>
+      </el-select>
+    </el-form-item>
+    <el-form-item label="瑙勬牸鍨嬪彿">
+      <el-input
+        v-model="form.deviceModel"
+        placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+        disabled
+      />
+    </el-form-item>
+    <el-form-item label="璁″垝淇濆吇鏃ユ湡">
+      <el-date-picker
+        style="width: 100%"
+        v-model="form.maintenancePlanTime"
+        format="YYYY-MM-DD"
+        value-format="YYYY-MM-DD HH:mm:ss"
+        type="date"
+        placeholder="璇烽�夋嫨璁″垝淇濆吇鏃ユ湡鏃ユ湡"
+        clearable
+      />
+    </el-form-item>
+  </el-form>
+</template>
+
+<script setup>
+import useFormData from "@/hooks/useFormData";
+import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
+import { onMounted } from "vue";
+
+defineOptions({
+  name: "璁″垝琛ㄥ崟",
+});
+
+const deviceOptions = ref([]);
+const loadDeviceName = async () => {
+  const { data } = await getDeviceLedger();
+  deviceOptions.value = data;
+};
+
+const { form, resetForm } = useFormData({
+  deviceLedgerId: undefined, // 璁惧Id
+  deviceName: undefined, // 璁惧鍚嶇О
+  deviceModel: undefined, // 瑙勬牸鍨嬪彿
+  maintenancePlanTime: undefined, // 璁″垝淇濆吇鏃ユ湡
+});
+
+const setDeviceModel = (id) => {
+  const option = deviceOptions.value.find((item) => item.id === id);
+  form.deviceModel = option.deviceModel;
+};
+
+const getForm = () => {
+  return form;
+};
+
+/**
+ * @desc 璁剧疆琛ㄥ崟鍐呭
+ * @param data 璁惧淇℃伅
+ */
+const setForm = (data) => {
+  form.deviceLedgerId = data.deviceLedgerId;
+  form.deviceName = data.deviceName;
+  form.deviceModel = data.deviceModel;
+  form.maintenancePlanTime = dayjs(data.maintenancePlanTime).format(
+    "YYYY-MM-DD HH:mm:ss"
+  );
+};
+
+const loadForm = () => {};
+
+onMounted(() => {
+  loadDeviceName();
+});
+
+defineExpose({
+  loadForm,
+  resetForm,
+  getForm,
+  setForm,
+});
+</script>
+
+<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue b/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue
new file mode 100644
index 0000000..583d627
--- /dev/null
+++ b/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue
@@ -0,0 +1,60 @@
+<template>
+  <el-drawer v-model="visible" :title="modalOptions.title" direction="ltr">
+    <MaintenanceForm ref="maintenanceFormRef" />
+    <template #footer>
+      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
+      <el-button type="primary" @click="sendForm" :loading="loading">
+        {{ modalOptions.confirmText }}
+      </el-button>
+    </template>
+  </el-drawer>
+</template>
+
+<script setup>
+import MaintenanceForm from "../Form/MaintenanceForm.vue";
+import { useModal } from "@/hooks/useModal";
+import { addMaintenance } from "@/api/equipmentManagement/upkeep";
+
+defineOptions({
+  name: "淇濆吇妯℃�佹",
+});
+
+const maintenanceFormRef = ref();
+const emits = defineEmits(["ok"]);
+
+const {
+  id,
+  visible,
+  loading,
+  openModal,
+  modalOptions,
+  handleConfirm,
+  closeModal,
+} = useModal({ title: "璁惧缁翠慨" });
+
+/**
+ * @desc 淇濆瓨淇濆吇
+ */
+const sendForm = async () => {
+  loading.value = true;
+  const form = await maintenanceFormRef.value.getForm();
+  const { code } = await addMaintenance({ id: id.value, ...form });
+  if (code == 200) {
+    emits("ok");
+    maintenanceFormRef.value.resetForm();
+    closeModal();
+  }
+  loading.value = false;
+};
+
+const open = async (id, row) => {
+  openModal(id);
+  await nextTick();
+  maintenanceFormRef.value.setForm(row);
+};
+defineExpose({
+  open,
+});
+</script>
+
+<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Modal/PlanModal.vue b/src/views/equipmentManagement/upkeep/Modal/PlanModal.vue
new file mode 100644
index 0000000..239025a
--- /dev/null
+++ b/src/views/equipmentManagement/upkeep/Modal/PlanModal.vue
@@ -0,0 +1,76 @@
+<template>
+  <el-dialog
+    v-model="visible"
+    :title="modalOptions.title"
+    width="30%"
+    @close="close"
+  >
+    <PlanForm ref="planFormRef"></PlanForm>
+    <template #footer>
+      <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
+      <el-button type="primary" @click="sendForm" :loading="loading">
+        {{ modalOptions.confirmText }}
+      </el-button>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup>
+import { useModal } from "@/hooks/useModal";
+import PlanForm from "../Form/PlanForm";
+import {
+  addUpkeep,
+  editUpkeep,
+  getUpkeepById,
+} from "@/api/equipmentManagement/upkeep";
+import { ElMessage } from "element-plus";
+
+defineOptions({
+  name: "璁惧淇濆吇鏂板璁″垝",
+});
+
+const emits = defineEmits(["ok"]);
+const planFormRef = ref();
+const {
+  id,
+  visible,
+  loading,
+  openModal,
+  modalOptions,
+  handleConfirm,
+  closeModal,
+} = useModal({ title: "璁惧淇濆吇璁″垝" });
+
+const openEdit = async (id) => {
+  const { data } = await getUpkeepById(id);
+  openModal(id);
+  await nextTick();
+  await planFormRef.value.setForm(data);
+};
+
+const sendForm = async () => {
+  loading.value = true;
+  const form = await planFormRef.value.getForm();
+  const { code } = id.value
+    ? await editUpkeep({ id: unref(id), ...form })
+    : await addUpkeep(form);
+  if (code == 200) {
+    ElMessage.success(`${id ? "缂栬緫" : "鏂板"}璁″垝鎴愬姛`);
+    closeModal();
+    emits("ok");
+  }
+  loading.value = false;
+};
+
+const close = () => {
+  planFormRef.value.resetForm();
+  closeModal();
+};
+
+defineExpose({
+  openModal,
+  openEdit,
+});
+</script>
+
+<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/index.vue b/src/views/equipmentManagement/upkeep/index.vue
new file mode 100644
index 0000000..5d3dcd2
--- /dev/null
+++ b/src/views/equipmentManagement/upkeep/index.vue
@@ -0,0 +1,213 @@
+<template>
+  <div class="app-container">
+    <div class="table_list">
+      <div class="actions">
+        <el-text class="mx-1" size="large">璁惧淇濆吇</el-text>
+        <div>
+          <el-button
+            type="primary"
+            icon="Plus"
+            :disabled="multipleList.length !== 1"
+            @click="addMaintain"
+          >
+            鏂板淇濆吇
+          </el-button>
+          <el-button type="success" icon="Van" @click="addPlan">
+            鏂板璁″垝
+          </el-button>
+          <el-button
+            type="danger"
+            icon="Delete"
+            :disabled="multipleList.length <= 0"
+          >
+            鎵归噺鍒犻櫎
+          </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"
+      >
+        <template #maintenanceResultRef="{ row }">
+          <el-tag v-if="row.maintenanceResult === 1" type="success">
+            瀹屽ソ
+          </el-tag>
+          <el-tag v-if="row.maintenanceResult === 0" type="danger">
+            缁翠慨
+          </el-tag>
+        </template>
+        <template #statusRef="{ row }">
+          <el-tag v-if="row.status === 1" type="success">瀹岀粨</el-tag>
+          <el-tag v-if="row.status === 0" type="danger">寰呬繚鍏�</el-tag>
+        </template>
+        <template #operation="{ row }">
+          <el-button
+            type="primary"
+            text
+            icon="editPen"
+            @click="editPlan(row.id)"
+          >
+            缂栬緫
+          </el-button>
+          <el-button
+            type="danger"
+            text
+            icon="delete"
+            @click="delRepairByIds(row.id)"
+          >
+            鍒犻櫎
+          </el-button>
+        </template>
+      </PIMTable>
+    </div>
+    <PlanModal ref="planModalRef" @ok="getTableData" />
+    <MaintenanceModal ref="maintainModalRef" @ok="getTableData" />
+  </div>
+</template>
+
+<script setup>
+import { usePaginationApi } from "@/hooks/usePaginationApi";
+import { getUpkeepPage, delUpkeep } from "@/api/equipmentManagement/upkeep";
+import { onMounted } from "vue";
+import PlanModal from "./Modal/PlanModal.vue";
+import MaintenanceModal from "./Modal/MaintenanceModal.vue";
+import dayjs from "dayjs";
+import { ElMessageBox, ElMessage } from "element-plus";
+
+defineOptions({
+  name: "璁惧淇濆吇",
+});
+
+// 璁″垝寮圭獥鎺у埗鍣�
+const planModalRef = ref();
+// 淇濆吇寮圭獥鎺у埗鍣�
+const maintainModalRef = ref();
+
+// 琛ㄦ牸澶氶�夋閫変腑椤�
+const multipleList = ref([]);
+
+// 澶氶�夊悗鍋氫粈涔�
+const handleSelectionChange = (selectionList) => {
+  multipleList.value = selectionList;
+};
+
+// 琛ㄦ牸閽╁瓙
+const { filters, columns, dataList, pagination, getTableData, resetFilters } =
+  usePaginationApi(getUpkeepPage, {}, [
+    {
+      label: "璁惧鍚嶇О",
+      align: "center",
+      prop: "deviceName",
+    },
+    {
+      label: "瑙勬牸鍨嬪彿",
+      align: "center",
+      prop: "deviceModel",
+    },
+    {
+      label: "璁″垝淇濆吇鏃ユ湡",
+      align: "center",
+      prop: "maintenancePlanTime",
+      formatData: (cell) => dayjs(cell).format("YYYY-MM-DD"),
+    },
+    {
+      label: "褰曞叆浜�",
+      align: "center",
+      prop: "createUserName",
+    },
+    {
+      label: "褰曞叆鏃ユ湡",
+      align: "center",
+      prop: "createTime",
+      formatData: (cell) => dayjs(cell).format("YYYY-MM-DD HH:mm:ss"),
+      width: 200,
+    },
+    {
+      label: "瀹為檯淇濆吇浜�",
+      align: "center",
+      prop: "maintenanceActuallyName",
+    },
+    {
+      label: "瀹為檯淇濆吇鏃ユ湡",
+      align: "center",
+      prop: "maintenanceActuallyTime",
+      formatData: (cell) => dayjs(cell).format("YYYY-MM-DD HH:mm:ss"),
+    },
+    {
+      label: "淇濆吇缁撴灉",
+      align: "center",
+      prop: "maintenanceResult",
+      dataType: "slot",
+      slot: "maintenanceResultRef",
+    },
+    {
+      label: "鐘舵��",
+      align: "center",
+      prop: "status",
+      dataType: "slot",
+      slot: "statusRef",
+    },
+    {
+      fixed: "right",
+      label: "鎿嶄綔",
+      dataType: "slot",
+      slot: "operation",
+      align: "center",
+      width: "200px",
+    },
+  ]);
+
+// 鏂板淇濆吇
+const addMaintain = () => {
+  const row = multipleList.value[0];
+  maintainModalRef.value.open(row.id, row);
+};
+
+// 鏂板璁″垝
+const addPlan = () => {
+  planModalRef.value.openModal();
+};
+
+// 缂栬緫璁″垝
+const editPlan = (id) => {
+  planModalRef.value.openEdit(id);
+};
+
+// 鍗曡鍒犻櫎
+const delRepairByIds = async (ids) => {
+  ElMessageBox.confirm("纭鍒犻櫎鎶ヤ慨鏁版嵁, 姝ゆ搷浣滀笉鍙��?", "璀﹀憡", {
+    confirmButtonText: "纭畾",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(async () => {
+    const { code } = await delUpkeep(ids);
+    if (code === 200) {
+      ElMessage.success("鍒犻櫎鎴愬姛");
+      getTableData();
+    }
+  });
+};
+
+onMounted(() => {
+  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/inventoryManagement/issueManagement/index.vue b/src/views/inventoryManagement/issueManagement/index.vue
index edb60b8..7e9039c 100644
--- a/src/views/inventoryManagement/issueManagement/index.vue
+++ b/src/views/inventoryManagement/issueManagement/index.vue
@@ -40,7 +40,7 @@
       <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
         :page="page.current" :limit="page.size" @pagination="paginationChange" />
     </div>
-    <el-dialog v-model="dialogFormVisible" :title="'鏂板鍑哄簱'" width="70%" @close="closeDia">
+    <el-dialog v-model="dialogFormVisible" :title="'鏂板鍑哄簱'" width="40%" @close="closeDia">
       <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
         <el-form-item label="鍑哄簱鏁伴噺锛�" prop="salesContractNo">
           <el-input v-model="form.salesContractNo" placeholder="璇疯緭鍏�" clearable />
@@ -100,7 +100,6 @@
 const fileList = ref([])
 
 // 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
-const operationType = ref('')
 const dialogFormVisible = ref(false)
 const data = reactive({
   searchForm: {
@@ -184,32 +183,31 @@
 
 // 鎵撳紑寮规
 const openForm = async (row) => {
-  operationType.value = type
-  form.value = {}
-  productData.value = []
-  let userLists = await userListNoPage()
-  userList.value = userLists.data
-  customerList().then(res => {
-    customerOption.value = res
-  })
-  console.log('userStore.id', userStore.id)
-  form.value.entryPerson = userStore.id
-  if (type === 'edit') {
-    currentId.value = row.id;
-    getSalesLedgerWithProducts({ id: row.id, type: 1 }).then(res => {
-      form.value = { ...res }
-      form.value.entryPerson = Number(res.entryPerson)
-      productData.value = form.value.productData
-      fileList.value = form.value.salesLedgerFiles
-    })
-  }
+  // form.value = {}
+  // productData.value = []
+  // let userLists = await userListNoPage()
+  // userList.value = userLists.data
+  // customerList().then(res => {
+  //   customerOption.value = res
+  // })
+  // console.log('userStore.id', userStore.id)
+  // form.value.entryPerson = userStore.id
+  // if (type === 'edit') {
+  //   currentId.value = row.id;
+  //   getSalesLedgerWithProducts({ id: row.id, type: 1 }).then(res => {
+  //     form.value = { ...res }
+  //     form.value.entryPerson = Number(res.entryPerson)
+  //     productData.value = form.value.productData
+  //     fileList.value = form.value.salesLedgerFiles
+  //   })
+  // }
   // let userAll = await userStore.getInfo()
   // userList.value.forEach(element => {
   //   if(userAll.user.nickName === element.nickName && userAll.user.userName === element.userName) {
   //     form.value.entryPerson = userAll.user.userId // 璁剧疆榛樿涓氬姟鍛樹负褰撳墠鐢ㄦ埛
   //   }
   // });
-  form.value.entryDate = getCurrentDate() // 璁剧疆榛樿褰曞叆鏃ユ湡涓哄綋鍓嶆棩鏈�
+  // form.value.entryDate = getCurrentDate() // 璁剧疆榛樿褰曞叆鏃ユ湡涓哄綋鍓嶆棩鏈�
   dialogFormVisible.value = true
 }
 
diff --git a/src/views/procurementManagement/invoiceEntry/index.vue b/src/views/procurementManagement/invoiceEntry/index.vue
index c8ece35..c7376ee 100644
--- a/src/views/procurementManagement/invoiceEntry/index.vue
+++ b/src/views/procurementManagement/invoiceEntry/index.vue
@@ -42,7 +42,7 @@
         :expand-row-keys="expandRowKeys"
         @expand-change="expandChange"
         @selection-change="handleSelectionChange"
-        @pagination="onCurrentChange"
+        @pagination="changePage"
       >
         <template #expand="{ row }">
           <ExpandTable ref="expandTableRef" />
@@ -182,6 +182,11 @@
   expandTableRef.value.getList(row.id);
 };
 
+const changePage = ({ page }) => {
+  pagination.currentPage = page;
+  onCurrentChange(page);
+};
+
 onMounted(() => {
   getTableData();
 });
diff --git a/src/views/procurementManagement/procurementInvoiceLedger/index.vue b/src/views/procurementManagement/procurementInvoiceLedger/index.vue
index 6c8afa3..339b020 100644
--- a/src/views/procurementManagement/procurementInvoiceLedger/index.vue
+++ b/src/views/procurementManagement/procurementInvoiceLedger/index.vue
@@ -56,7 +56,7 @@
           total: 0,
         }"
         @selection-change="handleSelectionChange"
-        @pagination="onCurrentChange"
+        @pagination="changePage"
       >
         <template #commonFilesRef="{ row }">
           <el-button
@@ -238,6 +238,11 @@
   });
 };
 
+const changePage = ({ page }) => {
+  pagination.currentPage = page;
+  onCurrentChange(page);
+};
+
 onMounted(() => {
   getTableData();
 });
diff --git a/src/views/reportAnalysis/projectProfit/index.vue b/src/views/reportAnalysis/projectProfit/index.vue
index bae35bb..c987e3c 100644
--- a/src/views/reportAnalysis/projectProfit/index.vue
+++ b/src/views/reportAnalysis/projectProfit/index.vue
@@ -20,7 +20,7 @@
           size: pagination.pageSize,
           total: pagination.total,
         }"
-        @pagination="onCurrentChange"
+        @pagination="changePage"
       ></PIMTable>
     </div>
   </div>
@@ -93,6 +93,11 @@
   ]
 );
 
+const changePage = ({ page }) => {
+  pagination.currentPage = page;
+  onCurrentChange(page);
+};
+
 onMounted(() => {
   getTableData();
 });
diff --git a/src/views/reportAnalysis/taxComparison/index.vue b/src/views/reportAnalysis/taxComparison/index.vue
index b04ebce..4ed69a5 100644
--- a/src/views/reportAnalysis/taxComparison/index.vue
+++ b/src/views/reportAnalysis/taxComparison/index.vue
@@ -28,7 +28,7 @@
           size: pagination.pageSize,
           total: pagination.total,
         }"
-        @pagination="onCurrentChange"
+        @pagination="changePage"
       />
     </div>
   </div>
@@ -82,6 +82,11 @@
   {}
 );
 
+const changePage = ({ page }) => {
+  pagination.currentPage = page;
+  onCurrentChange(page);
+};
+
 onMounted(() => {
   getTableData();
 });
diff --git a/src/views/salesManagement/invoiceLedger/index.vue b/src/views/salesManagement/invoiceLedger/index.vue
index 08be678..194b86c 100644
--- a/src/views/salesManagement/invoiceLedger/index.vue
+++ b/src/views/salesManagement/invoiceLedger/index.vue
@@ -65,11 +65,13 @@
           label="閿�鍞悎鍚屽彿"
           prop="salesContractNo"
           show-overflow-tooltip
+          width="180"
         />
         <el-table-column
           label="瀹㈡埛鍚堝悓鍙�"
           prop="customerContractNo"
           show-overflow-tooltip
+          width="180"
         />
         <el-table-column
           label="瀹㈡埛鍚嶇О"
@@ -77,9 +79,14 @@
           show-overflow-tooltip
           width="240"
         />
-        <el-table-column label="椤圭洰" prop="projectName" />
+        <el-table-column label="椤圭洰" prop="projectName" width="150" />
         <el-table-column label="浜у搧澶х被" prop="productCategory" />
-        <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
+        <el-table-column
+          label="瑙勬牸鍨嬪彿"
+          prop="specificationModel"
+          width="300"
+          show-overflow-tooltip
+        />
         <el-table-column
           label="鍙戠エ鍙�"
           prop="invoiceNo"
@@ -90,6 +97,7 @@
           prop="invoiceTotal"
           show-overflow-tooltip
           :formatter="formattedNumber"
+          width="120"
         />
         <el-table-column label="绋庣巼(%)" prop="taxRate" show-overflow-tooltip />
         <el-table-column
@@ -102,11 +110,13 @@
           prop="createTime"
           show-overflow-tooltip
           :formatter="formatDate"
+          width="180"
         />
         <el-table-column
           label="寮�绁ㄦ棩鏈�"
           prop="invoiceDate"
           show-overflow-tooltip
+          width="120"
         />
         <el-table-column
           label="鍙戠エ"
diff --git a/src/views/salesManagement/invoiceRegistration/index.vue b/src/views/salesManagement/invoiceRegistration/index.vue
index aeacdb2..f229f81 100644
--- a/src/views/salesManagement/invoiceRegistration/index.vue
+++ b/src/views/salesManagement/invoiceRegistration/index.vue
@@ -154,7 +154,11 @@
           show-overflow-tooltip
           :formatter="formattedNumber"
         />
-        <el-table-column label="鏈紑绁ㄩ噾棰�(鍏�)" show-overflow-tooltip>
+        <el-table-column
+          label="鏈紑绁ㄩ噾棰�(鍏�)"
+          prop="noInvoiceAmountTotal"
+          show-overflow-tooltip
+        >
           <template #default="{ row, column }">
             <el-text type="danger">
               {{ formattedNumber(row, column, row.noInvoiceAmountTotal) }}
@@ -516,8 +520,8 @@
 const summarizeMainTable = (param) => {
   return proxy.summarizeTable(param, [
     "contractAmount",
-    "noInvoiceAmountTotal",
     "invoiceTotal",
+    "noInvoiceAmountTotal",
   ]);
 };
 // 瀛愯〃鍚堣鏂规硶
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index 238501d..7ed2f28 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -43,10 +43,10 @@
             v-model="searchForm.entryDate"
             value-format="YYYY-MM-DD"
             format="YYYY-MM-DD"
-            type="date"
+            type="daterange"
             placeholder="璇烽�夋嫨"
             clearable
-            @change="handleQuery"
+            @change="changeDaterange"
           />
         </el-form-item>
         <el-form-item>
@@ -648,7 +648,12 @@
     customerContractNo: "", // 瀹㈡埛鍚堝悓缂栧彿
     salesContractNo: "", // 閿�鍞悎鍚岀紪鍙�
     projectName: "", // 椤圭洰鍚嶇О
-    entryDate: dayjs().format("YYYY-MM-DD"), // 褰曞叆鏃ユ湡
+    entryDate: [
+      dayjs().format("YYYY-MM-DD"),
+      dayjs().add(1, "day").format("YYYY-MM-DD"),
+    ], // 褰曞叆鏃ユ湡
+    entryDateStart: dayjs().format("YYYY-MM-DD"),
+    entryDateEnd: dayjs().add(1, "day").format("YYYY-MM-DD"),
   },
   form: {
     salesContractNo: "",
@@ -721,6 +726,17 @@
   headers: { Authorization: "Bearer " + getToken() },
 });
 
+const changeDaterange = (value) => {
+  if (value) {
+    searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
+    searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
+  } else {
+    searchForm.entryDateStart = undefined;
+    searchForm.entryDateEnd = undefined;
+  }
+  handleQuery();
+};
+
 // 鏌ヨ鍒楄〃
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
@@ -734,7 +750,8 @@
 };
 const getList = () => {
   tableLoading.value = true;
-  ledgerListPage({ ...searchForm, ...page })
+  const { entryDate, ...rest } = searchForm;
+  ledgerListPage({ ...rest, ...page })
     .then((res) => {
       tableLoading.value = false;
       tableData.value = res.records;
diff --git a/src/views/system/user/profile/userAvatar.vue b/src/views/system/user/profile/userAvatar.vue
index ae36e39..ff1c9ef 100644
--- a/src/views/system/user/profile/userAvatar.vue
+++ b/src/views/system/user/profile/userAvatar.vue
@@ -4,18 +4,9 @@
     <el-dialog :title="title" v-model="open" width="800px" append-to-body @opened="modalOpened" @close="closeDialog">
       <el-row>
         <el-col :xs="24" :md="12" :style="{ height: '350px' }">
-          <vue-cropper
-            ref="cropper"
-            :img="options.img"
-            :info="true"
-            :autoCrop="options.autoCrop"
-            :autoCropWidth="options.autoCropWidth"
-            :autoCropHeight="options.autoCropHeight"
-            :fixedBox="options.fixedBox"
-            :outputType="options.outputType"
-            @realTime="realTime"
-            v-if="visible"
-          />
+          <vue-cropper ref="cropper" :img="options.img" :info="true" :autoCrop="options.autoCrop"
+            :autoCropWidth="options.autoCropWidth" :autoCropHeight="options.autoCropHeight" :fixedBox="options.fixedBox"
+            :outputType="options.outputType" @realTime="realTime" v-if="visible" />
         </el-col>
         <el-col :xs="24" :md="12" :style="{ height: '350px' }">
           <div class="avatar-upload-preview">
@@ -26,15 +17,12 @@
       <br />
       <el-row>
         <el-col :lg="2" :md="2">
-          <el-upload
-            action="#"
-            :http-request="requestUpload"
-            :show-file-list="false"
-            :before-upload="beforeUpload"
-          >
+          <el-upload action="#" :http-request="requestUpload" :show-file-list="false" :before-upload="beforeUpload">
             <el-button>
               閫夋嫨
-              <el-icon class="el-icon--right"><Upload /></el-icon>
+              <el-icon class="el-icon--right">
+                <Upload />
+              </el-icon>
             </el-button>
           </el-upload>
         </el-col>
@@ -94,7 +82,7 @@
 }
 
 /** 瑕嗙洊榛樿涓婁紶琛屼负 */
-function requestUpload() {}
+function requestUpload() { }
 
 /** 鍚戝乏鏃嬭浆 */
 function rotateLeft() {
@@ -133,7 +121,7 @@
     formData.append("avatarfile", data, options.filename)
     uploadAvatar(formData).then(response => {
       open.value = false
-      options.img = import.meta.env.VITE_APP_BASE_API + response.imgUrl
+      options.img = import.meta.env.VITE_APP_BASE_API + '/profile/' + response.imgUrl
       userStore.avatar = options.img
       proxy.$modal.msgSuccess("淇敼鎴愬姛")
       visible.value = false

--
Gitblit v1.9.3