From 6da23f82d453e55ea9ae303c582fbdf8ca32250a Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期三, 14 十月 2026 15:22:19 +0800
Subject: [PATCH] feat(hrm): 社保公积金方案表单加「适用部门」与默认缴费基数,修比例输入精度

---
 src/views/hrm/salary/social-security-scheme/index.vue        |    4 ++
 src/views/hrm/salary/social-security-scheme/modules/form.vue |    1 
 src/views/hrm/salary/social-security-scheme/data.ts          |   83 +++++++++++++++++++++++++++++++++++++----
 src/api/hrm/salary/social-security-scheme/index.ts           |    8 ++++
 src/views/hrm/salary/tax-rate-config/data.ts                 |   11 ++++-
 src/views/hrm/salary/tax-rate-config/index.vue               |    6 ++
 6 files changed, 102 insertions(+), 11 deletions(-)

diff --git a/src/api/hrm/salary/social-security-scheme/index.ts b/src/api/hrm/salary/social-security-scheme/index.ts
index 4b1c69a..10ba4dc 100644
--- a/src/api/hrm/salary/social-security-scheme/index.ts
+++ b/src/api/hrm/salary/social-security-scheme/index.ts
@@ -18,6 +18,14 @@
     maternityRatio?: number;
     housingFundCompanyRatio?: number;
     housingFundPersonalRatio?: number;
+    /** 榛樿绀句繚缂磋垂鍩烘暟锛堜笉濉垯鐢ㄥ憳宸ュ熀鏈伐璧勶級 */
+    defaultSocialSecurityBase?: number;
+    /** 榛樿鍏Н閲戠即璐瑰熀鏁帮紙涓嶅~鎴� 0 鍒欑敤绀句繚鍩烘暟锛� */
+    defaultHousingFundBase?: number;
+    /** 閫傜敤閮ㄩ棬ID鍒楄〃锛堜负绌鸿〃绀哄叏灞�榛樿鏂规锛� */
+    deptIds?: number[];
+    /** 閫傜敤閮ㄩ棬鍚嶇О锛屽涓敤銆佸垎闅旓紙涓虹┖琛ㄧず鍏ㄥ眬榛樿锛� */
+    deptNames?: string;
     status?: number;
     remark?: string;
     createTime?: string;
diff --git a/src/views/hrm/salary/social-security-scheme/data.ts b/src/views/hrm/salary/social-security-scheme/data.ts
index 2e363b8..ca3a759 100644
--- a/src/views/hrm/salary/social-security-scheme/data.ts
+++ b/src/views/hrm/salary/social-security-scheme/data.ts
@@ -2,15 +2,26 @@
 import type { VxeTableGridOptions } from '#/adapter/vxe-table';
 import type { HrmSocialSecuritySchemeApi } from '#/api/hrm/salary/social-security-scheme';
 
+import { getDeptList } from '#/api/system/dept';
+import { handleTree } from '#/packages/utils/src';
+
 /** 琛ㄥ崟绫诲瀷 */
 export type FormType = 'create' | 'update';
 
-/** 鏍煎紡鍖栨瘮渚嬭緭鍏� */
-function createRatioFormatter(step: number = 0.01) {
+/**
+ * 鏍煎紡鍖栨瘮渚嬭緭鍏ワ細鏄剧ず鍊硷紙8.5%锛変笌瀛樺偍鍊硷紙0.085锛変簰杞�
+ *
+ * 淇濈暀 2 浣嶇櫨鍒嗘瘮灏忔暟锛屾濂藉搴旀暟鎹簱 decimal(5,4) 鐨� 4 浣嶅皬鏁扮簿搴︼紝
+ * 閬垮厤 8.5% 琚洓鑸嶄簲鍏ユ垚 9% 鍚庡啓鍥� 0.09銆�
+ */
+function createRatioFormatter() {
   return {
-    formatter: (value: number) => value !== undefined && value !== null ? `${(value * 100).toFixed(step === 0.001 ? 1 : 0)}%` : '',
+    formatter: (value: number) =>
+      value !== undefined && value !== null
+        ? `${Number((value * 100).toFixed(2))}%`
+        : '',
     parser: (value: string) => {
-      const num = parseFloat(value.replace('%', ''));
+      const num = parseFloat(String(value).replace('%', ''));
       return isNaN(num) ? 0 : num / 100;
     },
   };
@@ -59,6 +70,27 @@
         ],
       },
       rules: 'required',
+    },
+    {
+      fieldName: 'deptIds',
+      label: '閫傜敤閮ㄩ棬',
+      component: 'ApiTreeSelect',
+      componentProps: {
+        api: async () => {
+          const data = await getDeptList();
+          return handleTree(data);
+        },
+        labelField: 'name',
+        valueField: 'id',
+        childrenField: 'children',
+        multiple: true,
+        treeCheckable: true,
+        showCheckedStrategy: 'SHOW_ALL',
+        allowClear: true,
+        treeDefaultExpandAll: true,
+        placeholder: '涓嶉�夎〃绀哄叏灞�榛樿鏂规锛涘彧瀵规墍閫夐儴闂ㄦ湰绾х殑鍛樺伐鐢熸晥',
+      },
+      formItemClass: 'col-span-2',
     },
     // 鍏昏�佷繚闄�
     {
@@ -148,7 +180,7 @@
         step: 0.001,
         precision: 4,
         style: { width: '100%' },
-        ...createRatioFormatter(0.001),
+        ...createRatioFormatter(),
       },
     },
     {
@@ -162,7 +194,7 @@
         step: 0.001,
         precision: 4,
         style: { width: '100%' },
-        ...createRatioFormatter(0.001),
+        ...createRatioFormatter(),
       },
     },
     // 宸ヤ激/鐢熻偛淇濋櫓
@@ -183,7 +215,7 @@
         step: 0.001,
         precision: 4,
         style: { width: '100%' },
-        ...createRatioFormatter(0.001),
+        ...createRatioFormatter(),
       },
     },
     {
@@ -197,7 +229,7 @@
         step: 0.001,
         precision: 4,
         style: { width: '100%' },
-        ...createRatioFormatter(0.001),
+        ...createRatioFormatter(),
       },
     },
     // 鍏Н閲�
@@ -233,6 +265,35 @@
         precision: 4,
         style: { width: '100%' },
         ...createRatioFormatter(),
+      },
+    },
+    // 缂磋垂鍩烘暟
+    {
+      fieldName: 'divider_base',
+      label: '缂磋垂鍩烘暟锛堟湭鍗曠嫭缁存姢鍛樺伐绀句繚妗f鐨勫憳宸ユ寜姝よ绠楋級',
+      component: 'Divider',
+      formItemClass: 'col-span-2',
+    },
+    {
+      fieldName: 'defaultSocialSecurityBase',
+      label: '榛樿绀句繚鍩烘暟',
+      component: 'InputNumber',
+      componentProps: {
+        placeholder: '鐣欑┖鍒欑敤鍛樺伐鍩烘湰宸ヨ祫',
+        min: 0,
+        precision: 2,
+        style: { width: '100%' },
+      },
+    },
+    {
+      fieldName: 'defaultHousingFundBase',
+      label: '榛樿鍏Н閲戝熀鏁�',
+      component: 'InputNumber',
+      componentProps: {
+        placeholder: '鐣欑┖鎴� 0 鍒欑敤绀句繚鍩烘暟',
+        min: 0,
+        precision: 2,
+        style: { width: '100%' },
       },
     },
     // 澶囨敞
@@ -281,6 +342,12 @@
 export function useGridColumns(): VxeTableGridOptions<HrmSocialSecuritySchemeApi.SocialSecurityScheme>['columns'] {
   return [
     { field: 'name', title: '鏂规鍚嶇О', minWidth: 180 },
+    {
+      field: 'deptNames',
+      title: '閫傜敤閮ㄩ棬',
+      minWidth: 160,
+      slots: { default: 'deptNames' },
+    },
     { field: 'effectiveDate', title: '鐢熸晥鏃ユ湡', width: 110 },
     {
       field: 'pensionCompanyRatio',
diff --git a/src/views/hrm/salary/social-security-scheme/index.vue b/src/views/hrm/salary/social-security-scheme/index.vue
index 65c71b5..245d58f 100644
--- a/src/views/hrm/salary/social-security-scheme/index.vue
+++ b/src/views/hrm/salary/social-security-scheme/index.vue
@@ -95,6 +95,10 @@
           ]"
         />
       </template>
+      <template #deptNames="{ row }">
+        <span v-if="row.deptNames">{{ row.deptNames }}</span>
+        <Tag v-else color="blue">鍏ㄥ眬榛樿</Tag>
+      </template>
       <template #pensionCompanyRatio="{ row }">
         {{ formatRatio(row.pensionCompanyRatio) }}
       </template>
diff --git a/src/views/hrm/salary/social-security-scheme/modules/form.vue b/src/views/hrm/salary/social-security-scheme/modules/form.vue
index 9611251..8a94d6d 100644
--- a/src/views/hrm/salary/social-security-scheme/modules/form.vue
+++ b/src/views/hrm/salary/social-security-scheme/modules/form.vue
@@ -81,6 +81,7 @@
         maternityRatio: 0.005,
         housingFundCompanyRatio: 0.12,
         housingFundPersonalRatio: 0.12,
+        deptIds: [],
         status: 0,
       });
       return;
diff --git a/src/views/hrm/salary/tax-rate-config/data.ts b/src/views/hrm/salary/tax-rate-config/data.ts
index 2765700..f7a4571 100644
--- a/src/views/hrm/salary/tax-rate-config/data.ts
+++ b/src/views/hrm/salary/tax-rate-config/data.ts
@@ -60,8 +60,15 @@
         max: 1,
         step: 0.01,
         precision: 4,
-        formatter: (value: number) => `${(value * 100).toFixed(0)}%`,
-        parser: (value: string) => parseFloat(value.replace('%', '')) / 100,
+        // 淇濈暀 2 浣嶇櫨鍒嗘瘮灏忔暟锛堝搴� decimal(5,4) 鐨� 4 浣嶅皬鏁帮級锛岄伩鍏� 3.5% 琚洓鑸嶄簲鍏ユ垚 4%
+        formatter: (value: number) =>
+          value === undefined || value === null
+            ? ''
+            : `${Number((value * 100).toFixed(2))}%`,
+        parser: (value: string) => {
+          const num = parseFloat(String(value).replace('%', ''));
+          return isNaN(num) ? 0 : num / 100;
+        },
       },
       rules: 'required',
     },
diff --git a/src/views/hrm/salary/tax-rate-config/index.vue b/src/views/hrm/salary/tax-rate-config/index.vue
index 55a2fde..0f6f3e6 100644
--- a/src/views/hrm/salary/tax-rate-config/index.vue
+++ b/src/views/hrm/salary/tax-rate-config/index.vue
@@ -88,7 +88,11 @@
         {{ row.minAmount }} ~ {{ row.maxAmount === 0 ? '鈭�' : row.maxAmount }}
       </template>
       <template #taxRate="{ row }">
-        {{ (row.taxRate * 100).toFixed(0) }}%
+        {{
+          row.taxRate === undefined || row.taxRate === null
+            ? '-'
+            : `${Number((row.taxRate * 100).toFixed(2))}%`
+        }}
       </template>
       <template #actions="{ row }">
         <TableAction

--
Gitblit v1.9.3