2026-05-20-qc-material-library-design.md 12 KB

质检物料库 + 物料使用扣减设计

日期: 2026-05-20 状态: 待审阅 父模块: 质量检测 (质量检测一级菜单)

1. 背景与目标

现状

「质量检测」一级菜单下已实现质检工单和质检任务的完整流程(样本接收 → 质检工单 → 质检任务 → 填写检测结果)。但质检任务中只记录了质量检测结果,没有记录质量检测过程中使用的物料(如试剂、耗材等)。

目标

  1. 在「质量检测」一级菜单下新增 质检物料库,用于管理质检专用的物料信息及库存
  2. 每次质检任务完成时,登记使用的物料及用量,从物料库 扣减库存
  3. 支持手动入库补充库存
  4. 通过物料变动记录实现 盘存 目的

约束

  • 质检物料库 独立于 生产模块的耗材 (biz_consumable) 和试剂 (biz_reagent)
  • 简单模式:主表 + 库存量 + 变动记录,不做批次、有效期、库位管理
  • 扣减时机:质检任务完成时一次性扣减
  • 入库方式:手动入库(直接增加数量)

2. 数据库设计

2.1 biz_qc_material(质检物料主表)

DROP TABLE IF EXISTS `biz_qc_material`;
CREATE TABLE `biz_qc_material` (
  `id` varchar(64) NOT NULL COMMENT '主键ID',
  `material_code` varchar(64) NOT NULL COMMENT '物料编码',
  `material_name` varchar(200) NOT NULL COMMENT '物料名称',
  `spec_model` varchar(200) DEFAULT NULL COMMENT '规格型号',
  `unit` varchar(32) DEFAULT NULL COMMENT '单位',
  `stock_qty` decimal(18,4) NOT NULL DEFAULT 0.0000 COMMENT '当前库存量',
  `warning_qty` decimal(18,4) NOT NULL DEFAULT 0.0000 COMMENT '预警库存量',
  `status` char(1) NOT NULL DEFAULT '1' COMMENT '1-启用 0-停用',
  `tenant_no` varchar(64) NOT NULL DEFAULT 'zkxw' COMMENT '租户编号',
  `order_num` int(11) DEFAULT NULL COMMENT '排序号',
  `remark` varchar(512) DEFAULT NULL COMMENT '备注',
  `create_by` varchar(64) DEFAULT NULL COMMENT '创建人id',
  `create_dept_id` varchar(64) NOT NULL DEFAULT '' COMMENT '创建人部门ID',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_by` varchar(64) DEFAULT NULL COMMENT '更新人id',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `del_flag` tinyint(4) NOT NULL DEFAULT '0' COMMENT '删除标记:0-正常 1-已删除',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_qc_mat_tenant_code` (`tenant_no`, `material_code`, `del_flag`),
  KEY `idx_qc_mat_tenant_status` (`tenant_no`, `status`, `del_flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='质检物料';

2.2 biz_qc_material_usage(物料变动记录)

DROP TABLE IF EXISTS `biz_qc_material_usage`;
CREATE TABLE `biz_qc_material_usage` (
  `id` varchar(64) NOT NULL COMMENT '主键ID',
  `material_id` varchar(64) NOT NULL COMMENT '物料ID',
  `material_code` varchar(64) DEFAULT NULL COMMENT '物料编码快照',
  `material_name` varchar(200) DEFAULT NULL COMMENT '物料名称快照',
  `change_type` varchar(16) NOT NULL COMMENT '变动类型:use使用 / in入库',
  `change_qty` decimal(18,4) NOT NULL COMMENT '变动数量(使用为负,入库为正)',
  `stock_after` decimal(18,4) NOT NULL COMMENT '变动后库存量',
  `qc_task_id` varchar(64) DEFAULT NULL COMMENT '关联质检任务ID(使用时有值)',
  `qc_task_no` varchar(32) DEFAULT NULL COMMENT '质检任务号快照',
  `source_type` varchar(16) NOT NULL COMMENT '来源类型:task_complete任务完成 / manual_in手动入库',
  `tenant_no` varchar(64) NOT NULL DEFAULT 'zkxw' COMMENT '租户编号',
  `remark` varchar(512) DEFAULT NULL COMMENT '备注',
  `create_by` varchar(64) DEFAULT NULL COMMENT '创建人id',
  `create_dept_id` varchar(64) NOT NULL DEFAULT '' COMMENT '创建人部门ID',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_by` varchar(64) DEFAULT NULL COMMENT '更新人id',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `del_flag` tinyint(4) NOT NULL DEFAULT '0' COMMENT '删除标记:0-正常 1-已删除',
  PRIMARY KEY (`id`),
  KEY `idx_qc_mu_material` (`material_id`, `del_flag`),
  KEY `idx_qc_mu_task` (`qc_task_id`, `del_flag`),
  KEY `idx_qc_mu_tenant_time` (`tenant_no`, `change_type`, `create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='质检物料变动记录';

2.3 菜单数据

在 sys_menu 表中,父菜单 70000000000000000000000000000001(质量检测)下新增:

-- 质检物料库
INSERT INTO `sys_menu` (`id`, `menu_name`, `parent_id`, `menu_type`, `path`, `component`, `perms`, `is_frame`, `visible`, `status`, `tenant_no`, `order_num`, `remark`, `create_by`, `create_dept_id`, `create_time`, `update_by`, `update_time`, `del_flag`)
VALUES ('70000000000000000000000000000009', '质检物料库', '70000000000000000000000000000001', 'C', 'qc-material', '/quality-inspection/qc-material/index', 'biz:qcMaterial:list', 1, '1', '1', 'zkxw', 8, NULL, NULL, '', NOW(), NULL, NOW(), 0);

-- 物料变动记录
INSERT INTO `sys_menu` (`id`, `menu_name`, `parent_id`, `menu_type`, `path`, `component`, `perms`, `is_frame`, `visible`, `status`, `tenant_no`, `order_num`, `remark`, `create_by`, `create_dept_id`, `create_time`, `update_by`, `update_time`, `del_flag`)
VALUES ('70000000000000000000000000000010', '物料变动记录', '70000000000000000000000000000001', 'C', 'qc-material-usage', '/quality-inspection/qc-material-usage/index', 'biz:qcMaterialUsage:list', 1, '1', '1', 'zkxw', 9, NULL, NULL, '', NOW(), NULL, NOW(), 0);

3. 业务流程

3.1 物料库管理

新增物料:填写编码、名称、规格、单位、预警量 → stock_qty 初始为 0
编辑物料:修改名称、规格、预警量等(编码不可改)
停用物料:设置 status=0,不影响历史变动记录
删除物料:软删除 del_flag=1,仅限库存为 0 的物料

3.2 手动入库

在物料库页面点击"入库"按钮 → 弹窗中填写入库数量、备注
→ 校验:入库数量 > 0
→ 更新 biz_qc_material.stock_qty += 入库数量
→ 写入 biz_qc_material_usage(change_type=in, source_type=manual_in)

3.3 质检任务完成 + 物料扣减

质检人员点击"完成任务" → 弹窗:
  ① 现有的检测结果填写区域
  ② 新增:物料使用表格(可添加多行)
     - 从物料库下拉选择(仅显示 status=1 且 stock_qty > 0 的物料)
     - 自动带出:物料名称、规格、当前库存
     - 填写:使用数量

提交:
  ① 保存检测结果(现有逻辑不变)
  ② 遍历物料使用行:
     - 校验:使用数量 ≤ 物料当前 stock_qty
     - 更新 biz_qc_material.stock_qty -= 使用数量
     - 写入 biz_qc_material_usage(change_type=use, source_type=task_complete, qc_task_id=任务ID)
  ③ 更新任务状态为已完成(现有逻辑不变)

失败回滚:任何一行物料校验不通过,整个提交回滚,任务状态不变

3.4 盘存

物料变动记录页面:
  - 支持按物料、变动类型、时间范围筛选
  - 每条记录显示:物料名称、变动类型、变动数量、变动后库存、关联任务号、操作人、时间
  - 可导出为盘点报表

4. 后端实现

4.1 新增文件

文件 说明
backend/app/models/qc_material.py BizQcMaterial + BizQcMaterialUsage SQLAlchemy 模型
backend/app/crud/qc_material.py 物料 CRUD: list/get/create/update/soft_delete + stock_in(入库)
backend/app/crud/qc_material_usage.py 变动记录: list + deduct_for_task(扣减)

4.2 修改文件

文件 修改内容
backend/app/api/qc.py 新增物料库和变动记录的路由端点
backend/app/api/__init__.py 无需修改(共用 qc_router)
backend/app/crud/qc_task.py complete_with_result 方法扩展:接收物料使用数据,调用 deduct_for_task

4.3 API 端点设计

# 质检物料库
GET    /api/admin/web/admin/qc-materials              # 物料列表(分页、关键词搜索)
GET    /api/admin/web/admin/qc-materials/options       # 下拉选项(status=1)
POST   /api/admin/web/admin/qc-materials               # 新增物料
PUT    /api/admin/web/admin/qc-materials/{id}           # 编辑物料
DELETE /api/admin/web/admin/qc-materials/{id}           # 删除物料(软删除)
POST   /api/admin/web/admin/qc-materials/{id}/stock-in  # 手动入库

# 物料变动记录
GET    /api/admin/web/admin/qc-material-usages          # 变动记录列表(分页、筛选)

# 修改现有端点
POST   /api/admin/web/admin/qc-tasks/{id}/complete-with-result  # 扩展请求体,增加 materialUsages 字段

4.4 CRUD 模式

遵循 backend/app/crud/qc_third_party_company.py 的标准模式:

  • _row_to_dict() - 序列化,camelCase 键名
  • list_xxx() - 分页 + keyword 搜索 + tenant_no 过滤 + create_time DESC
  • get_xxx() - 按 ID + del_flag=0
  • create_xxx() - UUID ID,strip 字符串,编码唯一性校验
  • update_xxx() - 部分更新(仅非 None 字段)
  • soft_delete_xxx() - del_flag=1

5. 前端实现

5.1 新增文件

文件 说明
web-admin/src/api/qc-material.ts 物料 API 类型定义 + fetch 函数
web-admin/src/api/qc-material-usage.ts 变动记录 API 类型定义 + fetch 函数
web-admin/src/views/quality-inspection/qc-material/index.vue 质检物料库列表页
web-admin/src/views/quality-inspection/qc-material-usage/index.vue 物料变动记录列表页

5.2 修改文件

文件 修改内容
web-admin/src/router/modules/sqxp.ts 新增 qc-material 和 qc-material-usage 路由
web-admin/src/views/quality-inspection/qc-task/index.vue 完成任务弹窗中嵌入物料使用表格
web-admin/src/utils/status-tag-registry.ts 新增 changeType 注册(use/in)

5.3 页面设计

质检物料库页面(参照 production/consumable/index.vue):

  • 标准列表:编码、名称、规格型号、单位、当前库存、预警库存、状态
  • 工具栏:搜索 + 新增按钮
  • 操作列:编辑、入库、停用/启用、删除
  • 入库弹窗:入库数量(el-input-number)+ 备注
  • 库存预警:stock_qty <= warning_qty 时,库存列标红显示

物料变动记录页面(参照标准列表页):

  • 筛选条件:物料(下拉)、变动类型(下拉)、时间范围
  • 列表列:物料名称、物料编码、变动类型(Tag)、变动数量、变动后库存、关联任务号、操作人、时间
  • 只读列表,无新增/编辑/删除操作

完成任务弹窗扩展(修改现有 qc-task 完成弹窗):

  • 在现有检测结果区域下方,新增"物料使用"折叠面板或分隔区域
  • 物料使用表格:物料选择(远程搜索下拉)、规格(自动带出)、当前库存(自动带出)、使用数量(el-input-number)、操作(删除行)
  • 添加物料行按钮
  • 提交时校验:每行使用数量 > 0 且 ≤ 当前库存

6. 影响范围

不影响的部分

  • 现有质检工单创建/配置流程不变
  • 现有质检任务列表/查看/启动逻辑不变
  • 现有检测结果保存逻辑不变
  • 生产模块的耗材/试剂管理不受影响
  • 物料使用是 可选的,不填物料也能完成任务(向后兼容)

需要注意的

  • complete_with_result API 的请求体扩展需要向后兼容:materialUsages 为可选字段,为空时不执行扣减
  • 并发扣减防护:在 deduct_for_task 中使用数据库行锁(SELECT ... FOR UPDATE)确保库存不超扣

7. 未来扩展(当前不做)

  • 批次号管理
  • 有效期管理
  • 采购/入库单据流程
  • 库位管理
  • 自动盘点
  • 物料预警通知(当库存低于预警量时推送消息)