
做星空二开代码写在哪儿决定了它能不能扛住下一次补丁。我们项目里踩过最典型的一次两年前在标准销售订单上直接加了字段、改了保存逻辑上线很快。两年后标准产品升级单据元数据被新补丁刷了一遍自定义部分被覆盖功能失效而且因为改动散落在标准对象内部排查花了很久。同一个需求如果当初写成挂在标准单据事件上的插件升级时大概率不受影响。这篇文章把两种写法的差异落到代码层面讲清楚附字段承载建议表和升级后常见报错处理表。一、两种写法的代码差异写法 A直接改标准对象不推荐在 BOS 设计器里打开标准单据加自定义字段、改界面布局、重写业务逻辑。表面上看开发最快但改动直接压在标准对象的元数据上。写法 B插件挂标准单据推荐不动标准对象新增一个插件类挂到标准单据的公开事件上。using Kingdee.BOS.Core.Bill.PlugIn;using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;using System;using System.ComponentModel;namespace JiuDie.Erp.PlugIn.SaleOrder{////// 销售订单 - 保存前校验客户等级底线折扣/// 挂载方式BOS 设计器 - 销售订单 - 单据插件 - 保存(BeforeSave)///[Description(“销售订单-客户等级折扣底线校验”)]public class SaleOrderDiscountCheckPlugIn : AbstractBillPlugIn{// 底线折扣率百分数低于该值不允许保存private const decimal MinDiscountRate 70m;public override void BeforeSave(BeforeSaveEventArgs e) { base.BeforeSave(e); // 取当前单据上的字段值示意实际标识以现场元数据为准 var custLevel Convert.ToString(this.Model.GetValue(F_CustLevel)); // 客户等级 var discountRate Convert.ToDecimal(this.Model.GetValue(F_DiscountRate)); // 折扣率 if (string.IsNullOrWhiteSpace(custLevel)) { return; // 未填客户等级不拦截交由其他校验处理 } // 仅对低等级客户做底线校验 if (custLevel C discountRate MinDiscountRate) { throw new Exception(string.Format( 客户等级为 C 类折扣率 {0}% 低于底线 {1}%请走审批后保存。, discountRate, MinDiscountRate)); } } }}这样写的关键点有三个不碰标准对象元数据。字段通过「引入自定义字段」的方式挂到单据上而不是直接改建标准字段。补丁更新标准元数据时自定义字段是独立的一份不受影响。挂公开事件。BeforeSave 是标准单据生命周期里的公开扩展点。要避开那些未公开、可能在新版本被调整的内部方法重写。字段标识加前缀。自定义字段统一用 F_ 加业务前缀避免和标准字段撞标识。二、字段该承载在哪里同一个需求承载方式不同升级风险差很多。实践中可以按这张表选需求类型建议承载方式说明标准单据上的新增业务属性自定义字段不直接改建标准字段标识加业务前缀避免与标准字段冲突全新的业务单据自定义业务对象与标准对象解耦标准产品升级一般无影响标准单据的校验与联动插件挂在公开事件上事件点必须选公开且稳定的扩展点界面布局调整扩展方案 / 自定义布局不直接改标准界面模板跨系统数据进出WebAPI不动标准产品升级基本无感依赖标准内部算法的逻辑改为调用公开服务或接口内部实现可能随版本变化最后一行值得展开如果二开逻辑里直接引用了标准产品的内部类或内部方法这类代码在升级中最容易断。正确的做法是找有没有对应的公开服务没有的话再考虑把这段逻辑独立出来自己实现。三、升级后常见报错与处理这张表是我们项目里攒出来的实际排查时能省不少时间。升级后现象常见原因处理方式单据保存报「字段不存在」直接加在标准对象上的自定义字段被补丁覆盖先查二开清单定位字段用引入自定义字段的方式重建同步修正代码里的字段标识插件完全不触发挂载的事件点在新版本被废弃或改名查新版本的事件列表改挂公开且仍在维护的事件界面布局被还原标准界面模板被补丁更新覆盖自定义布局改走扩展方案不直接改标准模板金额或数量算错逻辑依赖了标准内部算法算法变了改为调用公开服务或把算法在本插件内独立实现报表取数为空直接读标准表表结构或状态字段变了改走业务对象视图或 WebAPI 取数不直连标准表列表过滤条件失效过滤依赖的状态枚举值发生变化改为引用标准枚举不写死数值四、发布前的自检清单改完代码别急着上生产这五项过一遍这次改动有没有直接修改标准对象的元数据插件挂的事件点是不是公开的代码里有没有引用标准产品的内部类或内部方法新增字段的标识是否加了业务前缀这次改动的影响范围有没有写进二开清单并给出回归测试点第 5 项经常被跳过但它是升级时最值钱的一份东西。没有它两三年后连当初改了什么都要靠猜。五、关于升级影响评估如果手上有历史二开、又准备升级标准产品比较稳的做法是先做一次升级影响评估把现有二开点按「是否触碰标准对象元数据」「是否依赖内部实现」两个维度过一遍输出一份风险清单和回归测试点。这类评估工作我们做得多一些广州地区有相关需求可以交流工程问题也可以直接留言讨论。