已删除5个文件
已修改7个文件
2406 ■■■■■ 文件已修改
CHDL.bat 451 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
JHHG.bat 451 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
KYZN.bat 451 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
YZFX.bat 451 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ZSJC.bat 451 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/hrm/salary/social-security-scheme/index.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/hrm/salary/calculation/index.vue 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/hrm/salary/social-security-scheme/data.ts 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/hrm/salary/social-security-scheme/index.vue 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/hrm/salary/social-security-scheme/modules/form.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/hrm/salary/tax-rate-config/data.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/hrm/salary/tax-rate-config/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
CHDL.bat
ÎļþÒÑɾ³ý
JHHG.bat
ÎļþÒÑɾ³ý
KYZN.bat
ÎļþÒÑɾ³ý
YZFX.bat
ÎļþÒÑɾ³ý
ZSJC.bat
ÎļþÒÑɾ³ý
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;
src/views/hrm/salary/calculation/index.vue
@@ -2,7 +2,7 @@
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { HrmSalaryCalculationApi } from '#/api/hrm/salary/calculation';
import { ref } from 'vue';
import { ref, watch } from 'vue';
import { Page } from '#/packages/effects/common-ui/src';
import { downloadFileFromBlobPart } from '#/packages/utils/src';
@@ -14,7 +14,6 @@
import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import {
  calculateSalary,
  confirmSalary,
  deleteSalaryCalculation,
  exportSalaryCalculation,
@@ -37,7 +36,6 @@
const previewLoading = ref(false);
const previewData = ref<HrmSalaryCalculationApi.SalaryCalculation[]>([]);
const submitLoading = ref(false);
const calculateLoading = ref(false);
// æ‰“开核算弹窗
async function openCalculateModal() {
@@ -56,25 +54,14 @@
  gridApi.query();
}
/** æ‰§è¡Œè–ªé…¬æ ¸ç®—(自动计算并保存) */
async function handleCalculate() {
  if (!calculatePeriod.value) {
    message.warning('请选择核算周期');
    return;
// æ ¸ç®—成果只允许在「预览 â†’ ä¿å­˜ã€ä¹‹é—´æµè½¬ï¼šæ”¹äº†å‘¨æœŸ/部门就必须重新预览,
// å¦åˆ™ä¼šæŠŠä¸Šä¸€è½®çš„预览结果按新的周期存下去
watch([calculatePeriod, calculateDeptId], () => {
  if (previewData.value.length > 0) {
    previewData.value = [];
    message.info('核算周期或部门已变更,请重新预览数据');
  }
  calculateLoading.value = true;
  try {
    await calculateSalary({
      period: calculatePeriod.value,
      deptId: calculateDeptId.value,
    });
    message.success('薪酬核算执行成功');
    calculateVisible.value = false;
    handleRefresh();
  } finally {
    calculateLoading.value = false;
  }
}
});
/** é¢„览核算数据 */
async function handlePreview() {
@@ -274,7 +261,7 @@
      :maskClosable="false"
    >
      <Alert
        message="两种核算方式:1. æ‰§è¡Œæ ¸ç®— - è‡ªåŠ¨è®¡ç®—å¹¶ä¿å­˜ï¼›2. é¢„览数据 - æ‰‹åŠ¨è°ƒæ•´åŽä¿å­˜"
        message="核算流程:选好核算周期与部门后点「预览数据」→ æ ¸å¯¹/调整各项金额 â†’ ç‚¹ã€Œä¿å­˜æ ¸ç®—」落库"
        type="info"
        show-icon
        style="margin-bottom: 16px"
@@ -303,12 +290,7 @@
          />
        </FormItem>
        <FormItem>
          <a-button type="primary" :loading="calculateLoading" @click="handleCalculate">
            æ‰§è¡Œæ ¸ç®—
          </a-button>
        </FormItem>
        <FormItem>
          <a-button :loading="previewLoading" @click="handlePreview">
          <a-button type="primary" :loading="previewLoading" @click="handlePreview">
            é¢„览数据
          </a-button>
        </FormItem>
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',
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>
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;
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',
    },
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