# 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`。 - 普通用户不要直接编辑 amount;amount 应通过入库、出库、转移、分装等交易动作更新。 - 支持库存状态:充足、低库存、耗尽,可由 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 | 必须先选择 crop;breeding_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 不允许物理删除。