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: '缴费基数(未单独维护员工社保档案的员工按此计算)',
      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',