Files
brapi-java/docs/requirements/02-germplasm-seed-entry-requirements.md
2026-05-28 11:56:17 +08:00

610 lines
43 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Germplasm / Seed 模块专业数据录入需求文档 V2
## 1. 文档目的
本文档用于指导 Germplasm / Seed 模块的前端页面、后端接口、字段校验、数据导入、测试验收设计。本文档不再只描述数据库表关系,而是从真实育种业务出发,解释每个字段的业务意义、录入方式、控件建议、校验规则和上下游影响。
## 2. 模块定位
Germplasm / Seed 模块描述育种材料的生命周期:
```text
材料身份 -> 材料属性 -> 杂交计划/实际杂交 -> 亲本 -> 系谱 -> 种子批次 -> 库存流转 -> 被 study / observation_unit 使用
```
核心概念如下:
| 概念 | 业务含义 | 主要表 |
| ---------------------------- | --------------------------------------------------------- | ------------------------------------------------------------ |
| Germplasm 材料身份 | 一个品种、品系、后代材料、种质资源的身份信息 | `germplasm` |
| Germplasm Attribute 材料属性 | 材料自身稳定特征,如抗性、熟期、籽粒硬度、基因/QTL 标记等 | `germplasm_attribute_definition``germplasm_attribute_value` |
| Cross 杂交动作 | 一次计划杂交或实际杂交,包含亲本、状态、项目归属 | `crossing_project``cross_entity``cross_parent` |
| Pedigree 系谱 | 材料之间的亲子、同胞、后代关系 | `pedigree_node``pedigree_edge` |
| SeedLot 种子批次 | 某个材料或杂交组合对应的一批实物种子,有数量、单位、库位 | `seed_lot``seed_lot_content_mixture` |
| Transaction 库存流转 | 入库、出库、转移、分装、合并、消耗等动作流水 | `seed_lot_transaction` |
## 3. 推荐业务流程
```text
1. 维护育种方法 breeding_method
2. 维护材料属性定义 germplasm_attribute_definition
3. 创建材料 germplasm
4. 给材料补充属性值 germplasm_attribute_value
5. 如涉及杂交,创建 crossing_project
6. 创建计划杂交 cross_entity(planned=true)
7. 给计划杂交录入亲本 cross_parent
8. 实际完成杂交后,创建实际杂交 cross_entity(planned=false, planned_cross_id=计划杂交)
9. 如产生后代材料,创建新的 germplasm并补充 pedigree_node / pedigree_edge
10. 如产生实物种子,创建 seed_lot
11. 在 seed_lot_content_mixture 中描述批次组成
12. 后续库存变化通过 seed_lot_transaction 记录
13. seed_lot / germplasm / cross_entity 后续可作为 observation_unit 的材料来源
```
## 4. 页面总体设计
### 4.1 Germplasm 材料详情页
```text
Germplasm 详情页
├─ 基本信息名称、默认显示名、PUI、accession、作物、育种方法
├─ 分类信息genus、species、subtaxa、country_of_origin_code
├─ 来源信息acquisition_date、seed_source、seed_source_description、collection
├─ 属性值germplasm_attribute_value
├─ 系谱pedigree_node / pedigree_edge 树图
├─ 作为亲本cross_parent
├─ 种子批次seed_lot_content_mixture -> seed_lot
└─ 下游使用observation_unit、reference_set、sample 追踪
```
### 4.2 SeedLot 库存详情页
```text
SeedLot 详情页
├─ 当前库存amount、units、location、storage_location
├─ 批次组成germplasm / cross / mixture_percentage
├─ 出入库操作:入库、出库、转移、分装、合并、消耗
├─ 流转流水seed_lot_transaction
└─ 下游使用:哪些 study / observation_unit 使用了该批种子
```
### 4.3 CrossingProject 杂交项目工作台
```text
CrossingProject 工作台
├─ 项目信息name、program、description
├─ 计划杂交cross_entity(planned=true)
├─ 实际杂交cross_entity(planned=false)
├─ 亲本cross_parent
├─ 后代材料germplasm / pedigree_node
└─ 产生种子批次seed_lot
```
---
# 5. 字段级专业录入需求
## 5.1 breeding_method 育种方法
### 业务说明
`breeding_method` 是育种方法字典,用来说明某个 germplasm 是通过什么方式形成的,例如杂交选育、回交、自交系选育、诱变、转基因、克隆选择等。它不是一次具体杂交动作,而是材料来源方法的分类。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| -------------- | -------------------------------------------- | -------------------------------- | --------- | -------------------------------- |
| `id` | 育种方法主键,系统内部唯一标识 | 新增时系统生成;导入时可允许指定 | 隐藏/只读 | 必填、唯一;编辑时不允许修改 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许前端手填 |
| `abbreviation` | 方法缩写,如 MB、BC、DH | 用户录入 | 文本框 | 可选;建议同一用户下唯一 |
| `description` | 方法解释,如“回交用于恢复目标基因” | 用户录入 | 多行文本 | 可选,限制长度 |
| `name` | 方法名称,如 Male Backcross、Doubled Haploid | 用户录入 | 文本框 | 必填;建议唯一;作为下拉展示名称 |
### 页面与交互
- 列表页展示:方法名称、缩写、描述、使用材料数量。
- 新增页为简单字典表单。
- 删除前检查是否被 `germplasm.breeding_method_id` 引用;已引用时不允许物理删除,只允许停用。
---
## 5.2 germplasm 种质 / 材料身份
### 业务说明
`germplasm` 是材料身份证,描述一个品种、品系、亲本、后代材料、遗传资源或研究材料“是谁”。它不表示库存数量,库存数量由 `seed_lot` 表达。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| ------------------------------------- | ------------------------------------------------------------ | -------------------------------------- | ----------------- | --------------------------------------------------------- |
| `id` | 种质主键,系统内部唯一标识 | 系统生成;导入可指定 | 隐藏/只读 | 必填、唯一;编辑不可随意修改 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `accession_number` | 材料在种质库/机构内的 accession 编号,如 PI 113869 | 用户录入或导入 | 文本框 | 可选;建议同一 crop / institution 下唯一 |
| `acquisition_date` | 材料进入本系统或本机构的获取日期 | 用户录入 | 日期选择器 | 可选;不得晚于当前日期太多,导入时允许缺月/缺日需统一规则 |
| `acquisition_source_code` | 获取来源编码,如采集、引进、交换、繁殖等 | 用户选择 | 下拉框 | 可选;值来自 BrAPI/MCPD 枚举或系统字典 |
| `biological_status_of_accession_code` | 材料生物状态,如野生、地方品种、育种材料、改良品种、突变体等 | 用户选择 | 下拉框 | 可选;使用受控枚举,不建议自由输入 |
| `collection` | 材料所属集合、群体、panel 或 collection | 用户录入/选择 | 文本框/选择器 | 可选;可用于分组筛选 |
| `country_of_origin_code` | 原产国或育成/选育国家代码 | 用户选择 | 国家代码选择器 | 可选;建议使用 ISO 3166-1 三字母代码 |
| `default_display_name` | 系统默认展示名,给下拉框、表格、详情标题使用 | 用户录入,可由 germplasm_name 自动带出 | 文本框 | 与 `germplasm_name` 至少填一个;建议必填 |
| `documentationurl` | 材料说明文档、外部数据库页面或 DOI 链接 | 用户录入 | URL 输入框 | 可选;校验 URL 格式 |
| `genus` | 属名,如 Oryza、Triticum | 用户录入/字典选择 | 文本框/物种选择器 | 可选;建议首字母大写 |
| `germplasm_name` | 材料名称,可以是品种名、品系名、后代编号 | 用户录入 | 文本框 | 与 `default_display_name` 至少填一个;不强制全局唯一 |
| `germplasmpui` | 永久唯一标识,通常是 DOI、URI 或全局唯一编码 | 用户录入/外部导入 | 文本框/URL 输入框 | 可选;若填写必须唯一;建议用于跨系统交换 |
| `germplasm_preprocessing` | 材料用于试验前的统一处理说明,如消毒、催芽、低温处理 | 用户录入 | 文本框/多行文本 | 可选 |
| `mls_status` | 多边系统 MLS 状态,涉及植物遗传资源交换协议 | 用户选择 | 下拉框 | 可选;普通业务可隐藏到高级信息 |
| `seed_source` | 材料来源标识,如来源机构+accession或亲本组合描述 | 用户录入 | 文本框 | 可选;注意它不是库存批次,不等于 seed_lot |
| `seed_source_description` | 材料来源详细说明 | 用户录入 | 多行文本 | 可选 |
| `species` | 种名,如 sativa、aestivum | 用户录入/物种字典 | 文本框 | 可选;建议小写 |
| `species_authority` | 种名命名权威,如 L. | 用户录入 | 文本框 | 可选 |
| `subtaxa` | 亚种、变种、品种群、line 等更细分类 | 用户录入 | 文本框 | 可选 |
| `subtaxa_authority` | 亚种/变种命名权威 | 用户录入 | 文本框 | 可选 |
| `breeding_method_id` | 该材料形成所使用的育种方法 | 从 breeding_method 选择 | 搜索选择器 | 可选;必须引用存在的 breeding_method |
| `crop_id` | 所属作物 | 从 crop 选择 | 作物选择器 | 必填;后续 trial/study/attribute 应尽量同 crop |
### 录入建议
- 新建材料时,第一屏只放核心字段:`crop_id``germplasm_name``default_display_name``germplasmpui``accession_number``breeding_method_id`
- 分类与来源信息放在“高级信息”或“来源信息”分组。
- `germplasmpui``accession_number``germplasm_name` 三者不要混为一谈:
- `germplasm_name` 是人看的名字;
- `accession_number` 是机构内编号;
- `germplasmpui` 是跨系统长期唯一标识。
### 验收标准
1. 新增 germplasm 时,必须选择 crop。
2. `germplasm_name``default_display_name` 至少填写一个。
3. 下拉选择材料时展示 `default_display_name`,辅助展示 accession number / PUI。
4. 如果 germplasm 已被 seed lot、cross parent、observation unit 引用,不允许物理删除。
---
## 5.3 germplasm_attribute_definition 属性定义
### 业务说明
属性定义描述“材料可以有哪些稳定属性”。这些属性通常不是环境依赖的田间观测值,而是材料自身特征,例如籽粒颜色、抗病基因、硬度、熟期类型、特定 QTL、分子标记结果等。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| ---------------------- | ------------------------------------------------------------ | ---------------------------- | ----------------- | ------------------------------------- |
| `id` | 属性定义主键 | 系统生成 | 隐藏/只读 | 必填、唯一 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `default_value` | 属性默认值 | 用户录入 | 动态输入框 | 可选;按 datatype / scale 校验 |
| `documentationurl` | 属性说明文档链接 | 用户录入 | URL 输入框 | 可选;校验 URL |
| `growth_stage` | 属性适用生长阶段,如 flowering | 用户录入/选择 | 下拉框/文本框 | 可选 |
| `institution` | 提交或维护该属性定义的机构 | 用户录入 | 文本框 | 可选 |
| `language` | 定义语言,如 zh、en | 用户选择 | 下拉框 | 可选;建议 ISO 639-1 |
| `scientist` | 提交该属性定义的科学家或负责人 | 用户录入/人员选择 | 文本框/人员选择器 | 可选 |
| `status` | 属性状态,如 recommended、obsolete、legacy | 用户选择 | 下拉框 | 可选;推荐使用枚举 |
| `submission_timestamp` | 属性定义提交时间 | 系统默认当前时间,可手动调整 | 日期时间选择器 | 可选;新增默认当前时间 |
| `crop_id` | 适用作物 | 从 crop 选择 | 作物选择器 | 可选;若填写,下游材料应同 crop |
| `method_id` | 属性测定方法 | 从 method 选择 | 方法选择器 | 可选;若填写,属性值录入按该方法解释 |
| `ontology_id` | 所属本体 | 从 ontology 选择 | 本体选择器 | 可选 |
| `scale_id` | 值标尺/单位/有效值范围 | 从 scale 选择 | 标尺选择器 | 可选;若填写,属性值必须按 scale 校验 |
| `trait_id` | 关联性状 | 从 trait 选择 | 性状选择器 | 可选 |
| `attribute_category` | 属性分类,如 Morphological、Genetic、Quality | 用户选择/录入 | 下拉框/文本框 | 可选;建议字典化 |
| `code` | 属性代码,便于导入导出 | 用户录入 | 文本框 | 可选;建议唯一 |
| `datatype` | 属性值数据类型,如 text、numeric、date、boolean、categorical | 用户选择 | 下拉框 | 必填 |
| `description` | 属性解释 | 用户录入 | 多行文本 | 可选 |
| `name` | 属性名称 | 用户录入 | 文本框 | 必填;作为属性选择器展示名称 |
| `pui` | 属性永久标识 | 用户录入 | 文本框/URL 输入框 | 可选;建议唯一 |
| `uri` | 属性 URI | 用户录入 | URL 输入框 | 可选;校验 URL |
### 录入建议
- 属性定义页面本质是“属性字典配置”。
- 前端应根据 `datatype` 动态决定属性值录入控件:
- numeric数字输入框
- categorical下拉框
- date日期选择器
- boolean开关
- text文本框。
- 若绑定了 `scale_id`,则优先按 scale 的单位、上下限、有效分类值校验。
---
## 5.4 germplasm_attribute_value 属性值
### 业务说明
属性值是“某个 germplasm 在某个属性上的实际取值”。它不是属性定义,也不是 observation。它适合记录材料相对稳定、不强依赖环境的特征。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| ----------------- | ------------------------------ | -------------------------------------- | ---------- | ---------------------------------------- |
| `id` | 属性值主键 | 系统生成 | 隐藏/只读 | 必填、唯一 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `determined_date` | 属性值被测定或确认的日期 | 用户录入 | 日期选择器 | 可选;多次测定时必须填写以区分记录 |
| `value` | 某个材料在某个属性上的实际取值 | 用户录入 | 动态控件 | 必填;按 attribute datatype / scale 校验 |
| `attribute_id` | 属性定义 | 从 germplasm_attribute_definition 选择 | 属性选择器 | 必选;必须存在 |
| `germplasm_id` | 所属材料 | 从 germplasm 选择 | 材料选择器 | 必选;必须存在 |
### 录入建议
- 推荐嵌入 Germplasm 详情页的“属性值”Tab。
- 支持批量导入,模板列建议为:`germplasm_id/germplasm_name``attribute_code/attribute_name``value``determined_date`
- 同一个 germplasm + attribute 可以允许多次测定,但页面必须显示测定日期、来源和最新值标记。
---
## 5.5 crossing_project 杂交项目
### 业务说明
`crossing_project` 是某个育种项目下的一组杂交任务集合。它不是一次杂交而是一个杂交工作台例如“2026 抗倒伏杂交项目”。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| -------------- | ------------------ | ------------------ | ---------- | ----------------------------- |
| `id` | 杂交项目主键 | 系统生成 | 隐藏/只读 | 必填、唯一 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `description` | 杂交项目说明 | 用户录入 | 多行文本 | 可选 |
| `name` | 杂交项目名称 | 用户录入 | 文本框 | 必填;同一 program 下建议唯一 |
| `program_id` | 所属育种项目 | 从 program 选择 | 项目选择器 | 必选;必须存在 |
### 页面与交互
- 详情页应展示计划杂交、实际杂交、潜在亲本、后代材料、产生的 seed lot。
- 创建 cross 时应自动带入 crossing_project_id。
---
## 5.6 cross_entity 计划杂交 / 实际杂交
### 业务说明
`cross_entity` 统一承载计划杂交和实际杂交。通过 `planned` 字段区分计划与实际,通过 `planned_cross_id` 指向来源计划。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| --------------------- | ------------------------------------------- | ------------------------ | -------------- | --------------------------------------- |
| `id` | cross 主键 | 系统生成 | 隐藏/只读 | 必填、唯一 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `cross_type` | 杂交类型,如 biparental、self、backcross 等 | 用户选择 | 下拉框 | 可选;值来自枚举字典 |
| `name` | cross 名称,如 A × B、A/B、Cross-2026-001 | 用户录入或自动生成 | 文本框 | 必填;同一 crossing project 下建议唯一 |
| `planned` | 是否为计划杂交 | 页面根据入口自动设置 | 开关/分段控件 | 必填;计划杂交为 true实际杂交为 false |
| `status` | 状态,如 TODO、DONE、SKIPPED、FAILED | 用户选择/系统更新 | 下拉框 | 可选;计划杂交常用 TODO/DONE/SKIPPED |
| `crossing_project_id` | 所属杂交项目 | 从 crossing_project 选择 | 杂交项目选择器 | 必选 |
| `planned_cross_id` | 实际杂交来源的计划杂交 | 从 cross_entity 选择 | Cross 选择器 | 可选;不能选择自己;实际杂交建议填写 |
### 录入建议
- 页面上分成“计划杂交”和“实际杂交”两个入口,但后端都保存到 `cross_entity`
- 创建计划杂交时:`planned=true``planned_cross_id=null`
- 完成实际杂交时:`planned=false``planned_cross_id=原计划杂交 id`
- 亲本不要直接塞在 cross 主表字段中,应通过 `cross_parent` 维护,便于支持多亲本和 observation_unit 亲本来源。
---
## 5.7 cross_parent 杂交亲本
### 业务说明
`cross_parent` 表示某个 cross 的亲本。亲本可以来自 `germplasm`,也可以来自某个 `observation_unit`,例如田间某一株实际被选作父本/母本。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| --------------------- | --------------------------------------------------- | ---------------------------------- | ----------------- | ------------------------------------- |
| `id` | 亲本记录主键 | 系统生成 | 隐藏/只读 | 必填、唯一 |
| `parent_type` | 亲本角色,如 MALE、FEMALE、SELF、POPULATION、CLONAL | 用户选择 | 下拉框 | 必填;使用枚举 |
| `cross_id` | 所属 cross | 从 cross_entity 选择或由详情页带入 | Cross 选择器/隐藏 | 必选 |
| `crossing_project_id` | 所属 crossing project | 由 cross 自动带出 | 只读/隐藏 | 可选;如填写必须与 cross 一致 |
| `germplasm_id` | 亲本材料 | 从 germplasm 选择 | 材料选择器 | 与 `observation_unit_id` 至少一个必填 |
| `observation_unit_id` | 亲本观测单元 | 从 observation_unit 选择 | 观测单元选择器 | 与 `germplasm_id` 至少一个必填 |
### 录入建议
- 在 Cross 详情页内嵌“亲本列表”。
- 常见快捷录入Parent1 / Parent2。
- 对于田间选株杂交,优先记录 observation_unit_id同时可带出 germplasm_id保证可追溯到具体植株。
---
## 5.8 pedigree_node 系谱节点
### 业务说明
`pedigree_node` 是系谱图中的节点,通常对应一个 germplasm。它用于描述材料在系谱树中的位置不等同于一次杂交记录。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| --------------------- | --------------------- | ------------------------ | -------------- | ----------------------------------------- |
| `id` | 系谱节点主键 | 系统生成 | 隐藏/只读 | 必填、唯一 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `crossing_year` | 亲本最初杂交年份 | 用户录入 | 年份选择器 | 可选;四位年份 |
| `family_code` | 家系编号 | 用户录入 | 文本框 | 可选;同一 crossing_project 下建议唯一 |
| `pedigree_string` | 系谱字符串,如 A/B//C | 用户录入/系统生成 | 文本框 | 可选;建议支持 Purdy notation |
| `crossing_project_id` | 产生该节点的杂交项目 | 从 crossing_project 选择 | 杂交项目选择器 | 可选 |
| `germplasm_id` | 该系谱节点对应的材料 | 从 germplasm 选择 | 材料选择器 | 建议必填;同一 germplasm 不建议重复建节点 |
### 录入建议
- Germplasm 详情页提供“系谱”Tab。
- 支持两种维护方式:树图拖拽维护、表格维护节点和边。
- 如果 cross 完成后产生后代 germplasm应自动或半自动创建 pedigree_node。
---
## 5.9 pedigree_edge 系谱边
### 业务说明
`pedigree_edge` 是系谱图中的边,描述节点之间的父子、同胞等关系。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| ------------------- | ------------------------------------------ | --------------------- | ---------- | ------------------------------------ |
| `id` | 系谱边主键 | 系统生成 | 隐藏/只读 | 必填、唯一 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `edge_type` | 边类型,如 parent、child、sibling | 用户选择 | 下拉框 | 必填 |
| `parent_type` | 如果是亲本关系,标识 MALE、FEMALE、SELF 等 | 用户选择 | 下拉框 | 可选;当 edge_type=parent 时建议必填 |
| `connceted_node_id` | 被连接节点 | 从 pedigree_node 选择 | 节点选择器 | 必选 |
| `this_node_id` | 当前节点 | 从 pedigree_node 选择 | 节点选择器 | 必选;不能等于 connected node |
### 录入建议
- 前端展示时不要暴露“this_node_id / connected_node_id”这种技术词应该显示为“当前材料”和“关联材料”。
- 添加父本/母本时,系统自动创建 edge_type=parent。
- 需要避免明显循环,例如 A 是 B 的父本,同时 B 又是 A 的父本。
---
## 5.10 seed_lot 种子批次
### 业务说明
`seed_lot` 是实物库存批次,描述某一批种子当前有多少、放在哪里、属于哪个项目。它不是 germplasm 身份;同一个 germplasm 可以有多个 seed_lot。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| ------------------- | ---------------------------------------------------- | --------------------- | ------------------- | ----------------------------- |
| `id` | SeedLot 主键 | 系统生成 | 隐藏/只读 | 必填、唯一 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `amount` | 当前库存数量,可以是粒数、重量、株数等 | 用户录入/交易自动更新 | 数字输入框 | 必填;非负;交易后自动更新 |
| `created_date` | 批次创建时间 | 系统默认,可导入 | 日期时间选择器/只读 | 默认当前时间 |
| `description` | 批次说明 | 用户录入 | 多行文本 | 可选 |
| `last_updated` | 最后更新时间,包含交易变化 | 系统自动更新 | 只读 | 不允许手动改 |
| `name` | 批次名称,如 华占-2026-荆门-扩繁批 | 用户录入或自动生成 | 文本框 | 必填;同一 program 下建议唯一 |
| `source_collection` | 原始来源 collection如野外采集、nursery、种质库集合 | 用户录入 | 文本框 | 可选 |
| `storage_location` | 具体库位描述,如 冰箱A-2层-盒03 | 用户录入 | 文本框 | 可选 |
| `units` | 数量单位,如 seeds、g、kg、plants | 用户选择 | 下拉框/文本框 | 必填;交易单位需一致或可换算 |
| `location_id` | 库存所在地点 | 从 location 选择 | 地点选择器 | 可选 |
| `program_id` | 所属项目 | 从 program 选择 | 项目选择器 | 可选;用于项目库存筛选 |
### 录入建议
- 创建 seed_lot 后必须进入“批次组成”Tab至少录入一条 `seed_lot_content_mixture`
- 普通用户不要直接编辑 amountamount 应通过入库、出库、转移、分装等交易动作更新。
- 支持库存状态:充足、低库存、耗尽,可由 amount 和阈值计算。
---
## 5.11 seed_lot_content_mixture 批次组成
### 业务说明
`seed_lot_content_mixture` 描述一个 seed_lot 由哪些材料或 cross 组成。单一材料批次也需要有一条组成记录,比例为 100%。混合批次则多条记录占比合计为 100%。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| -------------------- | ----------------------------- | -------------------- | ------------------- | ---------------------------------------- |
| `id` | 批次组成主键 | 系统生成 | 隐藏/只读 | 必填、唯一 |
| `mixture_percentage` | 该材料或 cross 在批次中的占比 | 用户录入 | 百分比输入框 | 0 到 100同一 seed lot 总和建议等于 100 |
| `cross_id` | 来源 cross | 从 cross_entity 选择 | Cross 选择器 | 与 `germplasm_id` 至少一个必填 |
| `germplasm_id` | 来源 germplasm | 从 germplasm 选择 | 材料选择器 | 与 `cross_id` 至少一个必填 |
| `seed_lot_id` | 所属 seed lot | 由详情页带入或选择 | SeedLot 选择器/隐藏 | 必选 |
### 录入建议
- 新建 seed_lot 时,如果用户选择了单个 germplasm系统自动生成一条 mixture`germplasm_id=所选材料``mixture_percentage=100`
- 如果来源是某次杂交产生的种子,优先填写 `cross_id`
- 如果既能追溯 cross 又能追溯 germplasm可按系统设计决定是否允许同时填写若允许同时展示“来源杂交”和“当前材料身份”。
---
## 5.12 seed_lot_transaction 批次流转
### 业务说明
`seed_lot_transaction` 记录库存变化。它不应该由用户像普通表单一样手动维护,而应该由“入库、出库、转移、分装、合并、消耗”等业务动作自动生成。
### 字段说明
| 字段 | 业务意义 | 录入方式 | 控件建议 | 校验规则 |
| ------------------ | -------------------------------------------- | ----------------------- | ------------------- | ------------------------------------------------- |
| `id` | 流转记录主键 | 系统生成 | 隐藏/只读 | 必填、唯一 |
| `auth_user_id` | 数据所属用户或租户 | 登录上下文自动写入 | 隐藏 | 不允许手填 |
| `amount` | 流转数量 | 用户在业务动作中录入 | 数字输入框 | 必填;大于 0 |
| `description` | 流转说明,如用于某 study、分装原因、报废原因 | 用户录入 | 多行文本 | 可选;出库/报废建议必填 |
| `timestamp` | 流转发生时间 | 默认当前时间,可调整 | 日期时间选择器 | 必填 |
| `units` | 流转单位 | 默认继承 seed_lot.units | 下拉框/只读 | 必填;需与 seed_lot 单位一致或有换算关系 |
| `from_seed_lot_id` | 来源批次 | 按动作自动设置 | SeedLot 选择器/隐藏 | 与 `to_seed_lot_id` 至少一个存在 |
| `to_seed_lot_id` | 目标批次 | 按动作自动设置 | SeedLot 选择器/隐藏 | 与 `from_seed_lot_id` 至少一个存在;不能等于 from |
### 业务动作映射
| 动作 | from_seed_lot_id | to_seed_lot_id | amount 对库存影响 |
| --------- | ---------------- | -------------- | -------------------------------------------- |
| 入库 | 空 | 目标批次 | 目标批次增加 |
| 出库 | 来源批次 | 空 | 来源批次减少 |
| 转移 | 来源批次 | 目标批次 | 来源减少,目标增加 |
| 分装 | 原批次 | 新批次 | 原批次减少,新批次增加 |
| 合并 | 多个来源批次 | 目标批次 | 来源减少,目标增加;可能生成多条 transaction |
| 消耗/报废 | 来源批次 | 空 | 来源减少,并记录原因 |
### 验收标准
1. amount 必须大于 0。
2. 出库/消耗时amount 不得超过来源批次当前库存。
3. from 和 to 不能相同。
4. transaction 创建后应自动更新 seed_lot.amount 和 last_updated。
5. 已生成的 transaction 原则上不允许随意修改;如需纠错,应通过反向交易或更正记录处理。
---
# 6. 跨表联动与关键校验
## 6.1 选择器联动
| 场景 | 联动规则 |
| ------------------------- | ------------------------------------------------------------ |
| 创建 germplasm | 必须先选择 cropbreeding_method 可选 |
| 创建 attribute definition | crop 可选;若选择 trait/method/scale/ontology则必须引用存在记录 |
| 创建 attribute value | 选择 germplasm 后attribute 选择器优先展示同 crop 或未限定 crop 的属性 |
| 创建 crossing project | 必须选择 program |
| 创建 cross | 必须先选择 crossing_project计划杂交和实际杂交使用不同入口 |
| 创建 cross parent | 从 cross 详情页进入时自动带出 cross 和 crossing_project |
| 创建 seed lot | 可选择 program、location保存后必须维护 content mixture |
| 创建 transaction | 从 seed lot 详情页进入时自动带出 from/to seed lot |
## 6.2 删除规则
| 对象 | 删除限制 |
| -------------------- | ------------------------------------------------------------ |
| breeding_method | 已被 germplasm 引用时不可删除 |
| germplasm | 已被 attribute value、cross parent、seed lot mixture、pedigree、observation unit 引用时不可删除 |
| attribute definition | 已有 attribute value 时不可删除 |
| crossing_project | 已有 cross / cross parent / pedigree node 时不可删除 |
| cross_entity | 已有 parent、seed lot mixture、observation unit 引用时不可删除 |
| seed_lot | 已有 mixture、transaction、observation unit 引用时不可删除 |
| transaction | 原则上不可物理删除;只能冲销或作废 |
## 6.3 批量导入要求
### Germplasm 导入
必需列建议:
```text
crop_id 或 crop_name
germplasm_name 或 default_display_name
```
强烈建议列:
```text
accession_number
germplasmpui
breeding_method_name
country_of_origin_code
genus
species
seed_source
```
### SeedLot 导入
必需列建议:
```text
seed_lot_name
amount
units
germplasm_id/germplasm_name 或 cross_id/cross_name
mixture_percentage
```
### Attribute Value 导入
必需列建议:
```text
germplasm_id 或 germplasm_name
attribute_id 或 attribute_name/code
value
```
可选列:
```text
determined_date
source
remark
```
导入必须先预校验,错误报告至少包含:行号、字段、错误原因、建议修复方式。
---
# 7. 后端接口建议
## 7.1 主数据接口
```text
GET /germplasm
POST /germplasm
GET /germplasm/{id}
PUT /germplasm/{id}
DELETE /germplasm/{id}
GET /breeding-methods
POST /breeding-methods
GET /germplasm-attributes
POST /germplasm-attributes
GET /germplasm/{id}/attribute-values
POST /germplasm/{id}/attribute-values
GET /crossing-projects
POST /crossing-projects
GET /crossing-projects/{id}/crosses
GET /crosses
POST /crosses
GET /crosses/{id}/parents
POST /crosses/{id}/parents
GET /seed-lots
POST /seed-lots
GET /seed-lots/{id}/mixtures
POST /seed-lots/{id}/mixtures
GET /seed-lots/{id}/transactions
POST /seed-lots/{id}/transactions
```
## 7.2 选择器接口
```text
GET /selectors/crops
GET /selectors/breeding-methods
GET /selectors/germplasm?cropId=&keyword=
GET /selectors/germplasm-attributes?cropId=&datatype=&keyword=
GET /selectors/crossing-projects?programId=&keyword=
GET /selectors/crosses?crossingProjectId=&planned=&keyword=
GET /selectors/seed-lots?programId=&locationId=&keyword=
GET /selectors/observation-units?studyId=&germplasmId=&keyword=
```
---
# 8. 测试验收清单
1. 创建 germplasm 时,未选择 crop 不允许保存。
2. `germplasm_name``default_display_name` 都为空时不允许保存。
3. `germplasmpui` 重复时提示唯一性冲突。
4. attribute value 的 value 必须按 attribute datatype / scale 校验。
5. 创建 cross 时必须选择 crossing project。
6. 实际杂交选择 planned_cross_id 时不能选择自身。
7. cross parent 必须选择 parent_type。
8. cross parent 的 germplasm_id 和 observation_unit_id 至少填写一个。
9. seed lot 的 amount 不允许小于 0。
10. seed lot 的 units 必填。
11. seed lot content mixture 的 percentage 必须在 0 到 100 之间。
12. 同一 seed lot 的 mixture_percentage 总和不为 100 时,保存前应提示或禁止保存,具体取决于业务配置。
13. 出库数量不能超过当前库存。
14. transaction 创建后自动更新 seed_lot.amount。
15. 已有关联下游数据的 germplasm、cross、seed_lot 不允许物理删除。