# 工作进度-17:仓储模块(WMS)五模块移植 ## 一、任务目标 把 `D:\AntaiProject - 副本\trunk\WinClient\F9.Business.WMS` 下的五个子模块**按原业务逻辑一模一样**移植到本系统,UI 做适度美化: | 模块 | 原 F9 目录 | 本系统菜单 | | --- | --- | --- | | 原料 | `F9.Business.WMS\Yuanliao` | 仓储 / 原料 | | 副产品 | `F9.Business.WMS\Fuchanpin` | 仓储 / 副产品 | | 中间品 | `F9.Business.WMS\ZJP` | 仓储 / 中间品 | | 生丝 | `F9.Business.WMS\SS` | 仓储 / 生丝 | | 物资 | `F9.Business.WMS\WJ` | 仓储 / 物资 | ## 二、建模方案(统一模型 + 模块/口径区分) 五个模块的单据结构高度一致,因此没有建 5 套重复表,而是一套表 + 两个维度: - `Wms_Module_Enum`:原料=1 / 副产品=2 / 中间品=3 / 生丝=4 / 物资=5 - `Kind`:0=库存台账,1=笼筒架台账(中间品专用) ### 新增实体(Domain/Entities/Wms/Wms.cs) | 实体 | 表 | 说明 | | --- | --- | --- | | `WmsRuku` / `WmsRukuDetail` / `WmsBangmadan` | `WmsRukus` / `WmsRukuDetails` / `WmsBangmadans` | 入库单、入库明细、磅码单 | | `WmsChuku` / `WmsChukuDetail` | `WmsChukus` / `WmsChukuDetails` | 出库单、出库明细 | | `WmsKcTzDate` / `WmsKcTzItem` | `WmsKcTzDates` / `WmsKcTzItems` | 库存台账(日期 + 明细) | | `WmsPici` / `WmsPiciBaojian` | `WmsPicis` / `WmsPiciBaojians` | 生丝批次、包件 | | `WmsKucun` | `WmsKucuns` | 物资库存(按物资目录) | | `WmsCaigou` | `WmsCaigous` | 原料采购 | | `WmsFbplan` / `WmsFbjl` | `WmsFbplans` / `WmsFbjls` | 原料翻包计划 / 翻包记录 | | `WmsCgplan` / `WmsCgplanItem` | `WmsCgplans` / `WmsCgplanItems` | 物资采购计划 / 明细 | ### 台账项目口径(与 F9 一致) - 原料:按**原料庄口**;中间品笼筒架台账:按**工艺庄口**(且只统计「联统茧」物资) - 其余:按**物资目录**;生丝额外按 `SubKey`(基地 / 外购)分组 ### 两列数值口径 - 原料 / 副产品 / 中间品 / 生丝:**件数 / 净重**(生丝件数列取「批数」) - 物资:**数量 / 金额** ## 三、对齐 F9 的业务规则 ### 1. 单据类型枚举(完整照搬 F9) | 模块 | 入库类型 | 出库类型 | | --- | --- | --- | | 原料 | 采购1 / 调拨2 / 其他3 | 领料1 / 销售2 / 样茧3 / 其他4 | | 副产品 | 生产1 / 试缫2 / 其他5 | 销售1 / 调拨2 / 其他3 | | 中间品 | 选茧0 / 试缫2 / 退料3 / 其他5 | 领料0 / 销售1 / 其他2 | | 生丝 | 生产0 / 退货1 / 其他2 | 销售1 / 其他5 | | 物资 | 采购1 / 冲账2 / 盘盈3 / 其他4 | 领料1 / 销售2 / 调拨3 / 报废4 / 其他5 | ### 2. 重量 / 金额计算 - 磅码单:净重 = 毛重 − 皮重;明细件数 / 毛重 / 皮重 / 净重由磅码单汇总 - 明细净重 = 毛重 − 皮重 − 包装重量 − 运损(未使用的项为 0) - 物资:金额 = 数量 × 单价;库存单价 = 库存金额 ÷ 库存数量(4 位小数) - 物资出库金额(`WJ_Chuku_Detail.CalJine`): - 出库数量 = 库存数量 → 金额 = 库存金额,单价 = 金额 ÷ 数量 - 否则 → 单价 = 库存单价,金额 = 数量 × 单价 - 物资出入库实时更新库存(加权平均单价);删除 / 修改单据时回滚,保证严格对称 ### 3. 库存台账生成(`YL_Kucun_Taizhang_Edit.GenerateTaizhang / CalTdayJiecun`) - 上日结存:取上一台账中「件数或净重不为 0」的行 - 汇总区间:`LastDate + 1天` ~ `TzDate`(笼筒架台账为 `LastDate` ~ `TzDate`,与 F9 的 Yesterday~Date 一致) - 无上一台账时 `LastDate = 1970-01-01`(与 F9 `Page_YL_Kucun_Taizhang.cs` 一致,首份台账汇总全部历史) - 今日结存件数 = 上日 + 入库 − 出库 - 今日结存重量 = Round(上日 + 入库 − 出库 + 盈亏, 2, AwayFromZero) - 全部出库 = 上日结存 ≠ 0 且今日结存 = 0;勾选后把结存转入盈亏(取消则转回) - 只能生成**晚于**最新台账日期的台账 ### 4. 台账保存校验(与 F9 一致) - 结存重量恒等式:`上日 + 入库 − 出库 + 盈亏 = 今日结存` - 结存重量不能小于 0 - 原料:全部出库时样茧件数必须为 0 ### 5. 生丝批次包件 - 净重 = 毛重 − 皮重;公量 = 净重 × (1 + 11%) ÷ (1 + 实测回潮率%) - 批次库存状态:待入库1 / 已入库2 / 部分出库3 / 已出库4;生丝出库后按批次号更新为「已出库」 ### 6. 物资扩展 - 采购计划(草稿 / 已确认 / 已完成)+ 计划明细 - 采购报销:入库单 `BxStatus` 无0 / 待报销1 / 已报销2,支持批量报销 - 库存查询、出入库流水(入库为正、出库为负) ## 四、后端实现 | 文件 | 说明 | | --- | --- | | `Domain/Entities/Wms/Wms.cs` | 全部 WMS 实体与 `Wms_Module_Enum` | | `Application/Dtos/Wms/WmsDtos.cs` | 出入库 / 明细 / 磅码单 / 台账 / 批次 / 采购 DTO | | `Application/Services/Wms/WmsService.cs` | 统一服务:五模块出入库、台账、库存、流水、批次、采购 | | `Api/Controllers/Wms/WmsController.cs` | `api/wms/*` 接口 | | `Application/DependencyInjection.cs` | 注册 `IWmsService` | | `Infrastructure/Data/DbSeeder.cs` | 一级菜单「仓储」+ 5 个子菜单;清理软删残留 | ### 接口清单(`/api/wms`) ``` GET /options?module= 类型 / 物资 / 原料庄口 / 工艺庄口 / 部门 / 往来单位 GET /ruku?module=&start=&end=&type=&like= GET /ruku/{id} POST /ruku DELETE /ruku/{id} POST /ruku/baoxiao 采购报销(物资) GET /chuku?... GET /chuku/{id} POST /chuku DELETE /chuku/{id} GET /taizhang/dates?module=&kind= GET /taizhang?module=&kind=&date=®enerate= POST /taizhang DELETE /taizhang/{id} GET /kucun?module= GET /crk?module=&start=&end=&wzmlId= GET /pici GET /pici/{id} POST /pici DELETE /pici/{id} GET /caigou POST /caigou DELETE /caigou/{id} GET /fbplan POST /fbplan DELETE /fbplan/{id} GET /cgplan GET /cgplan/{id} POST /cgplan DELETE /cgplan/{id} ``` ### 设计要点 - 单据编号(模块 + 日期 + 单号)唯一,重复时返回友好提示 - 出入库单、批次采用**物理删除**:避免软删残留撞唯一索引而无法重建同号单据 - 启动时清理历史软删残留(`WmsRukus` / `WmsChukus` / `WmsPicis`) ## 五、前端实现 | 文件 | 说明 | | --- | --- | | `views/wms/moduleConfig.js` | 五模块差异化配置(项目口径、字段显示、数值口径、枚举选项) | | `views/wms/components/RukuPanel.vue` | 通用入库(含磅码单弹窗、明细合计) | | `views/wms/components/ChukuPanel.vue` | 通用出库(物资显示库存数、自动算金额) | | `views/wms/components/TaizhangPanel.vue` | 通用台账(生成 / 编辑 / 盈亏 / 全部出库 / 保存 / 删除) | | `views/wms/components/WjKucun.vue` | 物资库存 | | `views/wms/components/WjCrk.vue` | 物资出入库流水 | | `views/wms/components/WjCgplan.vue` | 物资采购计划 | | `views/wms/components/WjCgbx.vue` | 物资采购报销 | | `views/wms/components/SsPici.vue` | 生丝批次 + 包件(公量自动计算) | | `views/wms/components/YlCaigou.vue` | 原料采购 | | `views/wms/components/YlFbplan.vue` | 原料翻包计划 + 翻包记录 | | `views/wms/{yuanliao,fuchanpin,zjp,ss,wj}/index.vue` | 五个模块页面(Tab 组织) | | `router/index.js` | 注册 5 个页面组件 | ### UI 优化点 - 统一卡片式布局 + Tab 分区,顶部带模块说明 - 查询栏(日期区间 / 类型 / 关键字)与操作按钮分离,右侧对齐 - 单据编辑弹窗:表头 4 列栅格表单,明细用可编辑表格(下拉 + 数字框),底部实时合计 - 磅码单独立弹窗,自动算净重并汇总 - 台账:结存列加粗高亮,盈亏 / 全部出库可交互,底部合计条 - 状态用 `el-tag` 着色(库存状态、报销状态、翻包状态、采购计划状态) ## 六、菜单 一级菜单「仓储」(`/wms`,排序 9,位于「薪资」之后),五个子菜单: | 名称 | 路径 | 组件 | | --- | --- | --- | | 原料 | `/wms/yuanliao` | `wms/yuanliao/index`(入库 / 出库 / 库存台账 / 原料采购 / 翻包计划) | | 副产品 | `/wms/fuchanpin` | `wms/fuchanpin/index`(入库 / 出库 / 库存台账) | | 中间品 | `/wms/zjp` | `wms/zjp/index`(入库 / 出库 / 库存台账 / 笼筒架台账) | | 生丝 | `/wms/ss` | `wms/ss/index`(入库 / 出库 / 库存台账 / 批次包件) | | 物资 | `/wms/wj` | `wms/wj/index`(入库 / 出库 / 库存台账 / 库存 / 出入库流水 / 采购计划 / 采购报销) | ## 七、验证结果(全流程脚本自动执行,已清理测试数据) ``` [1] 登录 OK [2] 菜单:仓储 children=5(原料 / 副产品 / 中间品 / 生丝 / 物资) [3] 选项:原料模块 入库类型3 / 出库类型4 / 原料庄口347 / 物资1000 [4] 原料入库:件数10 净重945(1000−50−5)✓ [5] 原料出库:件数4 净重380 ✓ [6] 台账生成:上日0 + 入库10/945 − 出库4/380 = 结存6/565 ✓ [7] 台账保存 ✓ [8] 次日台账:上日结存6/565 正确结转 ✓ [9] 物资入库:库存 100 / 1000 / 单价10 ✓ [10] 物资出库40:库存 60 / 600 / 单价10(CalJine 规则)✓ [11] 生丝批次:净重120 公量119.46(59 + 60.46)✓ [12] 原料采购 ✓ [13] 翻包计划 ✓ [14] 采购计划 ✓ [15] 批量报销 count=1 ✓ [16] 清理完成,物资库存归零 ✓ ``` 第二批(副产品 / 中间品 / 生丝 + 笼筒架台账): ``` [2 副产品] 入库6/570 出库2/190 结存4/380 ✓ [3 中间品] 入库6/570 出库2/190 结存4/380 ✓ [4 生丝] 入库2批/570 出库1批/190 结存1批/380(按基地分组)✓ [3 笼筒架台账] 按工艺庄口统计 结存4/380 ✓ ``` - 后端 `dotnet build`:0 错误 - 前端 `npm run build`:构建成功 - 服务运行中:后端 `http://localhost:3000`、前端 `http://localhost:5173` ## 八、后续修正(2026-10-26) 1. **「在制品」更名为「中间品」** - 枚举 `Wms_Module_Enum.在制品` → `中间品`(数据库存值仍为 3,不影响历史数据) - 菜单「仓储 / 中间品」、页面标题、模块配置同步更名 2. **按仓储区分物资分组** - 物资分组 `WuziGroup.BusinessType`:原料1 / 中间品2 / 生丝3 / 副产品4 / 五金5 - `/api/wms/options?module=` 只返回本模块所属分组的物资: | 仓储模块 | 分组业务类型 | 物资数(现有数据) | 示例 | | --- | --- | --- | --- | | 原料 | 原料(1) | 2 | 0101 优茧、0102 普茧 | | 副产品 | 副产品(4) | 39 | 040101 好五级茧 … | | 中间品 | 中间品(2) | 1 | 0301 联统 | | 生丝 | 生丝(3) | 6 | 070101 正品丝20/22 … | | 物资 | 五金(5) | 952 | 02010063 轴承盒 … | - 笼筒架台账的物资过滤同步改为匹配名称含「联统」的物资(原为「联统茧」) 3. **修复「新增页面点击确认保存报错」** - 原因:下拉框清空后前端提交 `null`,而后端 DTO 的 `long/int/decimal` 不接受 `null`, `System.Text.Json` 直接返回 400(`The JSON value could not be converted to System.Int64`) - 修复:新增 `cleanPayload()`(`views/wms/moduleConfig.js`),提交前把 `null/undefined` 统一转成 `0` (`scDate`、`guobangShijian`、`ckTime` 等日期型保持 `null`),所有 WMS 保存接口统一走该函数 - 验证:中间品入库(件数3 净重285=300−15)、物资入库(10×5=50)均保存成功,测试数据已清理 ## 九、说明与后续可选项 - 笼筒架台账只统计名称含「联统茧」的物资(与 F9 一致;未配置该物资时不过滤) - 生丝公量按 11% 公定回潮率计算(F9 标准值) - 已对齐 F9 的五个模块核心逻辑;如后续需要,可再补充: - 生丝混装(`SS_Pici_Hunzhuang`) - 物资调拨单、报废单的独立审批流 - 各模块台账的报表打印模板