---
url: /dev/reports/salary-table/index.md
---
# 工资表

## 功能概述

工资表用于按工人计算月度工资的明细数据，包含基本工资、岗位津贴、绩效工资、菜金补贴、工龄工资等各项应发项目，以及社保、公积金、个税等各项代扣代缴项目。工资表是工资核算体系的核心报表，直接决定工人的实际收入金额。

## 业务对象

| 业务对象 | 说明 |
| --- | --- |
| 工资计算 | 按工人计算月度工资的核心业务对象 |
| 工资项目 | 工资各组成项目的配置对象 |

**业务场景描述：** 每月末，系统汇总各工人的基本工资、岗位津贴、绩效工资（基于工时和产量考核）、菜金补贴、工龄工资等应发项目，扣除社保、公积金和个人所得税后，计算出每位工人的月度实发工资。工资表支持审核和工资发放流程。

## 实体设计

**工资表实体 (RP\_SalaryTableLine)**

| 字段名称 | 字段编码 | 数据类型 | 必填 | 是否隐藏 | 说明 |
| --- | --- | --- | --- | --- | --- |
| 主键ID | id | 整数 | 自动 | 系统自带 |
| 会计期间 | period | 文本 | 是 | 否 | 会计月份 |
| 车间ID | workshopId | 参照/外键 | 是 | 是 | 关联车间档案ID |
| 部门编码 | deptCode | 参照/外键 | 是 | 是 | 所属部门编码 |
| 工人编码 | workerCode | 文本 | 是 | 否 | 工人工号 |
| 工人姓名 | workerName | 文本 | 是 | 否 | 工人姓名 |
| 工种 | jobType | 文本 | 是 | 否 | 工种分类 |
| 技能等级 | skillLevel | 文本 | 是 | 否 | 初级/中级/高级/技师 |
| 基本工资 | baseSalary | 数值 | 是 | 否 | 基本工资（元）(2位小数) |
| 岗位津贴 | postAllowance | 数值 | 是 | 否 | 岗位津贴（元）(2位小数) |
| 绩效工资 | performanceSalary | 数值 | 是 | 否 | 绩效工资（元）(2位小数) |
| 菜金补贴 | mealAllowance | 数值 | 是 | 否 | 菜金补贴（元）(2位小数) |
| 工龄工资 | senioritySalary | 数值 | 是 | 否 | 工龄工资（元）(2位小数) |
| 其他应发 | otherIncome | 数值 | 是 | 否 | 其他应发项目（元）(2位小数) |
| 应发合计 | totalEarnings | 数值 | 是 | 否 | 应发工资合计(2位小数) |
| 社会保险 | socialInsurance | 数值 | 是 | 否 | 个人承担社保（元）(2位小数) |
| 住房公积金 | housingFund | 数值 | 是 | 否 | 个人承担公积金（元）(2位小数) |
| 个人所得税 | incomeTax | 数值 | 是 | 否 | 个人所得税（元）(2位小数) |
| 其他扣款 | otherDeduction | 数值 | 是 | 否 | 其他扣款（元）(2位小数) |
| 扣款合计 | totalDeduction | 数值 | 是 | 否 | 扣款合计(2位小数) |
| 实发工资 | netSalary | 数值 | 是 | 否 | 实发工资(2位小数) |
| 银行账号 | bankAccount | 文本 | 否 | 否 | 工资发放银行账号 |
| 计算状态 | calcStatus | 枚举 | 是 | 否 | 0-未计算/1-已计算/2-已审核/3-已发放 |
| 备注 | remark | 文本 | 否 | 否 | 备注说明 |
| 创建人 | createBy | 文本 | 自动 | 是 | 创建人 |
| 创建时间 | createTime | 日期时间 | 自动 | 是 | 创建时间 |
| 更新人 | updateBy | 文本 | 自动 | 是 | 更新人 |
| 更新时间 | updateTime | 日期时间 | 自动 | 是 | 更新时间 |
| 组织ID | orgId | 参照/外键 | 是 | 是 | 所属组织ID |

## 页面设计

### 页面布局

工资表页面采用多视图切换设计，支持明细表视图、汇总表视图和工资条视图。

**顶部筛选区：**

* 会计期间选择器
* 车间多选下拉框
* 部门筛选
* 工人编码/姓名搜索
* 计算状态筛选
* "执行计算"按钮
* "批量审核"按钮
* "发放"按钮
* 导出工资条功能

**明细表视图：**

* 按车间分组展示工人工资明细
* 同一车间内按部门、工号排序
* 工资项目分色标识（应发项目绿色、扣款项目红色）
* 实发工资列高亮显示
* 支持行内编辑备注

**汇总表视图：**

* 按车间、部门汇总工资数据
* 显示各工资项目的合计和平均值
* 支持按车间对比

**工资条视图：**

* 单个工人工资条展示
* 支持批量打印
* 显示工资条历史趋势

**底部汇总区：**

* 全厂工资合计
* 各车间工资占比
* 平均工资
* 应发/扣款/实发合计

### 核心组件

* **报表设计器：** 配置多级分组、条件格式和汇总规则
* **智能分析：** 基于语义模型自动分析工资构成，识别异常波动
* **个税计算器：** 集成个税计算引擎，自动计算月度个税
* **银行对接：** 支持工资发放数据导出至银行代发格式
* **批量审核：** 支持工资数据的批量审核和审批流

### 交互规则

1. 页面加载时自动加载当前期间的工资数据
2. 点击"执行计算"按钮触发工资计算流程
3. 点击"批量审核"按钮进入批量审核模式
4. 点击"发放"按钮生成银行代发数据
5. 工资数据支持明细编辑（备注），但金额需通过重计算修改

## 前端脚本

```javascript
// 切换视图
function onViewChange(viewType) {
    if (viewType === 'detail') {
        renderDetailView();
    } else if (viewType === 'summary') {
        renderSummaryView();
    } else if (viewType === 'payslip') {
        renderPayslipView();
    }
}

// 执行工资计算
async function onClickCalc() {
    const period = getFilterValue('period');
    const workshop = getFilterValue('workshop');
    showLoading('正在计算工资...');
    try {
        const result = await calculateSalary(period, workshop);
        renderDetailView(result.data);
        renderSummaryView(result.summary);
        showToast('工资计算完成');
    } catch (e) {
        showError('计算失败：' + e.message);
    } finally {
        hideLoading();
    }
}

// 批量审核
async function onClickBatchApprove() {
    const selectedRows = getSelectedRows();
    if (selectedRows.length === 0) {
        showWarning('请先选择要审核的记录');
        return;
    }
    showConfirm('确认审核选中的 ' + selectedRows.length + ' 条工资记录？', async () => {
        try {
            await approveSalaryData(selectedRows);
            showToast('审核成功');
            refreshTable();
        } catch (e) {
            showError('审核失败：' + e.message);
        }
    });
}

// 工资发放
async function onClickDispatch() {
    const period = getFilterValue('period');
    showConfirm('确认发放 ' + period + ' 月度工资？', async () => {
        try {
            await dispatchSalary(period);
            showToast('工资发放数据已生成');
        } catch (e) {
            showError('发放失败：' + e.message);
        }
    });
}

// 个税计算
function calcIncomeTax(taxableIncome) {
    const brackets = [
        { limit: 3000, rate: 0.03, deduct: 0 },
        { limit: 12000, rate: 0.10, deduct: 210 },
        { limit: 25000, rate: 0.20, deduct: 1410 },
        { limit: 35000, rate: 0.25, deduct: 2660 },
        { limit: 55000, rate: 0.30, deduct: 4410 },
        { limit: 80000, rate: 0.35, deduct: 7160 },
        { limit: Infinity, rate: 0.45, deduct: 15160 }
    ];
    for (const b of brackets) {
        if (taxableIncome <= b.limit) {
            return taxableIncome * b.rate - b.deduct;
        }
    }
    return 0;
}
```

**计算触发时机：**

* 页面加载时自动加载已有计算数据
* 用户点击"执行计算"按钮手动触发
* 支持按车间单独计算或全车间计算

## 后端脚本

### YonQL 查询

```sql
-- 查询工人基本工资
SELECT 
    WorkerCode,
    BaseSalary,
    PostAllowance
FROM WorkerSalaryStandard
WHERE IsActive = 1

-- 查询绩效工资（基于工时）
SELECT 
    WorkerCode,
    PerformanceAmount
FROM PerformanceSalary
WHERE Period = #{period}

-- 查询菜金补贴
SELECT 
    WorkerCode,
    MealAmount
FROM MealTable
WHERE Period = #{period}

-- 查询工龄工资
SELECT 
    WorkerCode,
    SeniorityAmount
FROM SenioritySalary
WHERE Period = #{period}

-- 查询社保公积金
SELECT 
    WorkerCode,
    SocialInsurance,
    HousingFund
FROM WorkerInsurance
WHERE Period = #{period}
```

### 报表计算逻辑

```javascript
async function calculateSalary(period, workshop) {
    // 1. 获取工人基础数据
    const workers = await queryWorkers(period, workshop);
    
    // 2. 获取各工资项目数据
    const baseSalaries = await queryBaseSalary();
    const performanceData = await queryPerformanceSalary(period, workshop);
    const mealData = await queryMealAllowance(period, workshop);
    const seniorityData = await querySenioritySalary(period, workshop);
    const insuranceData = await queryInsurance(period, workshop);
    
    // 3. 逐工人计算工资
    for (const worker of workers) {
        const base = baseSalaries.find(b => b.WorkerCode === worker.WorkerCode);
        const perf = performanceData.find(p => p.WorkerCode === worker.WorkerCode);
        const meal = mealData.find(m => m.WorkerCode === worker.WorkerCode);
        const seniority = seniorityData.find(s => s.WorkerCode === worker.WorkerCode);
        const insurance = insuranceData.find(i => i.WorkerCode === worker.WorkerCode);
        
        const totalEarnings = (base?.BaseSalary || 0) 
                            + (base?.PostAllowance || 0)
                            + (perf?.PerformanceAmount || 0)
                            + (meal?.MealAmount || 0)
                            + (seniority?.SeniorityAmount || 0);
        
        const socialIns = insurance?.SocialInsurance || 0;
        const housingFund = insurance?.HousingFund || 0;
        const taxableIncome = totalEarnings - socialIns - housingFund - 5000;
        const incomeTax = calcIncomeTax(Math.max(0, taxableIncome));
        const totalDeduction = socialIns + housingFund + incomeTax;
        const netSalary = totalEarnings - totalDeduction;
        
        await saveSalary({
            Period: period,
            Workshop: worker.Workshop,
            WorkerCode: worker.WorkerCode,
            WorkerName: worker.WorkerName,
            BaseSalary: base?.BaseSalary || 0,
            PostAllowance: base?.PostAllowance || 0,
            PerformanceSalary: perf?.PerformanceAmount || 0,
            MealAllowance: meal?.MealAmount || 0,
            SenioritySalary: seniority?.SeniorityAmount || 0,
            TotalEarnings: totalEarnings,
            SocialInsurance: socialIns,
            HousingFund: housingFund,
            IncomeTax: incomeTax,
            TotalDeduction: totalDeduction,
            NetSalary: netSalary,
            CalcStatus: '已计算'
        });
    }
    
    // 4. 汇总和同步
    await summarizeSalary(period, workshop);
}
```

### 数据汇总

工资表按车间和部门汇总工资数据，生成工资总表数据。工资计算完成后，数据传递至工资总表进行车间级汇总，同时生成银行代发数据。

## 报表配置

### 报表数据源配置

| 配置项 | 说明 |
| --- | --- |
| 主数据源 | 工资表实体 (RP\_SalaryTableLine) |
| 关联数据源 | 工人档案、工资标准、绩效工资、菜金表、工龄工资表、社保数据 |
| 数据类型 | 计算类报表 |
| 语义模型 | 基于"工人-工资项目-期间"三维工资语义模型 |

### 过滤条件

* 会计期间：必选
* 车间：可选，多选
* 部门：可选
* 工人编码/姓名：可选
* 计算状态：可选

### 分组统计

* **一级分组：** 车间
* **二级分组：** 部门
* **三级分组：** 工种
* **汇总指标：** 各工资项目合计、应发合计、扣款合计、实发合计

## 数据权限

### 功能权限

| 角色 | 查看 | 计算 | 审核 | 发放 | 导出 |
| --- | --- | --- | --- | --- | --- |
| 车间主任 | ✅ | ✅ | ✅ | ❌ | ✅ |
| 人事人员 | ✅ | ✅ | ✅ | ❌ | ✅ |
| 财务人员 | ✅ | ❌ | ❌ | ✅ | ✅ |
| 系统管理员 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 普通用户 | ❌ | ❌ | ❌ | ❌ | ❌ |

### 数据权限规则

1. 车间主任可查看本车间工资数据并执行计算和审核
2. 人事人员可查看全公司工资数据并执行计算和审核
3. 财务人员可查看全公司工资数据并执行发放操作
4. 系统管理员拥有全部权限
5. 工资数据为敏感数据，所有操作需记录详细日志
6. 工资数据审核后不可修改，需重新计算
