【仓库】库存盘点
库存盘点模块,由 yudao-module-mes 后端模块的 wm.stocktaking 包实现,覆盖仓库物料的实物盘点场景——通过创建盘点方案和盘点任务,将系统账面库存与实际库存进行核对,识别盘盈/盘亏差异。
本文涉及两个子模块:
- 盘点方案:定义盘点范围(按仓库/库区/库位/物料/批次/质量状态维度筛选),作为盘点任务的模板。
- 盘点任务:基于盘点方案生成实际盘点清单,由盘点人逐行录入实盘数量,系统自动对比并生成盘盈/盘亏结果。
本文涉及表如下图所示:

# 1. 盘点方案
盘点方案,由 MesWmStockTakingPlanController 提供接口。盘点方案是盘点任务的模板,定义「盘什么」。
# 1.1 表结构
省略 creator/create_time/updater/update_time/deleted/tenant_id 等通用字段
CREATE TABLE `mes_wm_stock_taking_plan` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`code` varchar(64) NOT NULL COMMENT '方案编码',
`name` varchar(128) DEFAULT NULL COMMENT '方案名称',
`type` tinyint DEFAULT NULL COMMENT '盘点类型',
`start_time` datetime DEFAULT NULL COMMENT '开始时间',
`end_time` datetime DEFAULT NULL COMMENT '结束时间',
`blind_flag` bit(1) DEFAULT NULL COMMENT '是否盲盘',
`frozen` bit(1) DEFAULT NULL COMMENT '是否冻结库存',
`status` tinyint NOT NULL DEFAULT '1' COMMENT '状态',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='MES 盘点方案';
① type 为盘点类型,枚举 MesWmStockTakingTypeEnum(1=静态盘点,2=动态盘点)。动态盘点时需填写 start_time、end_time(有效时间窗口),非动态盘点时系统自动清空时间字段。
② blind_flag 标识是否盲盘。盲盘模式下,盘点人在录入实盘数量时看不到系统账面数量,避免先入为主的干扰。frozen 标识是否在盘点期间冻结库存,冻结后相关库存不可被其他出入库单据消耗。
③ status 使用通用状态 CommonStatusEnum(0=开启,1=关闭)。关闭状态下可编辑和删除,开启后方可被盘点任务引用。开启时校验方案参数不能为空。
该表包含一个子表:
mes_wm_stock_taking_plan_param(方案参数):在编辑页面中维护,定义盘点范围的筛选条件。
# 1.2 管理后台
对应 [MES 系统 -> 仓库管理 -> 盘点方案] 菜单,对应 yudao-ui-admin-vue3 项目的 @/views/mes/wm/stocktaking/plan 目录。
# 列表
支持按方案编码、名称、盘点类型等条件搜索。

# 新增
点击【新增】或【编辑】按钮(仅关闭状态可编辑),弹出盘点方案表单。主要填写方案编码(可自动生成)、方案名称、盘点类型、是否盲盘、是否冻结库存、时间范围(动态盘点时填写)。表单下方维护方案参数。

# 修改
点击编码链接或【编辑】按钮,弹出修改表单。表单下方展示子表数据:
★ 方案参数(编辑页面下方):由 mes_wm_stock_taking_plan_param 表存储,定义盘点范围的筛选条件。由 MesWmStockTakingPlanParamController 提供接口。
mes_wm_stock_taking_plan_param 表结构
CREATE TABLE `mes_wm_stock_taking_plan_param` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`plan_id` bigint NOT NULL COMMENT '方案ID',
`type` smallint NOT NULL COMMENT '参数类型',
`value_id` bigint NOT NULL COMMENT '参数值ID',
`value_code` varchar(64) DEFAULT NULL COMMENT '参数值编码',
`value_name` varchar(128) DEFAULT NULL COMMENT '参数值名称',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='MES 盘点方案参数';
① plan_id 关联主表 mes_wm_stock_taking_plan 的 id 字段。
② type 为参数类型,枚举 MesWmStockTakingPlanParamTypeEnum(WAREHOUSE=仓库,LOCATION=库区,AREA=库位,ITEM=物料,BATCH=批次,QUALITY_STATUS=质量状态),决定盘点范围按哪个维度筛选。
③ value_id、value_code、value_name 为参数值,分别存储选择的仓库/库区/物料等的 ID、编码、名称。一个方案可以有多个参数,多个同类型参数取并集,不同类型参数取交集。
# 开启/关闭
在列表页点击状态开关。开启时校验方案参数不能为空,开启后方案不可编辑和删除,可被盘点任务引用。
# 2. 盘点任务
盘点任务,由 MesWmStockTakingTaskController 提供接口。盘点任务是实际执行盘点的载体,关联盘点方案并生成盘点清单。
# 2.1 表结构
省略 creator/create_time/updater/update_time/deleted/tenant_id 等通用字段
CREATE TABLE `mes_wm_stock_taking_task` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`code` varchar(64) NOT NULL COMMENT '任务编码',
`name` varchar(128) DEFAULT NULL COMMENT '任务名称',
`type` tinyint DEFAULT NULL COMMENT '盘点类型',
`plan_id` bigint DEFAULT NULL COMMENT '盘点方案ID',
`user_id` bigint NOT NULL COMMENT '盘点人',
`taking_date` datetime DEFAULT NULL COMMENT '盘点日期',
`blind_flag` bit(1) DEFAULT NULL COMMENT '是否盲盘',
`frozen` bit(1) DEFAULT NULL COMMENT '是否冻结库存',
`start_time` datetime DEFAULT NULL COMMENT '开始时间',
`end_time` datetime DEFAULT NULL COMMENT '结束时间',
`status` tinyint NOT NULL DEFAULT '0' COMMENT '状态',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='MES 盘点任务';
① plan_id 关联 mes_wm_stock_taking_plan 表的 id 字段(选填),标识基于哪个盘点方案创建。创建/编辑时校验方案需为「开启」状态。关联方案后,系统根据方案参数自动生成盘点清单行。
② user_id 关联系统用户表,标识盘点人(必填)。type、blind_flag、frozen、start_time、end_time 可从方案继承或手动填写。
③ status 为盘点任务状态,枚举 MesWmStockTakingTaskStatusEnum:
| 状态值 | 枚举 | 说明 | 可执行操作 |
|---|---|---|---|
| 0 | PREPARE | 草稿 | 编辑、提交、删除 |
| 2 | APPROVING | 审批中 | 完成、取消 |
| 4 | FINISHED | 已完成 | — |
| 5 | CANCELED | 已取消 | — |
状态流转说明
创建 ──→ 草稿(0) ──提交──→ 审批中(2) ──完成──→ 已完成(4)
│
└──取消──→ 已取消(5)
- 创建(
createStockTakingTask):创建盘点任务,初始状态为草稿。若关联了盘点方案,系统根据方案参数自动查询库存台账并生成盘点清单行。 - 提交(
submitStockTakingTask):校验盘点清单行不能为空。状态变为「审批中」。若frozen=true,同时冻结相关库存。 - 完成(
finishStockTakingTask):状态变为「已完成」。若frozen=true,同时解除库存冻结。 - 取消(
cancelStockTakingTask):已完成和已取消状态不允许取消。若frozen=true,同时解除库存冻结。
该表包含两个子表:
mes_wm_stock_taking_task_line(盘点清单行):根据方案自动生成或手工添加,记录待盘点的物料及系统账面数量。mes_wm_stock_taking_task_result(盘点结果):提交后录入实盘数量,系统自动对比生成盘盈/盘亏结果。
# 2.2 管理后台
对应 [MES 系统 -> 仓库管理 -> 盘点任务] 菜单,对应 yudao-ui-admin-vue3 项目的 @/views/mes/wm/stocktaking/task 目录。
# 列表
支持按任务编码、名称、盘点类型、盘点日期、状态等条件搜索。

# 新增
点击【新增】按钮,弹出盘点任务新增表单。主要填写任务编码(可自动生成)、任务名称、盘点方案(选填)、盘点人(必填)、盘点类型、盘点日期、是否盲盘、是否冻结库存。新建成功后弹窗自动切换为编辑模式,在表单下方展示盘点清单。

# 修改
点击编码链接或【编辑】按钮(仅草稿状态可编辑),弹出盘点任务修改表单。表单下方通过 el-divider 分隔展示盘点清单行列表。

★ 盘点清单行(编辑弹窗下方):由 mes_wm_stock_taking_task_line 表存储,记录待盘点的物料、库位和系统账面数量。由 MesWmStockTakingTaskLineController 提供接口。
mes_wm_stock_taking_task_line 表结构
CREATE TABLE `mes_wm_stock_taking_task_line` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`task_id` bigint NOT NULL COMMENT '盘点任务ID',
`item_id` bigint NOT NULL COMMENT '物料ID',
`quantity` decimal(24,6) DEFAULT NULL COMMENT '系统账面数量',
`taking_quantity` decimal(24,6) DEFAULT NULL COMMENT '实盘数量',
`material_stock_id` bigint DEFAULT NULL COMMENT '库存记录ID',
`batch_id` bigint DEFAULT NULL COMMENT '批次ID',
`batch_code` varchar(50) DEFAULT NULL COMMENT '批次号',
`warehouse_id` bigint NOT NULL COMMENT '仓库ID',
`location_id` bigint NOT NULL COMMENT '库区ID',
`area_id` bigint NOT NULL COMMENT '库位ID',
`status` tinyint DEFAULT NULL COMMENT '盘点结果状态',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='MES 盘点任务行';
① task_id 关联主表 mes_wm_stock_taking_task 的 id 字段。
② item_id 关联 mes_md_item 表的 id 字段,标识待盘点物料。quantity 为系统账面数量(创建时根据库存台账自动填充)。taking_quantity 为实盘数量(由盘点人手工录入)。
③ material_stock_id 关联 mes_wm_material_stock,标识对应的库存记录。batch_id、batch_code 关联批次信息。
④ warehouse_id、location_id、area_id 标识待盘点物料所在的仓库/库区/库位。
⑤ status 为盘点结果状态,枚举 MesWmStockTakingTaskLineStatusEnum(1=正常,2=盘盈,3=盘亏)。系统根据实盘数量与账面数量对比自动计算:
taking_quantity=quantity→ 正常(1)taking_quantity>quantity→ 盘盈(2)taking_quantity<quantity→ 盘亏(3)
# 提交
在编辑弹窗中点击【提交】按钮(仅草稿状态下显示)。校验盘点清单行不能为空。提交后进入「审批中」状态,若启用冻结,同时冻结相关库存记录。
# 盘点结果
在「审批中」状态下,可查看盘点结果。

★ 盘点结果(详情页中):由 mes_wm_stock_taking_task_result 表存储,汇总每行的账面数量与实盘数量的对比。由 MesWmStockTakingTaskResultController 提供接口。
mes_wm_stock_taking_task_result 表结构
CREATE TABLE `mes_wm_stock_taking_task_result` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
`task_id` bigint NOT NULL COMMENT '盘点任务ID',
`line_id` bigint NOT NULL COMMENT '盘点行ID',
`item_id` bigint NOT NULL COMMENT '物料ID',
`quantity` decimal(10,2) DEFAULT NULL COMMENT '系统账面数量',
`taking_quantity` decimal(10,2) DEFAULT NULL COMMENT '实盘数量',
`material_stock_id` bigint DEFAULT NULL COMMENT '库存记录ID',
`batch_id` bigint DEFAULT NULL COMMENT '批次ID',
`batch_code` varchar(64) DEFAULT NULL COMMENT '批次号',
`warehouse_id` bigint NOT NULL COMMENT '仓库ID',
`location_id` bigint NOT NULL COMMENT '库区ID',
`area_id` bigint NOT NULL COMMENT '库位ID',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='MES 盘点结果';
① task_id 关联主表(冗余字段)。line_id 关联盘点清单行 mes_wm_stock_taking_task_line 的 id 字段。
② item_id 为盘点物料。quantity 为系统账面数量,taking_quantity 为实盘数量。
③ material_stock_id、batch_id、batch_code 从盘点清单行继承。
④ warehouse_id、location_id、area_id 从盘点清单行继承。
# 完成
在「审批中」状态下,点击【完成】按钮。状态变为「已完成」。若启用冻结,同时解除库存冻结。
# 取消
在列表页点击【取消】按钮(已完成和已取消状态不允许取消,其他状态均可取消),需二次确认。若启用冻结,同时解除库存冻结。取消后不可恢复。
# 3. 盘点业务流程总览
端到端业务流程
盘点方案:定义盘点范围(仓库/库区/物料/批次等维度筛选)
│
│ 引用
↓
盘点任务:创建 ──→ 自动生成清单行(从库存台账匹配) ──→ 提交(冻结库存)
│
│ 盘点人逐行录入实盘数量
↓
盘点结果:系统自动对比 → 正常 / 盘盈 / 盘亏
│
│ 完成(解除冻结)
↓
后续处理:盘盈 → 通过「其他入库」调增库存
盘亏 → 通过「其他出库」调减库存
- 盘点方案定义盘点范围,通过参数组合实现灵活筛选(同类型并集,跨类型交集)。
- 盘点任务关联方案后自动生成清单行,盘点人只需录入实盘数量。盲盘模式下隐藏账面数量。
- 库存冻结确保盘点期间库存不被其他业务变动,保证盘点结果准确性。
- 差异处理:盘点模块本身不直接修改库存,盘盈/盘亏需通过「其他入库」或「其他出库」(详见 《【仓库】其他入库、其他出库》)进行库存调整。