fix:开发完毕

This commit is contained in:
彭帅
2026-05-28 17:25:32 +08:00
parent 50879a71da
commit c5d4d7a7e1
63 changed files with 4960 additions and 851 deletions

View File

@@ -1,112 +1,7 @@
"use client";
import { useCallback, useMemo } from "react";
import { Share2 } from "lucide-react";
import { BrapiEntityPage, type BrapiFormField } from "@/components/brapi/BrapiEntityPage";
import {
createPedigreeRow,
fetchPedigreeDetail,
fetchPedigreeRows,
normalizePedigreeForm,
updatePedigreeRow,
} from "../api";
import { useCrossPedigree } from "../CrossPedigreeContext";
import { NONE_SELECT_VALUE } from "../types";
import { PedigreeNodeFormPanel } from "./PedigreeNodeFormPanel";
export function PedigreeNodeTab() {
const { snapshot } = useCrossPedigree();
const germplasmOptions = snapshot?.germplasm ?? [];
const crossingProjectOptions = snapshot?.crossingProjectOptions ?? [];
const loadRows = useCallback(async () => {
const rows = await fetchPedigreeRows();
const projectNameById = new Map(
(snapshot?.crossingProjects ?? []).map((project) => [project.id, project.name || project.id]),
);
return rows.map((row) => ({
...row,
crossing_project_name:
row.crossing_project_name || (row.crossing_project_id ? projectNameById.get(row.crossing_project_id) : null),
})) as unknown as Record<string, unknown>[];
}, [snapshot?.crossingProjects]);
const fetchRecord = useCallback(async (id: string) => {
const detail = await fetchPedigreeDetail(id);
return normalizePedigreeForm(detail);
}, []);
const fields = useMemo<BrapiFormField[]>(() => [
{
key: "germplasm_id",
label: "Germplasm 材料",
type: "select",
required: true,
options: [{ value: NONE_SELECT_VALUE, label: "请选择 Germplasm" }, ...germplasmOptions],
},
{
key: "crossing_project_id",
label: "CrossingProject 杂交项目",
type: "select",
options: [{ value: NONE_SELECT_VALUE, label: "不指定杂交项目" }, ...crossingProjectOptions],
},
{
key: "crossing_year",
label: "crossing_year 杂交年份",
type: "year",
placeholder: "四位年份",
},
{
key: "family_code",
label: "family_code 家系编号",
type: "text",
placeholder: "同一 crossing_project 下建议唯一",
},
{
key: "pedigree_string",
label: "pedigree_string 系谱字符串",
type: "text",
placeholder: "如 A/B//C支持 Purdy notation",
colSpan: 2,
},
], [crossingProjectOptions, germplasmOptions]);
return (
<BrapiEntityPage
icon={Share2}
iconBg="bg-gradient-to-br from-sky-500 to-blue-600"
title="Pedigree Node 系谱节点"
description="pedigree_node系谱树中的节点通常对应一个 germplasm。BrAPI 以 germplasmDbId 作为更新主键。"
addLabel="新增系谱节点"
useEnhancedDialog
fetchRecord={fetchRecord}
columns={[
{ key: "germplasm_name", label: "材料" },
{ key: "germplasm_id", label: "Germplasm ID" },
{ key: "crossing_project_name", label: "杂交项目" },
{ key: "crossing_year", label: "杂交年份" },
{ key: "family_code", label: "家系编号" },
{
key: "pedigree_string",
label: "系谱字符串",
render: (value) => {
const text = String(value ?? "").trim();
if (!text) return "—";
return text.length > 40 ? `${text.slice(0, 40)}` : text;
},
},
]}
fields={fields}
data={[]}
stats={[
{
label: "/brapi/v2/pedigree",
value: "BrAPI",
className: "bg-sky-50 text-sky-700 dark:bg-sky-400/10 dark:text-sky-200",
},
]}
loadData={loadRows}
createRecord={(payload) => createPedigreeRow(payload) as unknown as Promise<Record<string, unknown>>}
updateRecord={(id, payload) => updatePedigreeRow(id, payload) as unknown as Promise<Record<string, unknown>>}
/>
);
return <PedigreeNodeFormPanel />;
}