From 5b2222922a23a307a97204a01d7c2ca951855c6f Mon Sep 17 00:00:00 2001
From: tuqin <tuqin@tuqin.cn>
Date: 星期一, 19 十月 2026 10:44:23 +0800
Subject: [PATCH] feat(hrm): 薪酬核算列表新增「修改」,支持自定义各金额字段

---
 src/views/hrm/salary/calculation/data.ts          |    2 
 src/views/hrm/salary/calculation/modules/form.vue |  120 ++++++++++++++++++++++++++++++++++++++++
 src/views/hrm/salary/calculation/index.vue        |   10 +++
 3 files changed, 131 insertions(+), 1 deletions(-)

diff --git a/src/views/hrm/salary/calculation/data.ts b/src/views/hrm/salary/calculation/data.ts
index bd96225..c02d031 100644
--- a/src/views/hrm/salary/calculation/data.ts
+++ b/src/views/hrm/salary/calculation/data.ts
@@ -101,7 +101,7 @@
     },
     {
       title: '鎿嶄綔',
-      width: 120,
+      width: 220,
       fixed: 'right',
       slots: {
         default: 'actions',
diff --git a/src/views/hrm/salary/calculation/index.vue b/src/views/hrm/salary/calculation/index.vue
index 33a1f36..d07d3ea 100644
--- a/src/views/hrm/salary/calculation/index.vue
+++ b/src/views/hrm/salary/calculation/index.vue
@@ -28,8 +28,10 @@
 import { $t } from '#/locales';
 
 import { useGridColumns, useGridFormSchema, usePreviewColumns } from './data';
+import FormModal from './modules/form.vue';
 
 // 鏍哥畻寮圭獥鐩稿叧
+const formModalRef = ref();
 const calculateVisible = ref(false);
 const calculatePeriod = ref<string>();
 const calculateDeptId = ref<number>();
@@ -469,6 +471,7 @@
       </div>
     </Modal>
 
+    <FormModal ref="formModalRef" @success="handleRefresh" />
     <Grid table-title="钖叕鏍哥畻鍒楄〃">
       <template #toolbar-tools>
         <TableAction
@@ -511,6 +514,13 @@
         <TableAction
           :actions="[
             {
+              label: '淇敼',
+              type: 'link',
+              auth: ['hrm:salary-calculation:calculate'],
+              ifShow: row.status === 0,
+              onClick: () => formModalRef.value?.open(row),
+            },
+            {
               label: '纭',
               type: 'link',
               auth: ['hrm:salary-calculation:confirm'],
diff --git a/src/views/hrm/salary/calculation/modules/form.vue b/src/views/hrm/salary/calculation/modules/form.vue
new file mode 100644
index 0000000..6369f76
--- /dev/null
+++ b/src/views/hrm/salary/calculation/modules/form.vue
@@ -0,0 +1,120 @@
+<script lang="ts" setup>
+import type { HrmSalaryCalculationApi } from '#/api/hrm/salary/calculation';
+
+import { computed, ref } from 'vue';
+
+import { message, Modal, Form, FormItem, Input, InputNumber } from 'ant-design-vue';
+
+import { updateSalaryCalculation } from '#/api/hrm/salary/calculation';
+
+const emit = defineEmits(['success']);
+
+const visible = ref(false);
+const loading = ref(false);
+/** 褰撳墠缂栬緫鐨勮褰曪紙鍚墍鏈夊彲缂栬緫瀛楁锛� */
+const current = ref<Record<string, any>>({});
+
+/** 鏀跺叆椤� */
+const incomeFields = [
+  { key: 'baseSalary', label: '鍩烘湰宸ヨ祫' },
+  { key: 'performanceSalary', label: '缁╂晥宸ヨ祫' },
+  { key: 'overtimePay', label: '鍔犵彮璐�' },
+  { key: 'mealAllowance', label: '椁愯ˉ' },
+  { key: 'transportAllowance', label: '浜ら�氳ˉ璐�' },
+  { key: 'otherAllowance', label: '鍏朵粬琛ヨ创' },
+];
+
+/** 鎵i櫎椤� */
+const deductionFields = [
+  { key: 'socialSecurityDeduction', label: '绀句繚鎵f' },
+  { key: 'housingFundDeduction', label: '鍏Н閲戞墸娆�' },
+  { key: 'taxDeduction', label: '涓◣鎵f' },
+  { key: 'otherDeduction', label: '鍏朵粬鎵f' },
+  { key: 'leaveDeduction', label: '璇峰亣鎵f' },
+];
+
+/** 瀹炲彂宸ヨ祫锛堝疄鏃惰绠楋紝涓庡悗绔彛寰勪竴鑷达級 */
+const actualSalary = computed(() => {
+  const num = (v: any) => (v === undefined || v === null || v === '' ? 0 : Number(v));
+  const income = incomeFields.reduce((sum, f) => sum + num(current.value[f.key]), 0);
+  const deduction = deductionFields.reduce((sum, f) => sum + num(current.value[f.key]), 0);
+  return Number((income - deduction).toFixed(2));
+});
+
+function open(row: HrmSalaryCalculationApi.SalaryCalculation) {
+  current.value = { ...row };
+  visible.value = true;
+}
+
+async function handleOk() {
+  loading.value = true;
+  try {
+    await updateSalaryCalculation({
+      ...(current.value as HrmSalaryCalculationApi.SalaryCalculation),
+      actualSalary: actualSalary.value,
+    });
+    message.success('淇敼鎴愬姛');
+    visible.value = false;
+    emit('success');
+  } finally {
+    loading.value = false;
+  }
+}
+
+defineExpose({ open });
+</script>
+
+<template>
+  <Modal
+    v-model:open="visible"
+    :title="`淇敼钖叕鏍哥畻${current.no ? ' - ' + current.no : ''}`"
+    :width="760"
+    :confirm-loading="loading"
+    ok-text="淇濆瓨"
+    cancel-text="鍙栨秷"
+    @ok="handleOk"
+  >
+    <Form layout="vertical" class="mt-2">
+      <div class="mb-2 text-sm font-semibold text-gray-700">鏀跺叆椤�</div>
+      <div class="grid grid-cols-3 gap-x-4">
+        <FormItem v-for="f in incomeFields" :key="f.key" :label="f.label">
+          <InputNumber
+            v-model:value="current[f.key]"
+            :min="0"
+            :precision="2"
+            style="width: 100%"
+          />
+        </FormItem>
+      </div>
+
+      <div class="mb-2 mt-2 text-sm font-semibold text-gray-700">鎵i櫎椤�</div>
+      <div class="grid grid-cols-3 gap-x-4">
+        <FormItem v-for="f in deductionFields" :key="f.key" :label="f.label">
+          <InputNumber
+            v-model:value="current[f.key]"
+            :min="0"
+            :precision="2"
+            style="width: 100%"
+          />
+        </FormItem>
+      </div>
+
+      <div class="mb-2 mt-2 text-sm font-semibold text-gray-700">鑰冨嫟 / 鍏朵粬</div>
+      <div class="grid grid-cols-3 gap-x-4">
+        <FormItem label="鍑哄嫟澶╂暟">
+          <InputNumber v-model:value="current.workDays" :min="0" :max="31" :precision="0" style="width: 100%" />
+        </FormItem>
+        <FormItem label="鍔犵彮鏃堕暱(h)">
+          <InputNumber v-model:value="current.overtimeHours" :min="0" :precision="1" style="width: 100%" />
+        </FormItem>
+        <FormItem label="瀹炲彂宸ヨ祫锛堣嚜鍔ㄨ绠楋級">
+          <Input :value="actualSalary.toFixed(2)" disabled class="font-bold text-green-600" />
+        </FormItem>
+      </div>
+
+      <FormItem label="澶囨敞">
+        <Input.TextArea v-model:value="current.remark" :rows="2" placeholder="璇疯緭鍏ュ娉�" />
+      </FormItem>
+    </Form>
+  </Modal>
+</template>

--
Gitblit v1.9.3