别再被“对象类创建”坑了:我们如何用一套逻辑搞定SCSAI所有对象

别再被“对象类创建”坑了:我们如何用一套逻辑搞定SCSAI所有对象

你是不是也遇到过这种情况?系统里明明有一套“创建对象”的通用流程,可偏偏对象类(ItemType)的创建走的是另一条路。前端同学写了两套代码,后端同学维护着两套逻辑,每次新加一个类型都要小心翼翼地判断“这个该走哪条路”。更让人头疼的是,有时候明明只是创建个简单的对象类定义,代码却莫名其妙报错,查半天发现是编号逻辑在捣乱。

这不是技术问题,这是架构问题。今天我们就把这个坑彻底填平。

一个看似简单的问题:对象类到底怎么建?

先说说背景。我们的统一创建流程(unified-create)已经跑得很成熟了,普通对象如Part、Document、ECN都能正常创建。但对象类(ItemType)的创建一直是个“异类”——它有自己的入口ItemTypeManagement.vue,有自己的创建函数createItemTypeInSCSAI,走的是另一套前端直连SCSAI的老路。

这就产生了一个很尴尬的局面:同样是创建,普通对象走7步统一流程(预检、编号、预创建、关系处理、提交、兜底、日志),对象类却绕过了所有这些,直接调用SCSAI的ApplyItem接口。那统一流程里的存在性预检、编号自动生成、失败兜底这些能力,对象类就享受不到了。

更让人困惑的是,很多人下意识觉得“对象类是特殊的,它和普通对象不一样”。但真相是:在SCSAI的统一对象模型里,万物皆Item,Item必属某个ItemType。ItemType自己也只是ItemType这个ItemType的一个实例。Property、RelationshipType、Sequence、Part——无一例外,都是Item。

所以,“对象类创建”和“普通对象创建”在模型层根本没有区别。

问题出在哪?两条代码路径的“分裂”

我们仔细扒了扒现状,发现问题出在两个地方:

路径一:对象类创建(ItemTypeManagement.vue)

  • 查重:自己写rawQuery查SCSAI - 预查关联对象类ID:逐个查 - 构建relationships数组:包含Property和RelationshipType - 调用老版
useCreate.js的create方法,直接发ApplyItem给SCSAI

路径二:普通对象创建(unified-create.js)

  • 7步核心流程:预检、编号、预创建、关系处理、提交、兜底、日志 - 关系处理里硬编码了
['Property','RelationshipType']作为“特殊类型”直接内联
  • 编号逻辑里又硬编码了
['Part','Document','CAD','ECR','ECN','ECO']作为“需要编号的类型”

看到问题了吗?两条路径各有一套对“特殊类型”的硬编码判断。今天加一个新类型,明天改一个旧逻辑,后天发现某个类型既需要编号又需要内联——代码越来越臃肿,维护越来越痛苦。

而且更致命的是,这两套硬编码判断的语义可能不一致。比如useCreate.js里Property和RelationshipType被当作“自引用系统关系类型”直接内联,而unified-create.js里它们被当作“预创建失败才内联”的类型。同一个类型,两种处理方式,迟早要出bug。

真正的解决方案:让元数据驱动一切

既然SCSAI是统一对象模型,那正确的统一方式就不是“给ItemType开个特殊分支”,而是让唯一的创建流程对所有ItemType一视同仁。每一步的差异化,都应该来自该ItemType的真实元数据,而不是代码里的硬编码。

具体来说,我们只需要做三件事:

1. 编号与否,看元数据

每个ItemType都有自己的属性定义。如果某个ItemType有keyed字段(需要自动编号),就走getNextItemNumber;如果没有(比如ItemType用name做标识),就直接跳过。不需要在代码里写if (itemType === 'Part')这样的判断。

2. 内联还是预创建,看is_relationship标志

在SCSAI里,每个ItemType都有个is_relationship字段。为1的(如Property、RelationshipType)只能作为关系内联,不能独立创建;为0的(普通类如Part)才走预创建流程。

我们只需要在创建关系时,查一下related_item_typeis_relationship值,就能决定是内联还是预建。不需要再维护['Property','RelationshipType']这样的硬编码列表。

3. 特殊业务逻辑,用可插拔钩子

有些ItemType确实有特殊的业务约束,比如Project需要创建顶层WBS,ECN需要用title做标识。这些应该作为per-ItemType的可插拔钩子,在统一流程的特定步骤里按类型触发,而不是破坏统一流程本身。

落地效果:一套代码,搞定所有

我们已经在unified-create.js里实现了这套方案:

  • 新增
isRelationshipItemType(typeName)函数,先查本地缓存,再查SCSAI实时数据,结果缓存起来避免重复查询
  • 关系处理逻辑改为:对每个
related_item_type先查is_relationship,为true的直接内联,为false的才尝试预创建
  • 删除了所有按类型名硬编码的判断,改用通用的元数据驱动逻辑

验证结果很漂亮:通过统一入口成功创建了一个复杂对象类——包含3个自定义Property和2个RelationshipType,所有关系正确内联,没有走预创建,没有报编号错误。

这意味着什么?

  • 前端不再需要维护两套创建逻辑,所有创建都走
/api/unified/create
  • 后端不再需要为“特殊类型”写特殊分支,所有差异由元数据自动驱动 - 新加任何ItemType,只要配置好元数据,创建流程自动适配 - 对象类创建也获得了统一的存在性预检、日志、兜底能力

左帮右臂能为你做什么

我们做的不仅仅是技术优化。当你的企业系统里有上百个对象类型,每个类型都有自己的创建规则、编号逻辑、关系约束时,维护成本是指数级增长的。

左帮右臂(BossAgents)的智能体平台,专门解决这类“看似简单实则复杂”的企业级数据管理问题。我们不只是帮你写代码,而是帮你建立一套元数据驱动的智能体架构——所有业务逻辑的差异化,都通过配置而不是编码来实现。

从SCSAI到SAP,从Salesforce到自研系统,我们的智能体可以帮你统一对象创建、关系管理、数据校验、流程编排。不再有“特殊类型”,不再有“两条路径”,一切都是元数据说了算。

如果你也在被类似的问题困扰,不妨和我们聊聊。毕竟,一个好的架构,应该让你忘记架构的存在。

← 返回案例列表
分享:
🤖 Try Now →
🤖
🎁