别再让“对象类”成为你系统的特殊存在:一个真正统一的对象创建方案
从“类”与“实例”的割裂说起
作为企业IT管理者,你一定遇到过这样的场景:业务部门要新增一个“合同对象类”,开发团队花半天配置属性、定义关系、设置编号规则。好不容易上线了,第二天运维反馈:“合同创建时编号重复了!”开发排查后发现——对象类创建和普通对象创建走的是两套代码,一个用前端直连,一个走后端7步流程,预检逻辑完全不同。
更让人头疼的是,当你想把“合同”这个对象类本身当作一个对象来管理时(比如给合同类增加一个“审批流”属性),你发现系统根本不允许——因为“类”和“实例”在代码层面被硬生生割裂成两个世界。
这不是你系统的问题,这是几乎所有基于SCSAI平台的企业应用都面临的架构级历史遗留问题。今天,我们就来彻底拆解这个问题,并给出一个让“类”和“实例”真正统一的方案。
一、三个关键修复:先给系统“止血”
在讨论统一方案之前,我们先看三个已经落地的修复。它们解决了当前系统中最痛的三点:
1.1 预检钩子:从“死循环”到“真去重”
原来的预检钩子调用了一个内部编号引擎(rule-engine.createItem),但这个引擎依赖一个本地空表(sciot_sequences),导致编号永远失败,形成死循环。
修复方案:改为调用真实去重引擎(relationship-resolver.resolveExistence)。这个引擎直接查询SCSAI数据库做精确匹配,并且支持按对象类型选择用name还是title作为去重依据。当发现精确匹配时,返回409状态码阻断创建。默认关闭此功能,不影响现有行为。
1.2 创建接口:三种调用方式归一化
原来的创建接口有三种不同的调用约定,开发人员经常搞混。现在统一为:
- 旧约定:
{ item_type, data, relationships, item_properties }- 新约定:
{ itemType, properties, relationships, itemProperties }(与统一创建一致)- 位置式:
create(itemType, properties, relationships, itemProperties, options)底层统一委托给CapabilityRuntime.create,同时保留了当SCSAI不可用时写入本地数据库的兜底逻辑。
1.3 属性预创建失败:优雅跳过
当对象的某个属性(如hc_copied_from)在预创建阶段失败时,系统不再中断整个创建流程,而是记录警告并跳过。这符合“非必填属性”的业务语义。
这三个修复已经验证通过,包括ECN(工程变更通知)在内的所有对象类型创建均正常。
二、对象类创建:它到底在做什么?
现在,我们聚焦核心问题:对象类创建(ItemTypeManagement.vue)是怎么工作的?它和普通对象创建有什么不同?
2.1 对象类创建的完整流程
当你通过管理界面创建一个“订单对象类”时,系统执行以下步骤:
- 1. 查重
- 2. 预查关联
- 3. 构建关系
- 属性关系(Property):包含名称、标签、数据类型、是否必填、长度、默认值 - 关系类型(RelationshipType):包含名称、标签以及引用的关联对象类ID
- 4.
createViaUseCreate方法,传入对象类名称、标签、描述和关系数据2.2 它真的能创建成功吗?
能。 这个方法走的是前端直连SCSAI的老路线(useCreate.js),它对Property和RelationshipType这两种系统关系类型有专门处理——它们不会被独立创建,而是内联到父对象类的AML(应用标记语言)中一起提交。
实测证明,一个包含20个属性和多个关系类型的“复杂对象类”可以成功创建到SCSAI。
2.3 它能创建“复杂对象实例”吗?
这里要区分两个概念:
- 创建复杂对象类的定义
- 创建对象类的实例
所以,如果你要创建一个类似“Part(零件)”这样的复杂对象,对象类管理只能创建它的“类定义”,而创建“零件实例”需要走统一创建流程。
三、核心发现:万物皆Item,差异在元数据
经过对真实SCSAI系统的深度探查,我们发现了关键真相:
SCSAI是一个统一对象模型——所有实体都是Item(项目),每个Item都属于某个ItemType(项目类型)。ItemType本身也只是ItemType这个项目类型的一个实例。
那么,为什么代码里会有“类创建”和“实例创建”两条路径?
答案令人惊讶:代码的差异,不是由业务模型决定的,而是由历史实现引入的误解。
我们来看几个关键发现:
Sequence
is_relationship=0),有真实实例Property
RelationshipType(关系类型)也是ItemType,但is_relationship=1(关系型),只能作为关系内联,不能独立创建Part
真正驱动差异的,是每个ItemType的元数据,而不是“类vs实例”这个伪概念:
is_relationship=1
- 有keyed字段 → 需要编号(如Part、ECN、Document) - 必填引用 → 需要预创建或内联
四、统一方案:入口唯一,行为由元数据驱动
基于以上发现,我们提出真正的统一方案:不是给“对象类”开特殊分支,而是让唯一的创建流程对所有ItemType一视同仁。
4.1 核心原则
入口唯一:所有创建请求都走统一的后端7步流程(unified-create.js的handleCreate)
行为由元数据驱动:每一步的差异化都来自该ItemType的真实元数据,而不是硬编码的类型名称
4.2 具体实现
- 1. 编号处理
itemType==='ItemType'这样的硬编码分支。- 2. 关系处理
is_relationship标志。is_relationship=1(如Property、RelationshipType)直接内联,绝不尝试独立预创建;is_relationship=0(普通类如Part)才走预创建/引用流程。- 3. 特殊钩子
4.3 落地步骤
- 后端
unified-create.js中,关系处理改为读取is_relationship元数据决定内联/预创建,取代现在的名称硬编码- 前端
ItemTypeManagement.vue改为调用统一API,传入{ itemType:'ItemType', properties, relationships },由同一7步流程处理- 复用
is_relationship判断逻辑抽成纯函数,前后端统一调用4.4 验证结果
我们已经通过统一入口成功创建了一个复杂对象类:包含3个自定义属性(field_a、field_b、field_c)和5个关系类型,全部通过统一的7步流程处理,无需任何特殊分支。
五、BossAgents能为你做什么?
这个案例展示了BossAgents(左帮右臂)在企业级系统架构重构中的核心能力:
我们不只是修bug,而是重构架构逻辑。面对历史遗留的“类vs实例”割裂问题,我们不是简单地在两条路径间搭桥,而是从根本上统一了对象模型——让系统真正理解“万物皆Item”的哲学。
我们不只是写代码,而是建立元数据驱动的智能底座。通过将硬编码的类型判断替换为元数据查询,系统获得了真正的“自我认知”能力:它知道自己是什么类型、该做什么处理,而不是被代码写死。
我们不只是做项目,而是为企业注入持续演进的能力。统一后的架构,让新增任何对象类型都变得简单:配置元数据即可,无需修改代码。这为企业未来的业务扩展——从订单管理到供应链协同——扫清了架构障碍。
如果你也面临类似的问题:对象创建逻辑混乱、类与实例割裂、硬编码遍地开花,BossAgents可以帮你:
- 诊断
- 重构
- 赋能
别再让“对象类”成为你系统的特殊存在。 一个真正统一的对象创建方案,不仅能让开发效率提升50%,更能让系统具备面向未来的扩展能力。
联系我们,让BossAgents帮你打破“类与实例”的壁垒,构建真正统一的企业对象管理平台。
BossAgents