新增工资/仓储/生产日报等模块,移除旧考勤模块

- 新增 PayRoll(工资)、Wms(仓储)、Prod(车速/缫丝/考勤/丝片检测/丝片台账/纤检日报/质量日报) 模块
- 新增对应 Domain 实体、Application DTO/Service、Api Controller 与前端页面
- 移除旧 Attendance 考勤模块(Controller/Service/Entity/DTO 及 5 个前端页面),由 Prod/Kaoqin 取代
- 调整路由、仪表盘、Lsjl 流丝记录实体与服务
- 更新业务种子数据与 DbSeeder
- 补充工作进度文档 14-27
This commit is contained in:
yanpeng200212
2026-10-27 09:09:57 +08:00
parent 69c4052a64
commit 1f1b184411
119 changed files with 21576 additions and 1668 deletions
+211
View File
@@ -0,0 +1,211 @@
# 工作进度-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 保存脚本。
- 煮茧日报的「已存在相同的煮茧日报」校验会命中已软删记录,删除后无法在同一「日期+车间+庄口+规格」重建(既有模块行为,本次未改动)。