From 0e9563993ac594b9d89ae5537ebfe60e62a07242 Mon Sep 17 00:00:00 2001
From: tuqin <tuqin@tuqin.cn>
Date: 星期五, 23 十月 2026 12:09:13 +0800
Subject: [PATCH] feat: 薪酬核算列表行内编辑、工单处理人下拉搜索、社保比例两位小数、退货客户可编辑

---
 src/views/hrm/salary/calculation/index.vue |   69 ++++++++++++++++++++++++++++++++++
 1 files changed, 68 insertions(+), 1 deletions(-)

diff --git a/src/views/hrm/salary/calculation/index.vue b/src/views/hrm/salary/calculation/index.vue
index d07d3ea..77e4204 100644
--- a/src/views/hrm/salary/calculation/index.vue
+++ b/src/views/hrm/salary/calculation/index.vue
@@ -7,7 +7,7 @@
 import { Page } from '#/packages/effects/common-ui/src';
 import { downloadFileFromBlobPart } from '#/packages/utils/src';
 
-import { message, Modal, Form, FormItem, DatePicker, TreeSelect, Table, InputNumber, Alert, Tag } from 'ant-design-vue';
+import { message, Modal, Form, FormItem, DatePicker, TreeSelect, Table, Input, InputNumber, Alert, Tag } from 'ant-design-vue';
 
 import { DICT_TYPE } from '#/packages/constants/src';
 import { getDictLabel } from '#/packages/effects/hooks/src';
@@ -22,6 +22,7 @@
   previewSalaryCalculation,
   revokeSalaryCalculation,
   saveSalaryCalculation,
+  updateSalaryCalculation,
 } from '#/api/hrm/salary/calculation';
 import { getDeptList } from '#/api/system/dept';
 import { handleTree } from '#/packages/utils/src';
@@ -32,6 +33,7 @@
 
 // 鏍哥畻寮圭獥鐩稿叧
 const formModalRef = ref();
+const saving = ref(false);
 const calculateVisible = ref(false);
 const calculatePeriod = ref<string>();
 const calculateDeptId = ref<number>();
@@ -226,6 +228,55 @@
 async function handleExport() {
   const data = await exportSalaryCalculation(await gridApi.formApi.getValues());
   downloadFileFromBlobPart({ fileName: '钖叕鏍哥畻琛�.xls', source: data });
+}
+
+/** 鍒楄〃鍙紪杈戠殑鏁板�煎瓧娈� */
+const EDITABLE_NUMBER_FIELDS = [
+  'baseSalary',
+  'performanceSalary',
+  'overtimePay',
+  'mealAllowance',
+  'transportAllowance',
+  'otherAllowance',
+  'socialSecurityDeduction',
+  'housingFundDeduction',
+  'taxDeduction',
+  'otherDeduction',
+  'leaveDeduction',
+  'workDays',
+  'overtimeHours',
+];
+
+/** 鏂囨湰杈撳叆杞暟瀛楋紙绌哄�兼寜 0锛� */
+function toNumberOrZero(val: any) {
+  if (val === '' || val === null || val === undefined) {
+    return 0;
+  }
+  const num = Number(String(val).replace(/,/g, ''));
+  return Number.isNaN(num) ? 0 : num;
+}
+
+/** 淇濆瓨鍒楄〃鍐呰仈淇敼锛堜粎寰呯‘璁ょ姸鎬侊級 */
+async function handleSaveEdits() {
+  const rows = (gridApi.grid.getData() as any[]).filter((r) => r.status === 0);
+  if (rows.length === 0) {
+    message.warning('褰撳墠椤垫病鏈夊緟纭鐨勮褰曞彲淇敼');
+    return;
+  }
+  saving.value = true;
+  try {
+    for (const row of rows) {
+      const payload: any = { ...row };
+      EDITABLE_NUMBER_FIELDS.forEach((f) => {
+        payload[f] = toNumberOrZero(payload[f]);
+      });
+      await updateSalaryCalculation(payload);
+    }
+    message.success(`宸蹭繚瀛� ${rows.length} 鏉℃牳绠楄褰昤);
+    handleRefresh();
+  } finally {
+    saving.value = false;
+  }
 }
 
 const [Grid, gridApi] = useVbenVxeGrid({
@@ -496,6 +547,13 @@
               onClick: handleBatchSave,
             },
             {
+              label: '淇濆瓨淇敼',
+              type: 'primary',
+              auth: ['hrm:salary-calculation:calculate'],
+              loading: saving,
+              onClick: handleSaveEdits,
+            },
+            {
               label: $t('ui.actionTitle.export'),
               type: 'primary',
               icon: ACTION_ICON.DOWNLOAD,
@@ -505,6 +563,15 @@
           ]"
         />
       </template>
+      <template #editableCell="{ row, column }">
+        <Input
+          v-if="row.status === 0"
+          v-model:value="row[column.field]"
+          size="small"
+          :style="{ width: '100%' }"
+        />
+        <span v-else>{{ row[column.field] ?? '' }}</span>
+      </template>
       <template #status="{ row }">
         <Tag :color="row.status === 0 ? 'warning' : row.status === 10 ? 'success' : 'processing'">
           {{ getDictLabel(DICT_TYPE.HRM_SALARY_STATUS, row.status) }}

--
Gitblit v1.9.3