1212 * @ai -context: 反查已挂(list_links_by_target)、切换目标先撤旧链(幂等防堆
1313 * 积)、REQ-276 右缘钳制浮层均保持既有语义。
1414 */
15- import { useCallback , useEffect , useMemo , useState } from "react" ;
15+ import { useCallback , useEffect , useMemo , useRef , useState } from "react" ;
1616import { invoke } from "@tauri-apps/api/core" ;
1717import type {
1818 KnowledgeConcept , KnowledgeLink , KnowledgeModel , KnowledgeNode , KnowledgeSystem ,
@@ -108,7 +108,12 @@ export default function NoteLinkToSystem({ noteId, onChanged }: Props) {
108108 setNodes ( ns ) ; setConcepts ( cs ) ; setModels ( ms ) ;
109109 } , [ ] ) ;
110110
111+ // 审查 D4:体系切换代际守卫——轻建在途(await 列表重载)期间若用户切换
112+ // 体系,旧代结果不得覆盖新体系选择/列表
113+ const entityGenRef = useRef ( 0 ) ;
114+
111115 useEffect ( ( ) => {
116+ entityGenRef . current += 1 ;
112117 setEntityId ( null ) ;
113118 void loadEntities ( effectiveSystemId ) ;
114119 } , [ effectiveSystemId , loadEntities ] ) ;
@@ -164,6 +169,7 @@ export default function NoteLinkToSystem({ noteId, onChanged }: Props) {
164169 // 留空,详情回体系页既有对话框补全;模型学科占位「未分类」可后改)
165170 const createEntity = useCallback ( async ( name : string , anchorId : number | null ) => {
166171 if ( effectiveSystemId == null ) throw new Error ( "请先选择体系" ) ;
172+ const gen = entityGenRef . current ;
167173 let id : number ;
168174 if ( entityType === "node" ) {
169175 const n = await invoke < KnowledgeNode > ( "add_knowledge_node" , {
@@ -176,14 +182,19 @@ export default function NoteLinkToSystem({ noteId, onChanged }: Props) {
176182 } ) ;
177183 id = c . id ;
178184 } else {
185+ // 审查 D1:Rust 契约 disciplines:String=JSON 数组字符串(normalize_disciplines
186+ // 只认 JSON 数组)——裸串必拒;同 KnowledgeSampleView JSON.stringify 范式
179187 const m = await invoke < KnowledgeModel > ( "add_knowledge_model" , {
180- systemId : effectiveSystemId , name, disciplines : "未分类" ,
188+ systemId : effectiveSystemId , name, disciplines : JSON . stringify ( [ "未分类" ] ) ,
181189 claim : null , validWhen : null , invalidWhen : null ,
182190 } ) ;
183191 id = m . id ;
184192 }
185193 await loadEntities ( effectiveSystemId ) ; // 列表重载(新增即见)
186- setEntityId ( id ) ; // 即建即选——确认挂接一步收尾
194+ // 审查 D4:代际一致才回填选择(期间切体系则丢弃本次回填)
195+ if ( entityGenRef . current === gen ) {
196+ setEntityId ( id ) ; // 即建即选——确认挂接一步收尾
197+ }
187198 } , [ effectiveSystemId , entityType , loadEntities ] ) ;
188199
189200 const nodeRows = useMemo ( ( ) => flattenNodeRows ( nodes ) , [ nodes ] ) ;
0 commit comments