From 5cd5a5baa076377f3136338db7a9336d0d570d33 Mon Sep 17 00:00:00 2001
From: tuqin <tuqin@tuqin.cn>
Date: 星期六, 24 十月 2026 19:47:33 +0800
Subject: [PATCH] feat(hrm): 前端同步新疆中亿装配的人力资源模块
---
src/views/hrm/salary/calculation/index.vue | 99 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 96 insertions(+), 3 deletions(-)
diff --git a/src/views/hrm/salary/calculation/index.vue b/src/views/hrm/salary/calculation/index.vue
index 33a1f36..1636793 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,14 +22,18 @@
previewSalaryCalculation,
revokeSalaryCalculation,
saveSalaryCalculation,
+ updateSalaryCalculation,
} from '#/api/hrm/salary/calculation';
import { getDeptList } from '#/api/system/dept';
import { handleTree } from '#/packages/utils/src';
import { $t } from '#/locales';
import { useGridColumns, useGridFormSchema, usePreviewColumns } from './data';
+import FormModal from './modules/form.vue';
// 鏍哥畻寮圭獥鐩稿叧
+const formModalRef = ref();
+const saving = ref(false);
const calculateVisible = ref(false);
const calculatePeriod = ref<string>();
const calculateDeptId = ref<number>();
@@ -148,19 +152,35 @@
previewData.value = [];
}
-/** 纭钖叕鏍哥畻 */
+/** 鎶婅鍐呯紪杈戠殑鏂囨湰鍊煎綊涓�涓烘暟瀛楀悗鎻愪氦淇濆瓨 */
+async function saveRowEdits(row: any) {
+ const payload: any = { ...row };
+ EDITABLE_NUMBER_FIELDS.forEach((f) => {
+ payload[f] = toNumberOrZero(payload[f]);
+ });
+ await updateSalaryCalculation(payload);
+}
+
+/** 纭钖叕鏍哥畻锛堟柟妗圓锛氱‘璁ゅ墠鍏堜繚瀛樺綋鍓嶈鐨勪慨鏀癸紝閬垮厤銆屾敼浜嗘病淇濆瓨灏辩‘璁ゃ�嶅鑷撮噾棰濅涪澶憋級 */
async function handleConfirm(row: HrmSalaryCalculationApi.SalaryCalculation) {
+ if (row.status === 0) {
+ await saveRowEdits(row);
+ }
await confirmSalary([row.id!]);
message.success('纭鎴愬姛');
handleRefresh();
}
-/** 鎵归噺纭閫変腑鐨勮褰� */
+/** 鎵归噺纭閫変腑鐨勮褰曪紙鍚屾牱鍏堜繚瀛樺嬀閫夌殑寰呯‘璁よ褰曪紝鍐嶇‘璁わ級 */
async function handleBatchConfirm() {
const records = gridApi.grid.getCheckboxRecords() as HrmSalaryCalculationApi.SalaryCalculation[];
if (records.length === 0) {
message.warning('璇烽�夋嫨瑕佺‘璁ょ殑璁板綍');
return;
+ }
+ const pending = records.filter((r) => r.status === 0);
+ for (const row of pending) {
+ await saveRowEdits(row);
}
const ids = records.map((r) => r.id!);
await confirmSalary(ids);
@@ -224,6 +244,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({
@@ -469,6 +538,7 @@
</div>
</Modal>
+ <FormModal ref="formModalRef" @success="handleRefresh" />
<Grid table-title="钖叕鏍哥畻鍒楄〃">
<template #toolbar-tools>
<TableAction
@@ -493,6 +563,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,
@@ -502,6 +579,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) }}
@@ -511,6 +597,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'],
--
Gitblit v1.9.3