# 库房管理模块实施方案 ## 1. 建设目标 本方案用于先把库房管理业务闭环走通,再进入前端页面、后端接口和 SQL 脚本开发。第一版建设范围包括: 1. 库房管理模块。 2. 库房对应库位管理。 3. 物料入库、出库、退库、移库、调拨等库存变动。 4. 物料盘点、盘盈、盘亏、差异确认。 5. 物料综合查询。 6. 物料正向查询和逆向查询:查物料在哪些库位,也查某个库位放置了哪些物料。 核心原则:真实库存必须落到具体库房、具体库位、具体物料,所有库存数量变化都必须通过业务单据和库存流水产生,不允许只修改结果表而不留变动记录。 ## 2. 总体业务架构 ### 2.1 主数据 库房管理依赖以下主数据: | 主数据 | 说明 | 维护入口 | | --- | --- | --- | | 库房 | 仓储空间的一级单位,如一楼仓库、三楼仓库、外协暂存库 | 新增库房管理页面 | | 库位 | 库房下的具体存放位置,如 A01-01、B02-03 | 新增或复用货位管理页面 | | 物料 | 现有物料主文件,字段包含物料编码、物料名称、图号或型号、规格、单位等 | 现有物料维护 | | 库存现存量 | 某物料在某库房、某库位的当前库存数量 | 由出入库、盘点、调拨自动维护 | | 库存变动流水 | 每一次入库、出库、盘点、调拨产生的数量变化记录 | 由业务单据自动写入 | ### 2.2 单据数据 | 单据 | 说明 | 影响库存 | | --- | --- | --- | | 入库单 | 采购件、自制件、退料、其他入库 | 增加指定库位库存 | | 出库单 | 领料、生产出库、销售出库、其他出库 | 减少指定库位库存 | | 移库单 | 同库房或跨库房从一个库位移动到另一个库位 | 原库位减少,目标库位增加 | | 盘点单 | 按库房、库位、物料生成盘点任务并录入实盘数量 | 差异确认后调整库存 | | 库存调整单 | 非盘点场景的库存调整,需权限控制 | 按调整方向增减库存 | ## 3. 业务流程设计 ### 3.1 库房与库位建档流程 1. 仓库主管新增库房,维护库房编号、库房名称、库房类型、负责人、启用状态。 2. 在库房下新增库位,维护库位编号、库位名称、库区、货架、层号、容量、是否允许混放、启用状态。 3. 系统校验同一库房下库位编号唯一。 4. 已发生库存业务的库位不允许物理删除,只允许停用。 5. 停用库位如果仍有库存,禁止停用或提示先完成移库。 ### 3.2 入库流程 1. 用户选择入库来源:采购入库、自制件入库、退料入库、其他入库。 2. 系统带出物料、批次、供应商、订单或生产任务等来源信息。 3. 仓库人员选择实际上架库房和库位。 4. 系统校验库房、库位启用状态,校验数量大于 0。 5. 提交后写入入库单主表、入库单明细表。 6. 同一事务内更新库存现存量: - 如果该物料、批次、库位已存在库存记录,则累加库存数量。 - 如果不存在,则新增库存现存量记录。 7. 写入库存变动流水,变动类型为“入库”,变动数量为正数。 ### 3.3 出库流程 1. 用户选择出库来源:领料单、生产任务、销售发货、其他出库。 2. 系统按物料查询可用库存,展示该物料在哪些库房、库位有库存。 3. 仓库人员选择出库库位和出库数量。 4. 系统校验出库数量必须小于等于该库位可用库存。 5. 提交后写入出库单主表、出库单明细表。 6. 同一事务内扣减库存现存量。 7. 写入库存变动流水,变动类型为“出库”,变动数量为负数。 8. 如果库存扣减后为 0,保留库存现存量记录,便于追溯历史库位;查询时可默认过滤 0 库存。 ### 3.4 移库和调拨流程 移库用于同一库房或不同库房之间调整物料位置。 1. 用户选择需要移动的物料库存记录。 2. 系统带出原库房、原库位、当前库存。 3. 用户选择目标库房、目标库位和移库数量。 4. 系统校验移库数量大于 0 且不超过原库位库存。 5. 提交后写入移库单主表、移库单明细表。 6. 同一事务内扣减原库位库存、增加目标库位库存。 7. 写入两条库存变动流水: - 原库位“移出”,数量为负数。 - 目标库位“移入”,数量为正数。 ### 3.5 盘点流程 1. 仓库主管创建盘点单,选择盘点库房、库位范围、物料范围。 2. 系统按当前库存现存量生成盘点明细,记录账面数量。 3. 盘点人员录入实盘数量,也可补录账面不存在但现场存在的物料和库位。 4. 系统计算差异数量:差异数量 = 实盘数量 - 账面数量。 5. 无差异明细可直接确认。 6. 有差异明细需要仓库主管确认差异原因。 7. 确认后生成库存调整: - 盘盈:增加库存。 - 盘亏:减少库存。 8. 写入库存变动流水,变动类型为“盘盈”或“盘亏”。 9. 盘点单状态流转为:草稿、盘点中、待确认、已确认、已作废。 ### 3.6 物料综合查询流程 物料综合查询用于按物料维度查看当前库存、库位分布和出入库历史。 查询条件: | 条件 | 说明 | | --- | --- | | 物料编码 | 精确或模糊查询 | | 物料名称 | 模糊查询 | | 图号或型号 | 模糊查询 | | 规格 | 模糊查询 | | 库房 | 按库房过滤 | | 库位 | 按库位过滤 | | 是否只看有库存 | 默认是 | 返回内容: | 信息 | 说明 | | --- | --- | | 物料基础信息 | 编码、名称、图号、规格、单位 | | 总库存 | 该物料所有库位库存合计 | | 主库位 | 库存数量最大的库位,用于快速定位 | | 库位明细 | 每个库位的库存数量 | | 最近入库 | 最近一次入库时间、数量、来源单号 | | 最近出库 | 最近一次出库时间、数量、来源单号 | ### 3.7 正向查询和逆向查询 正向查询:物料在哪些库位。 1. 输入物料编码、物料名称、图号或型号。 2. 系统查询库存现存量表。 3. 返回该物料所有库存大于 0 的库房、库位、批次、库存数量。 4. 支持点击库位查看该库位其他物料。 逆向查询:某库位放置哪些物料。 1. 选择库房和库位。 2. 系统查询该库位所有库存大于 0 的物料。 3. 返回物料编码、物料名称、图号或型号、规格、批次、库存数量。 4. 支持点击物料反查该物料在其他库位的分布。 ## 4. 表结构设计 以下为推荐新表或标准化表结构。若数据库中已有同名或相近表,应优先复用现有表,并通过新增字段、视图或存储过程兼容现有业务。 ### 4.1 库房主表 表名:`仓储管理_库房主表` | 字段名 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | 库房流水号 | int identity | 是 | 主键 | | 库房编号 | nvarchar(50) | 是 | 业务编号,唯一 | | 库房名称 | nvarchar(100) | 是 | 库房名称 | | 库房类型 | nvarchar(50) | 否 | 原料库、成品库、半成品库、暂存库等 | | 地址 | nvarchar(200) | 否 | 库房位置 | | 负责人流水号 | int | 否 | 对应人员表 | | 负责人 | nvarchar(50) | 否 | 冗余显示 | | 联系电话 | nvarchar(50) | 否 | 联系方式 | | 是否启用 | bit | 是 | 默认 1 | | 排序号 | int | 否 | 页面排序 | | 备注 | nvarchar(500) | 否 | 备注 | | 创建人 | int | 是 | UserID | | 创建时间 | datetime | 是 | 默认 GETDATE() | | 修改人 | int | 否 | UserID | | 修改时间 | datetime | 否 | 修改时间 | 主键:`PK_仓储管理_库房主表`,字段 `库房流水号`。 唯一约束:`UK_仓储管理_库房主表_库房编号`,字段 `库房编号`。 ### 4.2 库位主表 表名:`仓储管理_库位主表` | 字段名 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | 库位流水号 | int identity | 是 | 主键 | | 库房流水号 | int | 是 | 外键,关联库房 | | 库位编号 | nvarchar(50) | 是 | 同一库房下唯一 | | 库位名称 | nvarchar(100) | 是 | 页面显示名称 | | 库区 | nvarchar(50) | 否 | 如 A 区、B 区 | | 货架 | nvarchar(50) | 否 | 货架编号 | | 层号 | nvarchar(50) | 否 | 货架层号 | | 容量 | decimal(18,4) | 否 | 可选容量 | | 容量单位 | nvarchar(20) | 否 | 件、箱、kg 等 | | 是否允许混放 | bit | 是 | 默认 1 | | 是否启用 | bit | 是 | 默认 1 | | 备注 | nvarchar(500) | 否 | 备注 | | 创建人 | int | 是 | UserID | | 创建时间 | datetime | 是 | 默认 GETDATE() | | 修改人 | int | 否 | UserID | | 修改时间 | datetime | 否 | 修改时间 | 主键:`PK_仓储管理_库位主表`,字段 `库位流水号`。 外键:`FK_仓储管理_库位主表_库房`,`库房流水号` 关联 `仓储管理_库房主表.库房流水号`。 唯一约束:`UK_仓储管理_库位主表_库房库位编号`,字段 `库房流水号、库位编号`。 ### 4.3 库存现存量表 表名:`仓储管理_库存现存量` | 字段名 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | 库存流水号 | bigint identity | 是 | 主键 | | 物料流水号 | int | 是 | 关联物料主文件 | | 物料编码 | nvarchar(100) | 否 | 冗余字段,便于查询 | | 物料名称 | nvarchar(200) | 是 | 冗余字段 | | 图号或型号 | nvarchar(200) | 否 | 冗余字段 | | 规格 | nvarchar(200) | 否 | 冗余字段 | | 单位 | nvarchar(50) | 否 | 冗余字段 | | 库房流水号 | int | 是 | 外键,关联库房 | | 库位流水号 | int | 是 | 外键,关联库位 | | 批次编号 | nvarchar(100) | 否 | 有批次管理时必填 | | 库存数量 | decimal(18,4) | 是 | 当前库存数量 | | 冻结数量 | decimal(18,4) | 是 | 默认 0 | | 可用数量 | AS | 否 | 建议计算列:库存数量 - 冻结数量 | | 最后入库时间 | datetime | 否 | 最近入库时间 | | 最后出库时间 | datetime | 否 | 最近出库时间 | | 最后变动时间 | datetime | 是 | 最近库存变化时间 | | 状态 | nvarchar(20) | 是 | 正常、冻结、停用 | | 创建人 | int | 是 | UserID | | 创建时间 | datetime | 是 | 默认 GETDATE() | | 修改人 | int | 否 | UserID | | 修改时间 | datetime | 否 | 修改时间 | 主键:`PK_仓储管理_库存现存量`,字段 `库存流水号`。 外键: | 外键 | 字段 | 关联表 | | --- | --- | --- | | FK_仓储管理_库存现存量_库房 | 库房流水号 | 仓储管理_库房主表.库房流水号 | | FK_仓储管理_库存现存量_库位 | 库位流水号 | 仓储管理_库位主表.库位流水号 | | FK_仓储管理_库存现存量_物料 | 物料流水号 | 库存管理_物料主文件_基本.物料流水号 | 唯一约束:`UK_仓储管理_库存现存量_物料库位批次`,字段 `物料流水号、库位流水号、批次编号`。如果批次允许为空,需要在存储过程中统一把空批次处理为固定空值,避免 SQL Server 唯一约束对 NULL 的差异影响。 ### 4.4 库存变动流水表 表名:`仓储管理_库存变动流水` | 字段名 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | 库存变动流水号 | bigint identity | 是 | 主键 | | 库存流水号 | bigint | 否 | 关联库存现存量 | | 业务类型 | nvarchar(50) | 是 | 入库、出库、退库、移库、盘盈、盘亏、调整 | | 业务单号 | nvarchar(100) | 否 | 入库单号、出库单号、盘点单号等 | | 业务主表流水号 | bigint | 否 | 来源主表流水号 | | 业务明细流水号 | bigint | 否 | 来源明细流水号 | | 物料流水号 | int | 是 | 物料 | | 物料编码 | nvarchar(100) | 否 | 冗余 | | 物料名称 | nvarchar(200) | 是 | 冗余 | | 图号或型号 | nvarchar(200) | 否 | 冗余 | | 库房流水号 | int | 是 | 变动发生库房 | | 库位流水号 | int | 是 | 变动发生库位 | | 批次编号 | nvarchar(100) | 否 | 批次 | | 变动前数量 | decimal(18,4) | 是 | 变动前库存 | | 变动数量 | decimal(18,4) | 是 | 入库为正,出库为负 | | 变动后数量 | decimal(18,4) | 是 | 变动后库存 | | 对方库房流水号 | int | 否 | 移库时使用 | | 对方库位流水号 | int | 否 | 移库时使用 | | 操作人 | int | 是 | UserID | | 操作时间 | datetime | 是 | 默认 GETDATE() | | 备注 | nvarchar(500) | 否 | 备注 | 主键:`PK_仓储管理_库存变动流水`,字段 `库存变动流水号`。 索引: | 索引 | 字段 | 用途 | | --- | --- | --- | | IX_库存变动流水_物料时间 | 物料流水号、操作时间 | 物料追溯 | | IX_库存变动流水_库位时间 | 库位流水号、操作时间 | 库位追溯 | | IX_库存变动流水_业务单据 | 业务类型、业务主表流水号、业务明细流水号 | 单据追溯 | ### 4.5 入库单主表 表名:`仓储管理_入库单主表` | 字段名 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | 入库单流水号 | bigint identity | 是 | 主键 | | 入库单号 | nvarchar(100) | 是 | 业务单号 | | 入库类型 | nvarchar(50) | 是 | 采购入库、自制件入库、退料入库、其他入库 | | 来源单号 | nvarchar(100) | 否 | 采购合同、生产任务等 | | 供应商 | nvarchar(200) | 否 | 采购入库时使用 | | 入库人 | int | 是 | UserID | | 入库日期 | datetime | 是 | 入库时间 | | 状态 | nvarchar(20) | 是 | 草稿、已入库、已作废 | | 备注 | nvarchar(500) | 否 | 备注 | | 创建人 | int | 是 | UserID | | 创建时间 | datetime | 是 | 默认 GETDATE() | | 修改人 | int | 否 | UserID | | 修改时间 | datetime | 否 | 修改时间 | 主键:`PK_仓储管理_入库单主表`。 唯一约束:`UK_仓储管理_入库单主表_入库单号`。 ### 4.6 入库单明细表 表名:`仓储管理_入库单明细表` | 字段名 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | 入库明细流水号 | bigint identity | 是 | 主键 | | 入库单流水号 | bigint | 是 | 外键,关联入库主表 | | 物料流水号 | int | 是 | 物料 | | 物料编码 | nvarchar(100) | 否 | 冗余 | | 物料名称 | nvarchar(200) | 是 | 冗余 | | 图号或型号 | nvarchar(200) | 否 | 冗余 | | 规格 | nvarchar(200) | 否 | 冗余 | | 单位 | nvarchar(50) | 否 | 冗余 | | 库房流水号 | int | 是 | 入库库房 | | 库位流水号 | int | 是 | 入库库位 | | 批次编号 | nvarchar(100) | 否 | 批次 | | 入库数量 | decimal(18,4) | 是 | 入库数量 | | 来源明细流水号 | bigint | 否 | 来源明细 | | 备注 | nvarchar(500) | 否 | 备注 | 主键:`PK_仓储管理_入库单明细表`。 外键: | 外键 | 字段 | 关联表 | | --- | --- | --- | | FK_入库明细_主表 | 入库单流水号 | 仓储管理_入库单主表.入库单流水号 | | FK_入库明细_库房 | 库房流水号 | 仓储管理_库房主表.库房流水号 | | FK_入库明细_库位 | 库位流水号 | 仓储管理_库位主表.库位流水号 | ### 4.7 出库单主表 表名:`仓储管理_出库单主表` | 字段名 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | 出库单流水号 | bigint identity | 是 | 主键 | | 出库单号 | nvarchar(100) | 是 | 业务单号 | | 出库类型 | nvarchar(50) | 是 | 领料出库、生产出库、销售出库、其他出库 | | 来源单号 | nvarchar(100) | 否 | 领料单、销售单等 | | 领用部门 | nvarchar(100) | 否 | 领用部门 | | 领用人 | nvarchar(100) | 否 | 领用人 | | 出库人 | int | 是 | UserID | | 出库日期 | datetime | 是 | 出库时间 | | 状态 | nvarchar(20) | 是 | 草稿、已出库、已作废 | | 备注 | nvarchar(500) | 否 | 备注 | | 创建人 | int | 是 | UserID | | 创建时间 | datetime | 是 | 默认 GETDATE() | | 修改人 | int | 否 | UserID | | 修改时间 | datetime | 否 | 修改时间 | 主键:`PK_仓储管理_出库单主表`。 唯一约束:`UK_仓储管理_出库单主表_出库单号`。 ### 4.8 出库单明细表 表名:`仓储管理_出库单明细表` | 字段名 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | 出库明细流水号 | bigint identity | 是 | 主键 | | 出库单流水号 | bigint | 是 | 外键,关联出库主表 | | 物料流水号 | int | 是 | 物料 | | 物料编码 | nvarchar(100) | 否 | 冗余 | | 物料名称 | nvarchar(200) | 是 | 冗余 | | 图号或型号 | nvarchar(200) | 否 | 冗余 | | 规格 | nvarchar(200) | 否 | 冗余 | | 单位 | nvarchar(50) | 否 | 冗余 | | 库房流水号 | int | 是 | 出库库房 | | 库位流水号 | int | 是 | 出库库位 | | 批次编号 | nvarchar(100) | 否 | 批次 | | 出库数量 | decimal(18,4) | 是 | 出库数量 | | 来源明细流水号 | bigint | 否 | 来源明细 | | 备注 | nvarchar(500) | 否 | 备注 | 主键:`PK_仓储管理_出库单明细表`。 外键: | 外键 | 字段 | 关联表 | | --- | --- | --- | | FK_出库明细_主表 | 出库单流水号 | 仓储管理_出库单主表.出库单流水号 | | FK_出库明细_库房 | 库房流水号 | 仓储管理_库房主表.库房流水号 | | FK_出库明细_库位 | 库位流水号 | 仓储管理_库位主表.库位流水号 | ### 4.9 移库单主表 表名:`仓储管理_移库单主表` | 字段名 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | 移库单流水号 | bigint identity | 是 | 主键 | | 移库单号 | nvarchar(100) | 是 | 业务单号 | | 移库类型 | nvarchar(50) | 是 | 同库移位、跨库调拨 | | 移库人 | int | 是 | UserID | | 移库日期 | datetime | 是 | 移库时间 | | 状态 | nvarchar(20) | 是 | 草稿、已移库、已作废 | | 备注 | nvarchar(500) | 否 | 备注 | | 创建人 | int | 是 | UserID | | 创建时间 | datetime | 是 | 默认 GETDATE() | | 修改人 | int | 否 | UserID | | 修改时间 | datetime | 否 | 修改时间 | ### 4.10 移库单明细表 表名:`仓储管理_移库单明细表` | 字段名 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | 移库明细流水号 | bigint identity | 是 | 主键 | | 移库单流水号 | bigint | 是 | 外键,关联移库主表 | | 物料流水号 | int | 是 | 物料 | | 批次编号 | nvarchar(100) | 否 | 批次 | | 原库房流水号 | int | 是 | 原库房 | | 原库位流水号 | int | 是 | 原库位 | | 目标库房流水号 | int | 是 | 目标库房 | | 目标库位流水号 | int | 是 | 目标库位 | | 移库数量 | decimal(18,4) | 是 | 移库数量 | | 备注 | nvarchar(500) | 否 | 备注 | ### 4.11 盘点单主表 表名:`仓储管理_盘点单主表` | 字段名 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | 盘点单流水号 | bigint identity | 是 | 主键 | | 盘点单号 | nvarchar(100) | 是 | 业务单号 | | 盘点名称 | nvarchar(200) | 是 | 盘点任务名称 | | 盘点范围 | nvarchar(50) | 是 | 全库、库房、库位、物料 | | 库房流水号 | int | 否 | 按库房盘点时使用 | | 开始时间 | datetime | 否 | 开始时间 | | 结束时间 | datetime | 否 | 结束时间 | | 状态 | nvarchar(20) | 是 | 草稿、盘点中、待确认、已确认、已作废 | | 创建人 | int | 是 | UserID | | 创建时间 | datetime | 是 | 默认 GETDATE() | | 确认人 | int | 否 | UserID | | 确认时间 | datetime | 否 | 确认时间 | | 备注 | nvarchar(500) | 否 | 备注 | ### 4.12 盘点单明细表 表名:`仓储管理_盘点单明细表` | 字段名 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | 盘点明细流水号 | bigint identity | 是 | 主键 | | 盘点单流水号 | bigint | 是 | 外键,关联盘点主表 | | 库存流水号 | bigint | 否 | 来源库存记录 | | 物料流水号 | int | 是 | 物料 | | 物料编码 | nvarchar(100) | 否 | 冗余 | | 物料名称 | nvarchar(200) | 是 | 冗余 | | 图号或型号 | nvarchar(200) | 否 | 冗余 | | 库房流水号 | int | 是 | 库房 | | 库位流水号 | int | 是 | 库位 | | 批次编号 | nvarchar(100) | 否 | 批次 | | 账面数量 | decimal(18,4) | 是 | 生成盘点时库存数量 | | 实盘数量 | decimal(18,4) | 否 | 盘点录入数量 | | 差异数量 | decimal(18,4) | 否 | 实盘 - 账面 | | 差异原因 | nvarchar(500) | 否 | 差异说明 | | 处理方式 | nvarchar(50) | 否 | 盘盈、盘亏、不调整 | | 是否已确认 | bit | 是 | 默认 0 | | 备注 | nvarchar(500) | 否 | 备注 | ## 5. 表关系设计 ```mermaid erDiagram 仓储管理_库房主表 ||--o{ 仓储管理_库位主表 : 包含 仓储管理_库房主表 ||--o{ 仓储管理_库存现存量 : 拥有 仓储管理_库位主表 ||--o{ 仓储管理_库存现存量 : 存放 库存管理_物料主文件_基本 ||--o{ 仓储管理_库存现存量 : 对应 仓储管理_入库单主表 ||--o{ 仓储管理_入库单明细表 : 包含 仓储管理_出库单主表 ||--o{ 仓储管理_出库单明细表 : 包含 仓储管理_移库单主表 ||--o{ 仓储管理_移库单明细表 : 包含 仓储管理_盘点单主表 ||--o{ 仓储管理_盘点单明细表 : 包含 仓储管理_库存现存量 ||--o{ 仓储管理_库存变动流水 : 产生 ``` 关系说明: | 关系 | 说明 | | --- | --- | | 一个库房有多个库位 | `仓储管理_库位主表.库房流水号` 指向库房 | | 一个库位可放多个物料 | 通过 `仓储管理_库存现存量` 表体现 | | 一个物料可在多个库位 | 通过 `仓储管理_库存现存量` 表体现 | | 入库、出库、移库、盘点都写流水 | `仓储管理_库存变动流水` 记录库存变化来源 | | 查询库存以现存量为准 | 综合查询不直接汇总单据,默认读取库存现存量 | | 追溯库存以流水为准 | 查原因时读取库存变动流水和来源单据 | ## 6. 库存处理存储过程设计 ### 6.1 公共库存增加过程 建议新增公共过程:`仓储管理_库存_增加` 入参: | 参数 | 说明 | | --- | --- | | 物料流水号 | 物料 | | 库房流水号 | 库房 | | 库位流水号 | 库位 | | 批次编号 | 批次 | | 数量 | 增加数量 | | 业务类型 | 入库、退料、盘盈、移入 | | 业务单号 | 来源单号 | | 业务主表流水号 | 来源主表 | | 业务明细流水号 | 来源明细 | | 操作人 | UserID | | 备注 | 备注 | 处理规则: 1. 在事务内锁定 `仓储管理_库存现存量` 的对应物料、库位、批次记录。 2. 存在则更新 `库存数量 = 库存数量 + 数量`。 3. 不存在则新增库存记录。 4. 写入库存变动流水。 5. 返回库存流水号和变动后数量。 ### 6.2 公共库存扣减过程 建议新增公共过程:`仓储管理_库存_扣减` 处理规则: 1. 在事务内锁定对应库存记录。 2. 校验库存记录存在。 3. 校验 `库存数量 - 冻结数量 >= 数量`。 4. 更新 `库存数量 = 库存数量 - 数量`。 5. 写入库存变动流水,`变动数量 = -数量`。 6. 返回库存流水号和变动后数量。 ### 6.3 公共库存移库过程 建议新增公共过程:`仓储管理_库存_移库` 处理规则: 1. 开启事务。 2. 调用或复用扣减逻辑扣减原库位库存。 3. 调用或复用增加逻辑增加目标库位库存。 4. 写入移库单和移库明细。 5. 写入库存变动流水。 6. 提交事务。 注意:扣减和增加必须在同一个事务内完成,不能由前端拆成两个请求。 ### 6.4 公共盘点确认过程 建议新增公共过程:`仓储管理_库存盘点_确认` 处理规则: 1. 校验盘点单状态为待确认。 2. 遍历盘点明细。 3. 差异数量为 0 的明细只标记确认。 4. 差异数量大于 0 的明细调用库存增加逻辑,业务类型为“盘盈”。 5. 差异数量小于 0 的明细调用库存扣减逻辑,业务类型为“盘亏”。 6. 明细全部处理完成后,盘点单状态改为已确认。 ## 7. 前端页面设计 ### 7.1 库房管理页面 建议路径:`src/views/WarehouseManagement/Warehouse/index.vue` 页面结构: 1. 搜索栏:库房编号、库房名称、库房类型、是否启用。 2. 表格:库房编号、库房名称、库房类型、地址、负责人、是否启用、备注。 3. 操作:新增、编辑、停用、查看库位。 接口名称建议: | 操作 | name | | --- | --- | | 查询 | 仓储管理_库房_查询 | | 新增 | 仓储管理_库房_增加 | | 编辑 | 仓储管理_库房_编辑 | | 停用 | 仓储管理_库房_停用 | ### 7.2 库位管理页面 建议优先复用或改造现有 `src/views/WarehouseManagement/LocationManagement`。 页面结构: 1. 搜索栏:库房、库区、库位编号、库位名称、是否启用。 2. 表格:库房名称、库位编号、库位名称、库区、货架、层号、容量、是否允许混放、是否启用。 3. 操作:新增、编辑、停用、查看物料。 接口名称建议: | 操作 | name | | --- | --- | | 查询 | 仓储管理_库位_查询 | | 新增 | 仓储管理_库位_增加 | | 编辑 | 仓储管理_库位_编辑 | | 停用 | 仓储管理_库位_停用 | | 查询库位物料 | 仓储管理_库位_物料明细_查询 | ### 7.3 物料入库页面 建议优先兼容现有 `src/views/WarehouseManagement/PurchasePartsStorage`、`Inboundscanning`、`WarehousingRecord` 等入库入口。 页面要求: 1. 入库时必须选择库房和库位。 2. 优先显示该物料已有库存库位。 3. 没有已有库存库位时显示全部启用库位。 4. 提交时传入 `库房流水号`、`库位流水号`、`物料流水号`、`入库数量`。 5. 后端必须通过公共库存增加过程维护库存。 ### 7.4 物料出库页面 建议路径可结合现有领料和出库页面,例如 `MaterialRequisition`、`OutboundDetails`。 页面要求: 1. 选择物料后展示该物料所有可用库存库位。 2. 用户选择具体库位和出库数量。 3. 页面校验数量,但最终以数据库事务校验为准。 4. 出库成功后刷新物料库位库存。 ### 7.5 物料盘点页面 建议优先改造现有 `src/views/WarehouseManagement/InventoryCheck/index.vue`。 页面功能: 1. 创建盘点单。 2. 生成盘点明细。 3. 按库房、库位、物料录入实盘数量。 4. 显示账面数量、实盘数量、差异数量。 5. 差异确认后更新库存。 6. 支持导出盘点表。 ### 7.6 物料综合查询页面 建议优先改造现有 `src/views/WarehouseManagement/InventoryQuery/index.vue`。 页面功能: 1. 主表按物料聚合显示总库存。 2. 主库位显示库存数量最大的库位。 3. 点击主库位弹出库位明细。 4. 点击物料编码弹出库存流水。 5. 支持正向查询和逆向查询切换。 ## 8. 查询 SQL 设计思路 ### 8.1 物料正向查询 ```sql SELECT k.物料流水号, k.物料编码, k.物料名称, k.图号或型号, k.规格, f.库房编号, f.库房名称, w.库位编号, w.库位名称, k.批次编号, k.库存数量, k.冻结数量, k.最后变动时间 FROM 仓储管理_库存现存量 k LEFT JOIN 仓储管理_库房主表 f ON k.库房流水号 = f.库房流水号 LEFT JOIN 仓储管理_库位主表 w ON k.库位流水号 = w.库位流水号 WHERE ISNULL(k.库存数量, 0) > 0 AND (@物料流水号 IS NULL OR k.物料流水号 = @物料流水号) ORDER BY f.库房编号, w.库位编号; ``` ### 8.2 库位逆向查询 ```sql SELECT f.库房编号, f.库房名称, w.库位编号, w.库位名称, k.物料流水号, k.物料编码, k.物料名称, k.图号或型号, k.规格, k.批次编号, k.库存数量, k.最后变动时间 FROM 仓储管理_库存现存量 k LEFT JOIN 仓储管理_库房主表 f ON k.库房流水号 = f.库房流水号 LEFT JOIN 仓储管理_库位主表 w ON k.库位流水号 = w.库位流水号 WHERE ISNULL(k.库存数量, 0) > 0 AND k.库位流水号 = @库位流水号 ORDER BY k.物料编码, k.物料名称; ``` ### 8.3 物料综合查询 ```sql WITH 汇总 AS ( SELECT 物料流水号, MAX(物料编码) AS 物料编码, MAX(物料名称) AS 物料名称, MAX(图号或型号) AS 图号或型号, MAX(规格) AS 规格, SUM(ISNULL(库存数量, 0)) AS 总库存 FROM 仓储管理_库存现存量 WHERE ISNULL(库存数量, 0) > 0 GROUP BY 物料流水号 ), 主库位 AS ( SELECT k.物料流水号, f.库房名称, w.库位名称, k.库存数量, ROW_NUMBER() OVER ( PARTITION BY k.物料流水号 ORDER BY ISNULL(k.库存数量, 0) DESC, k.库位流水号 ASC ) AS 排名 FROM 仓储管理_库存现存量 k LEFT JOIN 仓储管理_库房主表 f ON k.库房流水号 = f.库房流水号 LEFT JOIN 仓储管理_库位主表 w ON k.库位流水号 = w.库位流水号 WHERE ISNULL(k.库存数量, 0) > 0 ) SELECT h.物料流水号, h.物料编码, h.物料名称, h.图号或型号, h.规格, h.总库存, z.库房名称 AS 主库房名称, z.库位名称 AS 主库位名称, z.库存数量 AS 主库位库存 FROM 汇总 h LEFT JOIN 主库位 z ON h.物料流水号 = z.物料流水号 AND z.排名 = 1; ``` ## 9. 实施步骤 ### 9.1 第一阶段:数据库方案落地 1. 核对现有表:库房、货位、物料与货位对照、入库记录、出库记录、库存盘点。 2. 确认哪些表复用,哪些表新增。 3. 建立或补齐主外键关系。 4. 建立库存现存量唯一约束。 5. 建立库存变动流水表。 6. 编写公共库存增加、扣减、移库、盘点确认存储过程。 7. 在测试库 `ERPTOOL_JY_20250826Back` 编译并验证。 ### 9.2 第二阶段:入库和出库闭环 1. 改造入库接口,提交时必须传库房和库位。 2. 入库接口调用公共库存增加过程。 3. 改造出库接口,出库时必须指定库存现存量或库位。 4. 出库接口调用公共库存扣减过程。 5. 验证同一物料多库位、多批次场景。 ### 9.3 第三阶段:盘点闭环 1. 盘点页面支持生成盘点单。 2. 盘点明细记录账面数量。 3. 支持录入实盘数量和差异原因。 4. 确认盘点时调用盘点确认过程。 5. 验证盘盈、盘亏、无差异三类场景。 ### 9.4 第四阶段:综合查询闭环 1. 新增物料综合查询接口。 2. 新增物料库位明细查询接口。 3. 新增库位物料明细查询接口。 4. 前端支持正向查询和逆向查询。 5. 前端支持点击主库位查看全部库位库存。 6. 前端支持点击物料查看库存变动流水。 ### 9.5 第五阶段:历史数据整理 1. 从现有 `库存管理_物料与货位对照表` 或相近库存表迁移当前库存。 2. 迁移时必须保留物料、货位、库存数量、批次等关键字段。 3. 对没有库房归属的货位先补齐库房。 4. 对重复物料库位批次记录进行合并。 5. 迁移后核对物料总库存和原库存查询结果是否一致。 6. 历史 0 库存记录可暂不迁移,后续按盘点结果清理。 ## 10. 验收标准 | 验收项 | 标准 | | --- | --- | | 库房管理 | 可新增、编辑、停用库房 | | 库位管理 | 库位必须归属库房,同一库房库位编号不可重复 | | 入库 | 入库后指定库位库存增加,并生成库存流水 | | 出库 | 出库后指定库位库存减少,并生成库存流水 | | 库存不足 | 出库、移库、盘亏时库存不足必须阻止提交 | | 移库 | 原库位减少,目标库位增加,事务一致 | | 盘点 | 差异确认后库存正确增减 | | 正向查询 | 可查询某物料在哪些库位 | | 逆向查询 | 可查询某库位有哪些物料 | | 综合查询 | 总库存等于所有库位库存合计 | | 追溯 | 每一次库存变化都能查到来源单据和操作人 | ## 11. 风险与控制 | 风险 | 控制措施 | | --- | --- | | 多人同时出库导致负库存 | 数据库事务内加锁并重新校验库存 | | 前端拆分请求导致只扣不加 | 移库、盘点确认必须由后端单事务完成 | | 历史库存和新库存表不一致 | 迁移前备份,迁移后做总量对账 | | 库位停用后仍被选择 | 所有业务查询默认只返回启用库位 | | 物料多库位导致扣错库存 | 出库必须指定库位或库存流水号 | | 批次为空导致唯一约束失效 | 存储过程统一处理空批次 | ## 12. 推荐开发顺序 1. 先建立库房、库位、库存现存量、库存变动流水四张核心表。 2. 再做公共库存增加和扣减过程。 3. 再把入库和出库接入公共库存过程。 4. 再做移库和盘点。 5. 最后做综合查询、正向查询、逆向查询和报表优化。 这样做的原因是:只要库存现存量和库存变动流水先稳定,后续所有业务都只是围绕“增加、扣减、移动、调整”四类库存动作扩展,业务链路会更稳。 ## 13. 后续开发对象清单 ### 13.1 SQL 脚本 建议新增: ```text sql/仓储管理_库房库位库存基础表.sql sql/仓储管理_库存公共过程.sql sql/仓储管理_入库出库接入库存.sql sql/仓储管理_盘点流程.sql sql/仓储管理_库存综合查询.sql ``` ### 13.2 前端页面 建议新增或改造: ```text src/views/WarehouseManagement/Warehouse/index.vue src/views/WarehouseManagement/LocationManagement/index.vue src/views/WarehouseManagement/InventoryQuery/index.vue src/views/WarehouseManagement/InventoryCheck/index.vue src/views/WarehouseManagement/PurchasePartsStorage/index.vue src/views/WarehouseManagement/OutboundDetails/index.vue ``` ### 13.3 后端接口名称 建议新增: ```text 仓储管理_库房_查询 仓储管理_库房_增加 仓储管理_库房_编辑 仓储管理_库房_停用 仓储管理_库位_查询 仓储管理_库位_增加 仓储管理_库位_编辑 仓储管理_库位_停用 仓储管理_库存_物料正向查询 仓储管理_库存_库位逆向查询 仓储管理_库存_综合查询 仓储管理_库存_变动流水_查询 仓储管理_库存盘点_创建 仓储管理_库存盘点_明细_查询 仓储管理_库存盘点_实盘_编辑 仓储管理_库存盘点_确认 ``` 修改人:Ld 修改时间:2026-07-28 15:37:19