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

## 功能概述

工龄工资表用于按工人工龄计算工龄工资的明细数据，根据工人的工作年限和对应的工龄工资标准计算每月应得的工龄工资。工龄工资表是工资核算体系的组成部分，工龄工资作为工资中的固定应发项目，体现了对工人长期服务的激励。

## 业务对象

| 业务对象 | 说明 |
| --- | --- |
| 工龄工资计算 | 按工人工龄计算工龄工资的核心业务对象 |
| 工龄标准 | 工龄工资计算标准的配置对象 |

**业务场景描述：** 每月末，系统根据每位工人的实际工作年限，对照工龄标准表中各工龄区间的工资标准，计算出每位工人应得的工龄工资。新入职工人按月折算工龄工资。工龄工资计算完成后传递至工资表。

## 实体设计

**工龄工资表实体 (RP\_SenioritySalaryLine)**

| 字段名称 | 字段编码 | 数据类型 | 必填 | 是否隐藏 | 说明 |
| --- | --- | --- | --- | --- | --- |
| 主键ID | id | 整数 | 自动 | 系统自带 |
| 会计期间 | period | 文本 | 是 | 否 | 会计月份 |
| 车间ID | workshopId | 参照/外键 | 是 | 是 | 关联车间档案ID |
| 工人编码 | workerCode | 文本 | 是 | 否 | 工人工号 |
| 工人姓名 | workerName | 文本 | 是 | 否 | 工人姓名 |
| 入职日期 | hireDate | 日期 | 是 | 否 | 工人入职日期 |
| 工龄（年） | seniorityYears | 数值 | 是 | 否 | 实际工作年限(2位小数) |
| 工龄档次 | seniorityLevel | 文本 | 是 | 否 | 1年以下/1-3年/3-5年/5-10年/10年以上 |
| 标准工龄工资 | standardAmount | 数值 | 是 | 否 | 对应档次的标准工龄工资（元）(2位小数) |
| 调整系数 | adjustFactor | 数值 | 是 | 否 | 工龄调整系数（新入职折算）(2位小数) |
| 工龄工资 | seniorityAmount | 数值 | 是 | 否 | 实际应发工龄工资（元）(2位小数) |
| 计算状态 | calcStatus | 枚举 | 是 | 否 | 0-未计算/1-已计算 |
| 备注 | remark | 文本 | 否 | 否 | 备注说明 |
| 创建人 | createBy | 文本 | 自动 | 是 | 创建人 |
| 创建时间 | createTime | 日期时间 | 自动 | 是 | 创建时间 |
| 更新人 | updateBy | 文本 | 自动 | 是 | 更新人 |
| 更新时间 | updateTime | 日期时间 | 自动 | 是 | 更新时间 |
| 组织ID | orgId | 参照/外键 | 是 | 是 | 所属组织ID |

## 页面设计

### 页面布局

工龄工资表页面采用人员明细报表布局，由筛选区、人员工龄工资列表区和汇总区组成。

**顶部筛选区：**

* 会计期间选择器
* 车间多选下拉框
* 工龄档次筛选
* 工人编码/姓名搜索
* "执行计算"按钮
* 工龄标准设置按钮
* 导出功能

**中间人员工龄工资列表区：**

* 按车间分组展示工人工龄工资明细
* 同一车间内按工龄档次排序
* 工龄档次用不同颜色标识（绿色低档→红色高档）
* 调整系数异常值高亮标注
* 支持点击查看工龄标准详情

**底部汇总区：**

* 各车间工龄工资合计
* 各工龄档次人数分布
* 平均工龄工资
* 工龄工资占工资总额比例

### 核心组件

* **报表设计器：** 配置多级分组、条件格式和汇总规则
* **智能分析：** 基于语义模型自动分析工龄工资分布，识别异常
* **工龄标准管理：** 支持快速进入工龄标准配置页面
* **数据联动：** 工龄工资计算结果自动联动至工资表

### 交互规则

1. 页面加载时自动加载当前期间的工龄工资数据
2. 点击"执行计算"按钮按工人工龄和标准计算工龄工资
3. 点击"工龄标准设置"按钮跳转至工龄标准配置页面
4. 支持按车间单独计算或全车间计算
5. 新入职工人的调整系数自动按月折算

## 前端脚本

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

// 跳转工龄标准设置
function onGoStandard() {
    navigateTo('/basic-data/seniority-standard');
}

// 工人搜索
async function onWorkerSearch() {
    const keyword = getSearchValue();
    const data = await searchSeniorityData(keyword);
    renderTable(data);
}

// 工龄档次筛选变更
async function onLevelChange() {
    const period = getFilterValue('period');
    const level = getFilterValue('level');
    const data = await loadSeniorityData(period, level);
    renderTable(data);
}

// 调整系数计算
function calcAdjustFactor(hireDate, period) {
    const monthsInPeriod = new Date(period).getMonth();
    const hireMonth = new Date(hireDate).getMonth();
    if (monthsInPeriod < 12) {
        return monthsInPeriod / 12;
    }
    return 1;
}
```

**计算触发时机：**

* 页面加载时自动加载已有计算数据
* 用户点击"执行计算"按钮手动触发
* 支持按车间单独计算或全车间计算
* 工龄标准变更后需重新计算

## 后端脚本

### YonQL 查询

```sql
-- 查询工人入职日期
SELECT 
    WorkerCode,
    WorkerName,
    Workshop,
    HireDate
FROM WorkerInfo
WHERE IsActive = 1

-- 查询工龄工资标准
SELECT 
    SeniorityLevel,
    MinYears,
    MaxYears,
    Amount AS StandardAmount
FROM SeniorityStandard
WHERE IsActive = 1
ORDER BY MinYears
```

### 报表计算逻辑

```javascript
async function calculateSenioritySalary(period, workshop) {
    // 1. 获取工人信息
    const workers = await queryActiveWorkers(period, workshop);
    
    // 2. 获取工龄工资标准
    const standards = await querySeniorityStandards();
    
    // 3. 逐工人计算工龄工资
    for (const worker of workers) {
        const hireDate = new Date(worker.HireDate);
        const periodDate = new Date(period);
        const seniorityYears = (periodDate - hireDate) / (365 * 24 * 3600);
        
        // 确定工龄档次
        let level = '1年以下';
        let standardAmount = 0;
        for (const std of standards) {
            if (seniorityYears >= std.MinYears && seniorityYears < std.MaxYears) {
                level = std.SeniorityLevel;
                standardAmount = std.StandardAmount;
                break;
            }
        }
        
        // 计算调整系数
        let adjustFactor = 1;
        if (seniorityYears < 1) {
            const months = Math.floor(seniorityYears * 12);
            adjustFactor = months / 12;
        }
        
        const seniorityAmount = standardAmount * adjustFactor;
        
        await saveSenioritySalary({
            Period: period,
            Workshop: worker.Workshop,
            WorkerCode: worker.WorkerCode,
            WorkerName: worker.WorkerName,
            HireDate: worker.HireDate,
            SeniorityYears: seniorityYears,
            SeniorityLevel: level,
            StandardAmount: standardAmount,
            AdjustFactor: adjustFactor,
            SeniorityAmount: seniorityAmount,
            CalcStatus: '已计算'
        });
    }
    
    // 4. 汇总计算
    await summarizeSeniority(period, workshop);
    
    // 5. 联动至工资表
    await syncToSalaryTable(period, workshop);
}
```

### 数据汇总

工龄工资表按车间和工龄档次汇总工龄工资，生成各车间工龄工资合计和工龄分布数据。计算完成后数据同步至工资表，作为工资组成部分。工龄工资数据同时纳入人工成本分析。

## 报表配置

### 报表数据源配置

| 配置项 | 说明 |
| --- | --- |
| 主数据源 | 工龄工资表实体 (RP\_SenioritySalaryLine) |
| 关联数据源 | 工人档案、工龄标准、车间档案 |
| 数据类型 | 计算类报表 |
| 语义模型 | 基于"工人-工龄-标准"三维工龄工资语义模型 |

### 过滤条件

* 会计期间：必选
* 车间：可选，多选
* 工龄档次：可选
* 工人编码/姓名：可选

### 分组统计

* **一级分组：** 车间
* **二级分组：** 工龄档次
* **汇总指标：** 工人人数、工龄工资合计、平均工龄工资

## 数据权限

### 功能权限

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

### 数据权限规则

1. 车间主任可查看本车间工龄工资数据并执行计算
2. 人事人员可查看全公司工龄工资数据并执行计算
3. 财务人员可查看全公司工龄工资数据但不可计算
4. 系统管理员拥有全部权限
5. 工龄工资数据为敏感数据，所有操作需记录日志
