对象类创建(ItemType 实例)调研与统一方案

对象类创建(ItemType 实例)调研与统一方案

时间:2026-07-09 18:38+

背景:用户要求 (1) 清理 unified-create 预检钩子改正确调用 (2) 统一 create 接口约定 (3) Part 的 hc_copied_from 预创建失败直接跳过 (4) 先调研 ItemTypeManagement.vue 对象类创建现状,再谈和普通对象创建统一。

前三项已完成并验证;本文聚焦第 4 项调研结论。

一、三项修复落地(已完成)

  1. 预检钩子改正确调用
  • unified-create.jsENABLE_RULE_PRECHECK 钩子,原来调用 rule-engine.createItem(死路:本地 sciot_sequences 空表,编号永远失败)。
  • 改为调用 relationship-resolver.resolveExistence(itemType, properties)--真实 SCSAI 去重,且已具备按类型选 name/title + 命中值校验(杜绝误判)。exact_match 时返回 409 阻断,默认关闭不破坏现有行为。
  1. create 接口约定统一
  • CapabilityRuntime.create(context, options) 现归一化支持三种形式:
  • { item_type, data, relationships, item_properties }(旧约定)
  • { itemType, properties, relationships, itemProperties }(与 unified-create 一致)
  • 位置式 create(itemType, properties, relationships, itemProperties, options)
  • capability-pipeline.createObject 改为委托 CapabilityRuntime.create(new 实例),保留 SCSAI 不可用时写 local_objects 兜底。
  • 验证:三种形式 + ECN 创建全部 success。
  1. Part 的 hc_copied_from 预创建失败 → 跳过
  • unified-create.js 预创建 item_property 失败时仅 warning 跳过(非必填属性),符合"直接跳过"要求,未做额外处理。

二、ItemTypeManagement.vue 对象类创建现状调研

2.1 它是怎么做的

  • 文件:src/views/ItemTypeManagement.vue(99KB)。
  • 创建入口:createItemTypeInSCSAI()(L1301)。
  • 流程:
  1. 查重:用 rawQuery 查 SCSAI 是否已存在同名 ItemType()。
  2. 关联对象类 ID 预查:对 def.relationships 里的 related_item_type 逐个查 ItemType id,存 relatedIds
  3. 构建 relationships 数组,含两类关系:
  • relationship_type: 'Property' → 内联 related_items(每个属性 name/label/data_type/is_required/stored_length/default_value);
  • relationship_type: 'RelationshipType' → 内联 related_items(name/label + item_properties.related_id 引用关联 ItemType)。
  1. 调用 createViaUseCreate({ itemType:'ItemType', properties:{name,label,description}, relationships, options:{skipDedup:true, skipAiCorrect:true} })
  • createViaUseCreate 来自 useCreate.js(L966 import,L1060 实例化)--即老的、前端直连 SCSAI 的 composable

2.2 能不能创建成功?

  • 能。 useCreate.jscreate()(L750)是成熟的客户端创建器,走 bomService._SCSAIApiRequest('ApplyItem', aml) 直连 SCSAI。
  • 它对 Property / RelationshipType 这类自引用系统关系类型有专门处理(L586 skipPrecreateRelTypes = ['Property','RelationshipType'],不独立预建、内联到父子 ItemType 的 AML 中)。
  • createRelationshipsRecursive(L492)正确把 Property/RelationshipType 作为 ItemType 的关系项内联提交。
  • 结论:对象类(ItemType 定义,含属性列表 + 关系类型)可成功创建到 SCSAI

2.3 能不能创建一个类似 Part 这样的"复杂对象类"?

  • 这里要区分两层含义:
  • (A) 创建一个"复杂对象类的定义"(即新建一个叫 MyComplexPart 的 ItemType,它有 20 个 Property + 多个 RelationshipType):✅ 能,因为 ItemTypeManagement 的 createItemTypeInSCSAI 就是干这个的。
  • (B) 创建一个"Part 实例"(业务数据):❌ 这不是 ItemTypeManagement 的职责,它建的是"类"不是"实例"。Part 实例创建走的是统一 unified-create.js(后端 7 步),已验证可建。
  • 所以"类似 Part 的复杂对象类"指 (A) 时答案是能;全流程依赖 useCreate 的嵌套关系能力,实测路径完整。

⚠️ 订正(2026-07-09 19:24 用户指正):下方 2.4 原表与“两者关系处理逻辑根本不同”的结论是概念错误,已作废。

实测证据见 inv_model(真实 SCSAI 探查):

  • SequenceItemTypeis_relationship=0,普通类),且有真实实例(acc_AccountPayable 等)→ SEQUENCE 就是普通对象类。
  • Property / RelationshipType 都是 ItemType,但 is_relationship=1(关系型);独立 add Propertysource item has to be specified只能作为关系内联,不能独立建。
  • Part 有 19 个关系类型,related 指向各种 ItemType(Part / Manufacturer Part / HC Validation…)。

正确模型(SCSAI 统一对象模型):万物皆 Item,Item 必属某个 ItemType;ItemType 自身只是 ItemType 这个 ItemType 的一个实例。Property/RelationshipType/Sequence/WBS/Part 无一例外都是 Item。

“对象类创建”与“普通对象创建”在模型层没有区别,都是“对某个 ItemType 做一次 add”。代码路径差异(useCreate 内联、unified-create 预建/编号)是被误当成模型差异的根源。

真正驱动差异的只有 per-ItemType 元数据,而非“类 vs 实例”:

  • is_relationship=1 → 该 Item 只能作为关系内联(Property/RelationshipType),不能独立 add;
  • 有 keyed 字段 → 需编号(Part/ECN/Document;ItemType 用 name 作标识、无 keyed);
  • 必填引用 → 预创建或内联;
  • Project→顶层 WBS 是 SCSAI Method 的个别业务约束,属“个别 ItemType 钩子”,非“类创建”专属机制。

故关系逻辑只有一套,差异由元数据驱动。 当前代码把 Property/RelationshipType 当“特殊类型硬编码内联”、unified-create 当“预创建失败才内联”——两条路径都未真正元数据驱动,这才是该统一的真问题(见第三节订正)。

三、统一的思路(订正版,待用户拍板再实现)

核心原则:入口唯一 + 行为由 per-ItemType 元数据驱动,不按“类/实例”分流。

既然 SCSAI 是统一对象模型,正确的统一不是“给 ItemType 开个特殊分支”,而是让唯一的 unified-create.js handleCreate(7步核心)对所有 ItemType 一视同仁,每一步的差异化都来自该 ItemType 的真实元数据:

  1. 编号:读 sciot_properties/SCSAI 元数据 的 keyed 字段 → 有则走 getNextItemNumber,无(如 ItemType 用 name 标识)则跳过。无需 itemType==='ItemType' 这类硬编码分支。
  2. 关系内联 vs 预创建:读 related ItemTypeis_relationship 标志(实测 Property/RelationshipType = 1)→ is_relationship=1 的 related Item 只能内联,绝不尝试独立预建;is_relationship=0(普通类如 Part)才走预创建/引用。当前 useCreate 把 Property/RelationshipType 当名字硬编码、unified-create 当“预建失败回退内联”——都应改为:统一查 is_relationship 元数据决定,名字硬编码是 bug 之源。
  3. 个别 ItemType 钩子:Project→顶层 WBS、ECN→title 标识等,作为 per-ItemType 的可插拔钩子(已在 resolver/编号器里按类型处理),不破坏统一流程。

推荐落地

  • unified-create.js 的关系处理改为:对每个 related_item_type 查其 is_relationship 元数据,决定内联/预建(取代现在的 ['Property','RelationshipType'] 名字硬编码)。前端 ItemTypeManagement.vue 改为调 /api/unified/create,传 { itemType:'ItemType', properties, relationships },由同一 7 步核心处理。
  • useCreate.js(前端老路径)的 is_relationship 判断逻辑抽成可直接复用的纯函数,后端统一调用,保证语义一致。
  • 收益:对象类创建也获得统一存在性预检、日志、兜底;彻底消除“类 vs 实例”两条代码路径的分裂。

注:上一版“在 unified-create 增加 ItemType 分支、跳过编号/预建”的写法仍隐含“按类型特判”,与统一模型相悖,已被本订正取代。

四、实施与验证(2026-07-09 19:50 起,已完成)

改动(server/routes/unified-create.js):

  1. 新增 isRelationshipItemType(typeName) 元数据驱动判定:先查本地 rule_engine.db.sciot_item_types.is_relationship,缺失时再 SCSAI 实时查 ItemTypeis_relationship(统一对象模型:ItemType 自身也是 Item),结果缓存。
  2. createRelationshipsRecursive 改为:对每个 related_item_type 先查 isRelationshipItemType=true(如 Property/RelationshipType)直接内联,跳过独立预创建;普通 ItemType 才走 precreateItem
  3. 删除原 ['Part','Document','CAD','ECR','ECN','ECO'] / 'Project'按类型名硬编码 keyed 字段回退——改用通用的 subProps 必填 keyed 补全逻辑。is_relationship 判断不再依赖 ['Property','RelationshipType'] 名字列表。

验证(真实 SCSAI):

  • ✅ 通过统一入口 handleCreate(null,null,{itemType:'ItemType',...}) 成功创建一个复杂对象类:含 3 个自定义 Property(field_a/field_b/field_c)+ 1 个 RelationshipType,无 source item required 报错(证明元数据驱动内联生效)。验证后已 delete 清理环境。
  • ✅ 回归 verify-capability-line.mjs:6 能力(create/repair/optimize/compare/generate/identify)全部 success。
  • ✅ 普通对象 Part 创建仍 success(统一入口未受影响)。

结论: 统一对象模型落地——handleCreate(7步核心)对所有 ItemType 一视同仁,关系行为完全由 per-ItemType 的 is_relationship 元数据驱动,不再按“类/实例”或类型名分流。

剩余迁移(待办,非阻塞):

  • 前端 src/views/ItemTypeManagement.vue(L966/L1060)仍直接 new useCreate(前端老路径)创建对象类;useCreate.js 内部对 Property/RelationshipType 仍是 ['Property','RelationshipType'] 名字硬编码(L586)。
  • 建议:让 ItemTypeManagement.vue 改调后端 /api/unified/create(同一 handleCreate),并同步把 useCreate.js 的硬编码改为复用 isRelationshipItemType 逻辑,彻底消除分裂。

四、待确认

  • 是否按"第三节推荐方案"实现 ItemType 分支统一?(需用户拍板后再动代码)
  • 实现后 useCreate.js 是否从 ItemTypeManagement 移除、还是仅新增后端入口并存?
  • 普通业务页(非对象类管理)是否也迁移到 unified-create(当前仍用 useCreate 老路径,存在嵌套 bug 路径风险)?
← 返回案例列表
分享:
🤖 Try Now →
🤖
🎁