3. Windchill对象模型与业务对象
在Windchill的接口开发中,真正决定代码能否跑通、数据能否落库的,往往不是API调用本身,而是对业务对象模型的准确理解。Windchill把工程数据抽象为一组相互关联的持久化对象,每个对象都有固定的类型体系、属性集合和生命周期状态。接口开发者的核心任务,就是把这些对象"翻译"成外部系统能理解的字段,再把外部数据"还原"成Windchill能接受的对象结构。
一、对象类型体系与继承关系
Windchill的业务对象并非彼此孤立,而是建立在一条清晰的继承链上。最顶层是WTPart、WTDocument、WTChangeOrder2等具体类型,它们都继承自WTObject,再往上追溯到Persistable。这条继承链意味着:凡是父类具备的属性(如name、number、versionInfo、lifeCycleInfo),子类对象天然拥有。接口开发中常见的错误,就是只盯着具体类型而忽略了继承属性,导致查询条件写错或字段遗漏。
以部件为例,WTPart又细分为WTPartMaster(主数据,承载编号与名称)和WTPart(版本实例,承载版本、状态、视图)。一个部件编号对应一个Master,而Master下可以挂多个版本实例。接口中若只传编号而不指定版本,系统通常返回最新已发布版本;若需要精确版本,必须同时提供versionInfo中的identifier和iteration。
二、核心业务对象的结构与关键属性
产品(Product/Container)是数据的组织容器,本身不直接承载工程属性,而是通过WTContainer体系管理上下文。接口中定位产品通常用containerName或containerOid,它决定了后续所有对象的作用域。
部件(Part)是BOM的骨架。关键属性包括:number(编号,唯一)、name(名称)、type(类型,如separable、inseparable)、source(来源,如make、buy)、unit(单位)、defaultUnit。版本属性由VersionInfo管理,包含identifier(版本标识,如A、B)和iteration(迭代号,如1、2)。生命周期状态通过LifeCycleInfo获取,常见状态有INWORK、RELEASED、OBSOLETE。
文档(Document)与部件结构相似,但多了content(内容文件)和documentType(文档类型)。接口上传文档时,通常先创建WTDocument对象,再通过ContentHolder挂载文件流,最后设置folder归属。
BOM(Bill of Materials)不是独立对象,而是部件之间的WTPartUsageLink关系。每条UsageLink记录父件、子件、数量quantity、单位unit、查找编号findNumber、行号lineNumber。接口展开BOM时,需要递归遍历UsageLink,并注意quantity是字符串类型,需做数值转换。
变更对象(Change Object)包括ChangeRequest(变更请求)、ChangeNotice(变更通知)、ChangeOrder2(变更单)。它们通过Changeable关系关联到受影响的部件或文档,并通过ChangeRecord记录具体变更动作。接口中创建变更单时,必须先建立变更对象,再挂载受影响对象,最后设置变更任务。
三、接口开发中如何定位和操作业务对象
定位业务对象的第一步是确定容器。Windchill中所有对象都归属于某个WTContainer,接口调用时若容器错误,即使编号正确也会返回空结果。实践中建议先用containerName获取containerOid,再以OID作为后续查询的上下文。
第二步是按业务编号查询。以部件为例,典型查询逻辑是:先通过WTPartMaster按number找到主数据,再通过主数据关联的WTPart版本实例获取具体版本。如果外部系统只传了编号,接口应默认取最新已发布版本;如果传了版本标识,则需同时匹配identifier和iteration。这里有一个容易踩的坑:iteration是迭代号,不是版本号,A.1和A.2是两个不同的迭代,但版本标识都是A。
第三步是操作对象。创建部件时,接口需要先构造WTPart对象,设置name、number、type、unit等属性,再调用PersistenceHelper.manager.save()持久化。更新对象时,必须先checkout锁定版本,修改属性后再checkin,否则会抛出WTException。删除对象则要区分逻辑删除和物理删除,Windchill默认走生命周期状态变更,而非直接删除记录。
对于BOM操作,接口展开时建议使用WTPartUsageLink的getUses()方法递归遍历。注意quantity字段在Windchill中存储为字符串,接口层需要做Double.parseDouble()转换,并处理单位换算。变更对象操作则更复杂:创建变更单后,必须通过Changeable关系挂载受影响对象,再通过ChangeRecord记录具体变更动作,最后设置变更任务和审批流程。接口中若跳过ChangeRecord直接修改部件属性,变更历史将无法追溯。
四、对象关系对接口设计的影响
理解对象关系后,接口设计会变得更清晰。例如,外部系统同步BOM时,接口不应只传父子件编号,而应同时传递quantity、unit、findNumber和lineNumber,因为这些字段共同构成UsageLink的完整语义。再如,同步文档时,接口需要先创建WTDocument对象,再通过ContentHolder挂载文件流,最后设置folder归属,三步缺一不可。
另一个关键点是版本与状态的联动。Windchill中,对象的versionInfo和lifeCycleInfo是独立管理的:版本标识由修订策略决定,生命周期状态由工作流驱动。接口中若只更新属性而不触发状态变更,对象可能停留在INWORK状态,导致下游系统无法获取。因此,接口设计时应明确:哪些操作需要触发状态流转,哪些操作只需修改属性。
最后,对象之间的引用关系决定了接口的查询深度。例如,从变更单查询受影响部件,需要经过Changeable关系;从部件查询关联文档,需要经过DescribedBy或Reference关系。接口开发者应熟悉这些关系名称,并在查询时合理设置expand参数,避免多次往返调用。
总结来说,Windchill对象模型的核心在于"继承链决定属性、关系链决定查询路径、版本与状态决定操作时机"。接口开发中,先定位容器,再按编号和版本精确查找对象,最后根据对象类型选择正确的创建、更新或变更操作。把这三层关系理清,接口的稳定性和可维护性会显著提升。