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

150 lines
9.8 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.
# 工作进度-23:移除现有考勤 + 移植「生产-职工考勤」调研(移植待续)
> **协作规则(长期生效)**:**每次对话结尾都要生成工作进度**。
> 即在每轮对话结束前,把本轮完成的内容追加为 `工作进度/工作进度-N.md`,并在文档中保留本条规则,方便下一轮接续。
## 一、任务
1. **移除**新系统现有考勤(`attendance`:打卡/请假/审批/记录/我的)
2. **移植**老系统「生产-职工考勤」:`D:\AntaiProject - 副本\trunk\WinClient\F9.Business.Prod\KQ`
- `CQDJ` 考勤登记
- `CQTJ` 考勤统计
## 二、本轮完成:移除现有考勤 ✅
### 后端删除
- `Application/Services/Attendance/IAttendanceService.cs`、`AttendanceService.cs`
- `Application/Dtos/Attendance/AttendanceDtos.cs`
- `Api/Controllers/Attendance/AttendanceController.cs`
- `Domain/Entities/Attendance/`:`LeaveRequest.cs`、`LeaveApprover.cs`、`AttendanceRecord.cs`
- `DependencyInjection.cs`:删除 `AddScoped<IAttendanceService, AttendanceService>()`,
**并删除 `using F9WebAiTest.Application.Services.Attendance;`**(否则 CS0234)
### 前端删除
- `web/src/views/attendance/` 下 5 个页面:`approve/ leave/ my/ punch/ records/` 的 `index.vue`
- `router/index.js`:删除静态路由 `attendance/approve`、`STATIC_ROUTES` 置空、删除 5 条组件映射
- `views/dashboard/index.vue`:删除「考勤打卡」快捷卡片
### 菜单
- `DbSeeder.cs`:移除 `SeedAttendanceMenus(fsql);` 调用(方法体保留为死代码,未调用即不生效)
- ⚠️ **库中已存在的 `/attendance` 菜单记录不会自动删除**,需在「系统管理-菜单管理」手动删,
或在 seed 中补清理逻辑(注意 `DbSeeder` 里菜单实体有 `SysMenu` 与 `Menu` 两种引用,别写错类型)
### 编译
- 解决方案编译:**无 error CS** ✅
> 注:`views/notification/type/index.vue` 里 `/attendance/approve?leaveId={businessId}` 只是
> **placeholder 示例文本**,不影响运行,未改(建议后续改成中性示例)。
## 三、老系统「职工考勤」调研结论(移植依据)
### 1. 实体
**考勤登记主表 `Cqdj`**(表 `biz_prod_kq_cqdj`,一人一天一条)
`Date / Dep_Id / Worktype_Id / Employee_Id / Banci / Is_xuegtong`
`Hours_standard / Hours_cq / Hours_qj / Hours_ld / Hours_jb / Hours_db / Hours_wp / Hours_kg / Hours_gs`
`Cs_yeban(夜班次数) / Memo`
唯一约束:`(Date, Employee_Id)`(一人一天一条);索引 `(Date,Dep_Id,Worktype_Id,Banci)`
**登记明细 `Cqdj_Item`**(表 `biz_prod_kq_cqdj_item`,一人一天多行,按出勤类型拆)
`Cqdj_id / Dep_id / Worktype_id / Employee_id / Banci / Type_cq / Type_qj / Hours`
`Jizu / Ct_start / Ct_end / Dangche_num / Memo`
**考勤统计 `Cqtj`**(表 `biz_prod_kq_cqtj`,**月快照**,非实时)
`Year / Month / Dep_id / Worktype_id / Employee_id`
`Days_cq_standard / Days_cq_actual / Hours_cq / Hours_qj`
`Hours_qj_shijia/bj/hj/cj/lx/sangjia/gj/nj/tx`(事病婚产轮休丧公年调)
`Hours_ld / Hours_jb / Hours_db / Hours_wp / Hours_kg / Cs_yeban`
`Hours_fadingjiaqi / Hours_qj_qqmc / Hours_qj_qqcal`
`Jine_quanqin / Jine_jb / Jine_jq_bz_hj/sangjia/bj/lx/fading/txnj / Jine_jq_bz`
`Jine_yb / Jine_kg_kk / Jine_liudong / Jine_daiban`
`Hours_xg_cq / Hours_xg_jiaban / Cq_tianci`
### 2. 枚举(硬编码,无配置表)
- 出勤类型 `Cqdj_CqType_Enum`:正常=1 请假=2 流动=3 加班=4 代班=5 外派=6 旷工=7 工伤=8
- 请假类型 `Cqdj_QjType_Enum`:无=0 事假=1 病假=2 产假=3 婚假=4 丧假=5 公假=6 年假=7 调休=9 轮休=10
- 校验:出勤类型=请假时请假类型≠无;非请假时请假类型必须为无
- 班次 `Prod_Banci_Enum`:甲=1 乙=2
### 3. 考勤登记(CQDJ)规则
- 查询:日期 + **部门(必选)** + 工种(可空=全部) + 班次(默认甲) + 关键字
- 主列表列:部门/工种/姓名/班次/学工/标准时长/出勤/请假/流动/加班/代班/外派/工伤/旷工/夜班/备注
- 明细(选中职工联动):出勤部门/工种/姓名/班次/出勤类型/请假类型/时长/备注
- **核心汇总公式**:
```
正常明细.Hours = 标准 - 请假 - 旷工 - 流动 - 外派 - 代班 - 工伤 (倒挤)
Hours_cq = Σ(正常 + 流动 + 代班 + 外派 + 工伤) (不含加班)
其余 Hours_qj/kg/ld/jb/wp/db/gs = 各类型明细求和
校验 Hours_cq >= 0
```
- 约束:每人最多一条「正常」明细;不能删最后一条正常记录;保存前校验每人必须有正常记录
- 新职工默认:`Hours_standard=9`、`Hours_cq=9`、明细 `Hours=9`、类型=正常/无;`Is_xuegong = !Base_is_zhuanzheng`
- **保存方式**:`Cqdj_SaveCommand` = 按 `(日期,部门,工种,班次)` **先软删旧登记与明细,再整批新增**(不做增量 diff)
- 按钮:设标准时长/设出勤时长/加班/流动/请假/公假/代班/夜班/添加职工/删除职工/刷新
- 「添加其他车间」(`Page_Cqdj_addOtherChejian_select.cs`)**老系统中无任何页面引用**,属遗留未启用功能,可不移植
### 4. 考勤统计(CQTJ)规则
- 维度:**年/月(账期)+ 部门 + 工种 + 职工**(一人一行)
- 数据来源:**快照**。点「录入」时:若该 年/月/部门 已有统计则取库;否则由 `Cqtj_TongjiQuery` 取账期内
全部 Cqdj + Cqdj_Item + 薪资配置 + 职工,在客户端计算后 `Cqtj_Save`(先软删该年月部门旧数据再整批插入)
- 派生公式(关键):
```
实际出勤天数 = Round(本部门 Hours_cq / 工种配置.HoursPerday, 2)
出勤天次 = 该人该部门登记中 (Hours_cq + Hours_jb) > 0 的天数计数
夜班补助 = 工种配置.JineYeban × Cs_yeban
旷工考核 = 工种配置.JiaqiJineKuangongKk × Hours_kg
流动工资 = Σ 工种配置.LiudongJineGuding × 流动时长
代班工资 = Σ (代班部门工种.JineGangwei / (QqDaysStandard×HoursPerday)) × 代班时长
带薪时长 = 轮休+年假+公假+调休+婚假+产假+丧假
加班免扣请假 = 若(出勤+总加班) ≥ QsQuanqinDays×HoursPerday 且 总加班 ≥ QqHoursDkMinjiaban
→ QqHoursDkQingjia,否则 0
全勤计算请假 = 总请假 - 加班免扣 - 带薪时长
假期补助 = 病假×BingjiaBz + 轮休×LunxiuBz + 婚假×HunjiaBz + 丧假×SangjiaBz
+ (年假+调休)×NianjiaBz + 法定假补助
(事假/产假/公假只计时长不计金额)
加班费 = Σ 加班时长 × 单价(单价取岗位胜任考核 5 档对应 Jiaban_gwsrkhJine*,无考核取 JiabanJineBz)
法定假期时长 = 职工配置.Hours_FadingBz + Hours_FadingGz
```
- **全勤奖 `quanqin()` 最复杂**(老系统在客户端 `Page_Cqtj.cs:837`,服务端 Command 是空实现):
学工用 `XgJineQuanqin`;总旷工 ≥ 半天 → 0;总出勤 ≤ 3 天 → 0;当月离职且出勤 ≤15 天 → 0;
单部门/工种:出勤 ≥15 天给满,否则 `全勤奖/(QqDaysStandard×HoursPerday) × 出勤时长`;
多部门:`全勤奖/总出勤时长 × 本部门出勤时长`;入职日在账期内按标准折算;设备办全职特殊口径;
最终:`全勤计算请假 ≥ QqHoursMaxQj → 0`,否则 `初始全勤奖 - 初始全勤奖/QqHoursMaxQj × 全勤计算请假`
### 5. 依赖的基础数据(移植前必须确认新系统是否具备)
| 依赖 | 说明 |
| --- | --- |
| 部门 | 排除「公司」类型,`Department_DutyType_Enum`(前缫=25/后缫=30/选剥茧=15/设备办=35) |
| 职工 | `Employee_GetByDepartmentIdView(DepId, WorkTypeId, Banci)`;用 `Base_is_zhuanzheng`(→学工)、`Base_RuzhiDate`、`LizhiDate`、`Base_WrokStatus`;`Base_WorktypeId=0` 过滤掉 |
| 工种 | `WorkType_GetByDepartmentIdView`;注册表 `基础数据\工种` 存 挡车工/车头工/值班长/选茧工 ID |
| 账期 `Biz_Base_Zhangqi` | `Zhangqi_GetByDate`、`Zhangqi_GetIsZhaZhangByDate`(**扎帐即禁止增删改**) |
| 薪资配置-工种 CONFGZ | HoursPerday、JineQuanqin、XgJineQuanqin、QqDaysStandard、QqHoursMaxQj、QqHoursDkMinjiaban、QqHoursDkQingjia、JiaqiJine*、JineYeban、JiaqiJineKuangongKk、LiudongJineGuding、JineGangwei、JiabanJineBz、Jiaban_gwsrkhJine*(5档) |
| 薪资配置-职工 CONFEMPLOYEE | `Hours_FadingBz`、`Hours_FadingGz`、`IsXuegong` |
| 薪资配置账期 CONFZQ | `QsQuanqinDays`(前缫出勤天数,必填) |
| 岗位胜任考核 | 决定加班单价档位 |
## 四、待办(下一轮实施移植)
1. 后端实体:`Cqdj` / `CqdjItem` / `Cqtj`(放 `Domain/Entities/Prod/`,继承 `BaseEntity`,
**必须 `using F9WebAiTest.Domain.Common;`**)
2. DTO + Service + Controller(路由建议 `api/prod/kaoqin`),含:
- 登记分页 / 按(日期,部门,工种,班次)整批保存(先软删后新增)/ 删除
- 统计分页 / 生成(快照)/ 编辑保存 / 删除
3. 前端页面(`web/src/views/prod/kaoqin/`):考勤登记(主从联动 + 明细按出勤类型)、考勤统计
4. 菜单:在 `DbSeeder.SeedProdMenus` 用 `EnsureTopMenuWithChildren` 加(与选剥茧同法)
- ⚠️ 加菜单必须改 **`DbSeeder.SeedProdMenus`(`SysMenu`)**,不要只改 `BusinessSeedData`
5. 确认新系统是否已有薪资配置(CONFGZ/CONFZQ/CONFEMPLOYEE)——**统计页强依赖**,缺失则需先补齐或先做简化版统计
6. 库中历史 `/attendance` 菜单手动删除
## 五、下次接续提示
- 出勤/请假/班次是**硬编码枚举**,前端下拉直接写死,不用查表
- 登记保存是「整批覆盖」不是增量 diff,实现时别做反
- 统计是**快照**(生成后落库),不是实时 SQL 汇总
- 移植顺序建议:**先做考勤登记(CQDJ)**,统计(CQTJ)因强依赖薪资配置,放到薪资配置确认后再做
- **每轮对话结尾记得生成本工作进度文档**