2026-05-21-cell-product-library-design.md 10.0 KB

细胞产品库(Cell Product Library)字段重设计

日期: 2026-05-21 状态: 已确认,待实施 范围: web-admin/src/views/production/cell-product/ + backend/app/ 相关文件


1. 背景与目标

1.1 现状

biz_cell_product 表已有基本 CRUD 功能:产品编码、产品名称、产品类型、规格、批次号、储物格位置、数量、单位、有效期、产品图片、备注。状态字段使用 zk/yc/ysy 缩写且代码中存在不一致。

1.2 新需求

  1. 细胞产品有代次(P1~P8,下拉选择)
  2. 有冻存日期(哪天开始冻存)
  3. 每份产品有预计细胞数量(单位:亿)
  4. 有活性百分比(用户填写 0~100 的数字)
  5. 状态重新定义为:已冻存 / 已售卖 / 已使用
  6. 产品编码自动生成(CP + YYYYMMDD + 6位序列号),生成后可编辑
  7. 产品图片改为上传方式,参考【采集协议单录入】附件上传 UI 样式
  8. 新增查看弹窗(只读详情页)

1.3 不在本次范围

  • 批量生成功能(后续对接生产模块时实现)
  • 生产任务自动生成细胞产品
  • 状态变更的审批流程

2. 数据库设计

2.1 新增字段

在 biz_cell_product 表中新增以下 4 个字段(放在业务字段区域,tenant_no 之前):

ALTER TABLE biz_cell_product
  ADD COLUMN `passage` VARCHAR(8) DEFAULT NULL COMMENT '代次(P1~P8)' AFTER `storage_slot_id`,
  ADD COLUMN `freeze_date` DATETIME DEFAULT NULL COMMENT '冻存日期' AFTER `passage`,
  ADD COLUMN `expected_cell_count` DECIMAL(18,4) DEFAULT NULL COMMENT '预计细胞数量(单位:亿)' AFTER `freeze_date`,
  ADD COLUMN `viability` DECIMAL(5,2) DEFAULT NULL COMMENT '活性(百分比,0~100)' AFTER `expected_cell_count`;

2.2 状态字段更新

product_status 字段(varchar(16))的值从 zk/yc/ysy 改为:

状态值 显示名 Tag 颜色 说明
frozen 已冻存 success(绿色) 新建时的默认状态
sold 已售卖 warning(橙色) 通过编辑弹窗变更
used 已使用 info(灰色) 通过编辑弹窗变更
ALTER TABLE biz_cell_product
  MODIFY COLUMN `product_status` VARCHAR(16) DEFAULT 'frozen' COMMENT '状态: frozen已冻存/sold已售卖/used已使用';

2.3 完整字段清单(按顺序)

# DB 列名 类型 必填 默认值 说明
1 id varchar(64) PK ✓ UUID 主键
2 product_code varchar(64) ✓ 自动生成 产品编码 CP+YYYYMMDD+6位序号
3 product_name varchar(200) ✓ 产品名称
4 product_type_id varchar(64) 细胞产品类型ID (FK)
5 spec_id varchar(64) 规格ID (FK)
6 batch_no varchar(64) ✓ 批次号
7 storage_slot_id varchar(64) 储物格ID (FK)
8 passage varchar(8) 代次 P1~P8
9 freeze_date datetime 冻存日期
10 expected_cell_count decimal(18,4) 预计细胞数量(亿)
11 viability decimal(5,2) 活性(0~100%)
12 product_status varchar(16) ✓ frozen 状态
13 source_type varchar(20) manual 来源
14 production_task_id varchar(64) 来源生产任务ID
15 quantity decimal(18,4) 数量
16 unit varchar(64) 单位
17 expiry_date datetime 有效期
18 product_images varchar(4000) 产品图片URL(逗号分隔)
— tenant_no ~ del_flag — — — 公共字段

3. 状态流转

新建 → 已冻存 (frozen, 默认)
           ├─→ 已售卖 (sold)  [编辑弹窗]
           └─→ 已使用 (used)  [编辑弹窗]

规则:

  • 状态变更仅通过编辑弹窗操作
  • 已售卖/已使用不可回退为已冻存(单向流转)
  • 只有 frozen 状态的产品才能被编辑改为 sold 或 used
  • 已售卖和已使用之间不可互转

4. 产品编码自动生成

4.1 规则

格式: CP + YYYYMMDD + 6位序列号(左补零)
示例: CP20260521000001

4.2 后端接口

新增 GET /web/admin/cell-products/next-code:

  • 查询当天已有最大编码,+1 返回下一个编码
  • 如果当天无记录,返回 CPYYYYMMDD000001
  • 响应:{ "code": "CP20260521000001" }

4.3 前端交互

  • 新增弹窗打开时,自动调用 next-code 接口填充产品编码
  • 产品编码字段可编辑,用户可手动修改
  • 编辑弹窗中产品编码只读

5. 前端界面设计

5.1 列表页

页面路径: /production/cell-product

参考模板: src/views/system/order/index.vue(复杂列表)

表格列(14列):

# 列名 宽度 说明
1 序号 60 type=index
2 产品编码 180 product_code
3 产品名称 160 product_name
4 产品类型 120 关联显示类型名称
5 规格 120 关联显示规格名称
6 代次 80 passage
7 批次号 140 batch_no
8 储物格位置 140 关联显示储物格路径
9 预计细胞数量(亿) 140 expected_cell_count
10 活性(%) 90 viability
11 状态 100 <el-tag> Tag 展示
12 有效期 120 expiry_date, YYYY-MM-DD
13 操作 ≥260 fixed="right": 查看、编辑、删除

搜索筛选栏:

  • 关键词(模糊搜索,搜索产品编码/产品名称)
  • 产品状态下拉(已冻存/已售卖/已使用)
  • 代次下拉(P1~P8)

工具栏:

  • 已选 N 项
  • 新增按钮(type="primary")
  • 删除按钮(批量)

5.2 新增/编辑弹窗

布局: label-position="top", 2 列网格 (.form-grid-2)

字段排列(左列 → 右列):

行 左列 右列
1 产品编码(自动填充,可编辑;编辑时只读) 产品名称(必填)
2 产品类型(下拉) 规格(下拉)
3 代次(下拉 P1~P8) 批次号(必填)
4 储物格位置(下拉) 预计细胞数量(数字输入,label 显示"预计细胞数量(亿)")
5 活性(数字输入 0~100,label 显示"活性(%)") 冻存日期(日期选择器)
6 数量 单位
7 有效期(日期选择器) 状态(编辑时可选,新增时隐藏/固定为 frozen)
8 产品图片(跨2列,上传组件,参考采集协议单附件上传样式)
9 备注(跨2列,textarea)

下拉数据来源:

  • 产品类型:/web/admin/cell-product-types 接口
  • 规格:/web/admin/cell-product-specs 接口
  • 储物格位置:库位管理接口,显示完整路径(/分隔)
  • 代次:前端硬编码选项 P1~P8

编辑弹窗状态字段:

  • 仅当当前状态为 frozen 时,显示状态下拉可改为 sold 或 used
  • 状态已为 sold 或 used 时,状态字段只读

5.3 查看弹窗

布局: 参考 SystemViewDialog 组件模式

展示字段:

  • 产品编码、产品名称
  • 产品类型(名称)、规格(名称)
  • 代次、批次号
  • 储物格位置(完整路径)
  • 预计细胞数量(亿)、活性(%)
  • 数量、单位
  • 冻存日期、有效期
  • 状态(<el-tag> 展示)
  • 产品图片(缩略图展示)
  • 备注

状态字段 使用 <el-tag> 渲染:

  • frozen → <el-tag type="success" size="small">已冻存</el-tag>
  • sold → <el-tag type="warning" size="small">已售卖</el-tag>
  • used → <el-tag type="info" size="small">已使用</el-tag>

5.4 产品图片上传

  • 参考【采集协议单录入】模块的附件上传 UI 样式
  • 上传触发器为卡片式(虚线边框),inline 排列
  • 支持多图上传
  • 上传后显示缩略图卡片,支持预览和删除
  • 图片存储使用 MinIO 对象存储

6. 后端改动

6.1 Model(backend/app/models/models.py — BizCellProduct)

新增 4 个 Column:passage、freeze_date、expected_cell_count、viability

更新 product_status 默认值为 'frozen'

6.2 Schema(backend/app/schemas/cell_product.py)

  • CellProductCreate: 新增 passage、freeze_date、expected_cell_count、viability(均 Optional)
  • CellProductUpdate: 同上 + product_status(可选,校验只能从 frozen→sold/used)
  • CellProductListQuery: 保持不变

6.3 CRUD(backend/app/crud/cell_product.py)

  • _row_to_dict: 新增 4 个字段的映射
  • create / update: 新增字段处理
  • 新增 get_next_code 方法:查询当天最大编码 +1

6.4 API(backend/app/api/production.py)

  • 新增 GET /web/admin/cell-products/next-code 端点
  • create 端点:新增字段写入
  • update 端点:状态变更校验(只允许 frozen→sold/used)

7. 涉及文件清单

层级 文件 改动类型
SQL docs/sql/ 新增迁移文件 ALTER TABLE
Model backend/app/models/models.py BizCellProduct 类 新增 4 个 Column + 更新默认值
Schema backend/app/schemas/cell_product.py 新增字段 + 状态校验
CRUD backend/app/crud/cell_product.py 字段映射 + next-code 方法
API backend/app/api/production.py 新增 next-code 端点 + 状态校验
前端页面 web-admin/src/views/production/cell-product/index.vue 全面重写(表格+表单+查看弹窗)
前端API web-admin/src/api/cell-product.ts 新增 next-code 接口

8. 约定遵循

  • UI 规范: docs/web-admin-ui-spec-fresh-mint.md(Fresh Mint 调色板)
  • 状态 Tag 颜色: success=已冻存, warning=已售卖, info=已使用
  • 弹窗表单: label-position="top", 2列网格, .dialog-form-layout
  • 产品图片上传: 参考采集协议单附件上传卡片化布局
  • 公共字段: 遵循 database-conventions(id → 业务字段 → tenant_no ~ del_flag)
  • 编码生成: CPYYYYMMDD + 6位序号左补零