Files
yanpeng200212 1f1b184411 新增工资/仓储/生产日报等模块,移除旧考勤模块
- 新增 PayRoll(工资)、Wms(仓储)、Prod(车速/缫丝/考勤/丝片检测/丝片台账/纤检日报/质量日报) 模块
- 新增对应 Domain 实体、Application DTO/Service、Api Controller 与前端页面
- 移除旧 Attendance 考勤模块(Controller/Service/Entity/DTO 及 5 个前端页面),由 Prod/Kaoqin 取代
- 调整路由、仪表盘、Lsjl 流丝记录实体与服务
- 更新业务种子数据与 DbSeeder
- 补充工作进度文档 14-27
2026-10-27 09:09:57 +08:00

212 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 工作进度-16:薪资-挡车车头产量计算(CALCLDCCT)及其全部依赖
> 时间:2026-10-24(承接工作进度-15)
> 需求:把 `D:\AntaiProject - 副本\trunk\WinClient\F9.Business.PayRoll\PAYROLL\CALCLDCCT` 模块移植进本系统,
> 并补齐它依赖的全部功能(配置 + 数据源)。
> 参考实现:`WinClient\F9.Business.PayRoll\PAYROLL\CALCLDCCT\Page_CalcLdcct.cs`(3067 行)、`Page_CalcLdcct_Edit.cs`、
> `Application\CQRS\Business\PayRoll\CALCLDCCT\`(CalcLdcct_SaveCommand / CalcLdcct_DeleteByDateRangeDepCommand …)、
> `Domain\Entities\Business\PayRoll\`(CalcLdcct / CONFGYZK / CONFGZ / CONFDCG / DCXDJK / XinZiJiaGePeiZhi)。
> 落库表:F9 `biz_payroll_calcldcct` → 本系统 `CalcLdccts`。
---
## 一、功能设计
```
薪资
├── 挡车车头产量计算 /payroll/calcldcct 本次新增(核心)
├── 工艺庄口薪资配置 /payroll/confgyzk 本次新增(依赖配置)
├── 工种薪资配置 /payroll/confgz 本次新增(依赖配置)
├── 挡车岗位薪资配置 /payroll/confdcg 本次新增(依赖配置)
├── 挡车纤度奖扣 /payroll/dcxdjk 本次新增(依赖配置)
└── 薪资价格配置 /payroll/xzjg 本次新增(依赖配置)
```
| F9 行为 | 本系统实现 |
|---|---|
| 查询:年月(→账期)+ 部门 + 工种 + 姓名/庄口 Like | `GET /api/payroll/calcldcct/list` |
| 一键计算(挡车工):部门穿梭框多选 → 逐部门计算 → 对账报告 | `POST /api/payroll/calcldcct/calc-dcg`(单部门;返回条数/丝量/金额/告警) |
| 一键计算(车头工):**强依赖已存的挡车工产量** | `POST /api/payroll/calcldcct/calc-ctg` |
| 录入:单部门计算后弹窗人工微调(可改产量初始值 / 系数 / 金额-产量) | 表格内 3 列直接编辑 + 「保存微调」整账期覆盖(`POST /save`) |
| 删除:按 账期 × 部门 × 工种 整批删除 | `DELETE /api/payroll/calcldcct?start=&end=&depId=&worktypeId=` |
| 5 套薪资配置各自的增删改查 | 5 个 `api/payroll/conf*` `/dcxdjk` `/xzjg` 控制器 |
### 计算口径(全部对齐 F9,服务端兜底重算)
```
【丝量】
每桶丝量 = 每车丝量(kg) × 1000 / 标准落丝桶数
甲乙合计丝量 = Round(Σ今缫桶数 × 每桶丝量, 0) (煮茧日报不分班)
班次丝量 = 甲乙合计 × Σ(挡车数×工时)_班 / Σ(挡车数×工时)_机组日 (挡车)
= 甲乙合计 × Σ(20×工时)_班 / Σ(20×工时)_机组日 (车头,固定 20 台/组)
个人丝量 = 班次丝量 × 挡车数×工时 / Σ(挡车数×工时)_同机组同班 (挡车)
= 班次丝量 × 工时 / (最长工时 × 2) (车头,2 人分摊)
看台时长 = Round(个人工时 × 庄口今缫桶数占比, 1),单庄口时等于个人工时
【等级】
挡车工:木桶短板法 —— 均方差/总差/清洁分/洁净分/二度/三度各自在「生丝定级指标(标准=个人)」里定级,取最低分
车头工:按挡车工丝量加权平均等级分后回落取整档;无挡车工产量时取庄口配置的 QsDengji/QsDengjifen
未下丝时:等级/等级分/缫折全部回落到庄口配置
【单价】
挡车:绪数 = 挡车数 × 20;<60→50档基数,<70→60档,<100→70档,否则 100 档
基础单价 = 岗位基数金额 / 标准出勤天数 / 挡车数 / 标准上班时长 / 庄口工艺台产
车头:基础单价 = 车头岗位金额 / 标准出勤天数 / 9 / 20 / 庄口工艺台产 × 2
等级单价增减 = (等级分 − 工艺等级分) / 0.1 × 等级奖扣单价 / 10 / 1000
实际单价 = 基础单价 + 等级单价增减
【质量】
缫折 = Σ(车台茧量×看台比例) × 100 / Σ(车台丝量×看台比例)
车台茧量 = 落丝茧量 × 该车台丝量占落丝丝量的比例(茧量只记在落丝层,需按丝量摊到车台)
中心纤度数 = 纤度值 == 生丝规格.中心纤度 的计数 × 看台比例
野纤数 = 纤度 ≤ 野纤下限 或 ≥ 野纤上限 的计数 × 看台比例
清洁扣款片数 = (特大糙 + 大糙 + 长结) × 看台比例
洁净扣款片数 = (85 + 80 + 75 + 70 分档) × 看台比例
二度/三度 = 黑板检验匀二度/匀三度 × 看台比例
两班(甲乙)时:中心纤度/野纤/清洁/洁净/二度/三度及其扣款全部 × 0.5
【金额】
产量金额初始值 = 实际单价 × 丝量; 产量金额 = 实际单价 × 丝量 × 计件系数
缫折考核 = ±2kg 死区不奖不扣,超出扣掉死区后 clamp(挡车 ±10 / 车头 ±3),每 1kg 每 100kg 丝 5元(挡车)/1元(车头)
中心纤度奖 = 中心纤度数 × 1 元
野纤扣 = −挡车纤度奖扣表扣款(≥2 条取扣款最大的 2 条求和)
清洁扣 = −(特大糙×2 + 大糙×0.5 + 长结×2)
洁净扣 = −(85×0.2 + 80×1 + 75×2 + 70×5)
二度扣/三度扣 = −二度×2 / −三度×20
```
> 关键常量:`20`(每台绪数、车头 20 台/组)、`9`/`2`(车头)、`0.1`(等级分步长)、
> `0.5`(两班折半)、`1.0/0.4/0.1`(清洁扣分基数)、`2`(缫折死区)、`5/1`(缫折单价)、`225`(F9 弹窗均值折算,本版未移植)。
> 全程 `MidpointRounding.AwayFromZero`。
---
## 二、后端
### 2.1 实体(`Domain/Entities/PayRoll/`)
| 类 | 文件 | 表 | 说明 |
|---|---|---|---|
| `CalcLdcct` | `CalcLdcct.cs` | `CalcLdccts` | 产量计算明细,唯一键 `Date+DepId+Banci+Jizu+EmployeeId+WorktypeId+GyzkId+Guige+Chetai` |
| `ConfGyzk` | `Conf.cs` | `ConfGyzks` | 工艺庄口薪资配置,唯一键 `Year+Month+GyzkId` |
| `ConfGz` | `Conf.cs` | `ConfGzs` | 工种薪资配置(40 项),唯一键 `WorkTypeId` |
| `ConfDcg` | `Conf.cs` | `ConfDcgs` | 挡车/车头岗位薪资配置,唯一键 `DepId` |
| `DangCheXianDuJiangKou` | `Conf.cs` | `DangCheXianDuJiangKous` | 挡车纤度奖扣,唯一键 `GuiGe+XianDu` |
| `XinZiJiaGePeiZhi` | `Conf.cs` | `XinZiJiaGePeiZhis` | 薪资价格配置,唯一键 `Group+Key` |
均继承 `BaseEntity`,建表沿用 `DbSeeder.SyncStructure`。
### 2.2 服务
| 服务 | 文件 | 说明 |
|---|---|---|
| `ICalcLdcctService` / `CalcLdcctService` | `Services/PayRoll/CalcLdcctService.cs` | 列表 + 挡车/车头一键计算 + 保存 + 删除,内含全部计算口径 |
| `IConfGyzkService` / `ConfGyzkService` | `Services/PayRoll/PayRollConfService.cs` | 工艺庄口配置 CRUD |
| `IConfGzService` / `ConfGzService` | 同上 | 工种配置 CRUD(含 40 项金额) |
| `IConfDcgService` / `ConfDcgService` | 同上 | 挡车岗位配置 CRUD |
| `IDcxdjkService` / `DcxdjkService` | 同上 | 挡车纤度奖扣 CRUD |
| `IXzjgService` / `XzjgService` | 同上 | 薪资价格 CRUD + `GetPriceAsync(group,key)` |
数据源(全部为系统已有模块,本次只做读取):看台记录 `KtjlDcg/KtjlCtg`、煮茧日报 `ZjrbRecord/ZjrbJizu`、
落丝记录 `LsjlRecord`、秤大丝 `CdsLsjl/CdsChetai`、纤度检验 `XdjyLsjl/XdjyRecord`、黑板检验 `HbjyRecord`、
生丝规格 `ShengsiGuige`、生丝定级指标 `ShengsiDingjizhibiao`、工艺庄口 `CraftZhuangKou`。
### 2.3 接口
```
GET /api/payroll/calcldcct/list?start=&end=&depId=&worktypeId=&like=&pageIndex=&pageSize=
POST /api/payroll/calcldcct/calc-dcg 一键计算(挡车工)
POST /api/payroll/calcldcct/calc-ctg 一键计算(车头工)
POST /api/payroll/calcldcct/save 整账期×部门×工种全量覆盖(人工微调)
DELETE /api/payroll/calcldcct?start=&end=&depId=&worktypeId=
GET /api/payroll/confgyzk/list?year=&month= POST /save GET /{id} DELETE /{id}
GET /api/payroll/confgz/list POST /save GET /{id} DELETE /{id}
GET /api/payroll/confdcg/list POST /save GET /{id} DELETE /{id}
GET /api/payroll/dcxdjk/list?guige= POST /save GET /{id} DELETE /{id}
GET /api/payroll/xzjg/list?group= POST /save GET /{id} DELETE /{id}
```
要点:
- 计算与保存都是「整账期 + 部门 + 工种全量覆盖」:先物理删除旧数据再重建,避免唯一索引冲突(与煮茧日报同一策略);
- 车头工计算必须已有挡车工产量,否则等级回落到庄口配置并给出告警;
- 所有告警通过 `CalcLdcctResultDto.Warnings` 返回,前端 `ElMessageBox.alert` 展示。
### 2.4 菜单
新增一级菜单「薪资」`/payroll`(排序 8,质量 7 与通知 9 之间),6 个子菜单:
| 顺序 | 菜单 | 路径 | 组件 | 权限标识 |
|---|---|---|---|---|
| 1 | 挡车车头产量计算 | /payroll/calcldcct | payroll/calcldcct/index | payroll:calcldcct:list |
| 2 | 工艺庄口薪资配置 | /payroll/confgyzk | payroll/confgyzk/index | payroll:confgyzk:list |
| 3 | 工种薪资配置 | /payroll/confgz | payroll/confgz/index | payroll:confgz:list |
| 4 | 挡车岗位薪资配置 | /payroll/confdcg | payroll/confdcg/index | payroll:confdcg:list |
| 5 | 挡车纤度奖扣 | /payroll/dcxdjk | payroll/dcxdjk/index | payroll:dcxdjk:list |
| 6 | 薪资价格配置 | /payroll/xzjg | payroll/xzjg/index | payroll:xzjg:list |
同时把一级菜单顺序归一为:`/qc` 7、`/payroll` 8、`/notification` 9、`/sys` 10、`/report` 11。
---
## 三、前端
| 文件 | 说明 |
|---|---|
| `views/payroll/calcldcct/index.vue` | 年月(→账期) + 部门 + 工种查询;多级表头(产量 / 质量 / 金额 / 金额-质量);一键计算(挡车/车头)、保存微调(产量初始值/系数/金额-产量三列直接编辑)、删除;底部显示当前页产量金额合计 |
| `views/payroll/confgyzk/index.vue` | 工艺庄口薪资配置 CRUD,庄口用 `CraftZhuangKouSelect` 选择 |
| `views/payroll/confgz/index.vue` | 工种薪资配置 CRUD,40 项按「出勤与工时/岗位与奖金/假期与加班/学工/岗位胜任考核/加班工资」分组 |
| `views/payroll/confdcg/index.vue` | 挡车岗位薪资配置 CRUD(50/60/70/100 绪基数金额 + 车头工金额) |
| `views/payroll/dcxdjk/index.vue` | 挡车纤度奖扣 CRUD |
| `views/payroll/xzjg/index.vue` | 薪资价格配置 CRUD,`薪资.前缫` 分组下预置「挡车工/车头工计件等级奖扣单价」 |
| `router/index.js` | `componentMap` 注册上述 6 个页面 |
---
## 四、验证记录(全部由助手自行执行,无需人工点击)
| 项 | 结果 |
|---|---|
| `dotnet build`(Domain / Application / Infrastructure / Api) | ✅ 0 错误 |
| `npm run build`(Node 在 `C:\Users\32453\.workbuddy\binaries\node\versions\22.22.2-6`) | ✅ `✓ built in 14.88s`(仅既有 chunk 体积警告) |
| IDE 诊断(6 个 vue + router) | ✅ 0 |
| 菜单与权限 | ✅ `/auth/menus` 返回「薪资」+ 6 个子菜单 |
| 6 个接口连通性 | ✅ 全部 200(空表) |
| 挡车工一键计算 | ✅ 生成 1 条/庄口;丝量 = 桶数100 × (10kg×1000/4) = 250000 g |
| 挡车工单价 | ✅ 挡车数 20 → 绪数 400 → 100 档;基础单价 = 4000/28/20/9/100 = 0.0079365 |
| 挡车工等级 | ✅ 生丝定级指标 192 条参与木桶短板,定出 `6A00 / 12`;等级增减 = (12−5)/0.1×0.3/10/1000 = 0.0021 |
| 挡车工实际单价 / 产量金额 | ✅ 0.0100365;0.0100365 × 250000 × 1 = 2509.13 |
| 挡车工缫折 | ✅ 落丝茧量 60000 g、秤大丝丝量 25000 g → 缫折 240(**修复前为 4800,见下方问题**) |
| 挡车工缫折考核 | ✅ (300−240)−2 = 58 → 封顶 10 → 10 × (250000/1000/100) × 5 = +125 |
| 车头工一键计算 | ✅ 丝量 = 250000 × 9/(9×2) = 125000;基础单价 = 2000/28/9/20/100×2 = 0.0079365;缫折考核 = 3 × 1.25 × 1 = 3.75 |
| 车头工依赖挡车工 | ✅ 无挡车工产量时给出「工种薪资配置缺失」类告警并按配置回落 |
| 人工微调保存 | ✅ 产量初始值改 999.99 后保存,回读 `999.99 / 系数1 / 金额999.99` |
| 整账期删除 | ✅ 删除后 `total=0`,且「删除后重建」不再撞唯一索引 |
| 班次显示 | ✅ 修正为 `甲=1 / 乙=2`(初版误按 0/1 映射,已修) |
| 测试数据清理 | ✅ 播种的煮茧日报、看台记录、落丝记录、秤大丝、5 套配置、计算结果全部删除;验证脚本 `verify-payroll.ps1` 已删除 |
### 过程中发现并修复的真实 bug
1. **缫折被放大 20 倍**:初版按「车台数 × 落丝茧量」累加分子,导致 20 台时缫折 = 4800(正确 240)。
修正为:茧量只记在落丝层,按「车台丝量 / 落丝丝量」摊到车台后再按看台比例摊到人。
2. **班次名称错位**:`Prod_Banci_Enum` 是 `甲=1 / 乙=2`,初版按 `0/1` 映射,甲班被显示成乙班。
---
## 五、移植取舍与后续
1. **未移植 F9 弹窗顶部的 4 个均值标签**(挡60/挡70/挡100/车头平均,`Σ金额 / Σ看台时长 × 225`):这是展示用的派生统计,
本版在列表底部给出「当前页产量金额合计」;如需可按同样公式补在弹窗/工具栏。
2. **未移植 F9 的「部门穿梭框多选」一键计算**:Web 端改为先选部门再点按钮,单部门计算(语义等价,逐个部门重复操作即可)。
3. **野纤「奖励」分支未使用**:与 F9 一致——挡车工路径下 `JineZlYexian` 只取 `-扣款`,奖励分支被丢弃。
4. **未移植的 F9 薪资子模块**(本次范围外,可按需继续):`CalXz`(薪资核算主表)、`Cmcl`(产量)、`QSXSCL`、`QTKH`、`SBRYKH` 等。
5. **待接入**:① Grid++ 打印(报表中心目前只有 `lsjl.grf`);② 历史 `biz_payroll_calcldcct` 数据可按工作进度-13 的 CSV 内嵌 + 幂等策略导入;
③ 本模块产出的「金额-产量 + 金额-质量」可直接作为计件工资与成本核算的数据源。
### 环境备注
- 本机 `node` / `npm` 不在默认 PATH,需先 `set PATH=C:\Users\32453\.workbuddy\binaries\node\versions\22.22.2-6;%PATH%`。
- Windows PowerShell 5.1 的 `Invoke-RestMethod` 默认按 ASCII 提交请求体,写中文会变成 `?`;
验证脚本改为 `[System.Text.Encoding]::UTF8.GetBytes()` + `application/json; charset=utf-8`,并用 UTF-8 BOM 保存脚本。
- 煮茧日报的「已存在相同的煮茧日报」校验会命中已软删记录,删除后无法在同一「日期+车间+庄口+规格」重建(既有模块行为,本次未改动)。