用友 U9 Cloud是用友面向中型、中大型离散制造企业的中高端 ERP 系统,基于 YonBIP 平台,B/S 浏览器架构,主打多组织、多工厂、复杂制造、集团协同。并且通过插件平台支持二次拓展开发,丰富系统功能,满足客户定制化开发需求。
今天介绍下U9 Cloud BE插件开发流程,BE是Business Entity的缩写,即业务实体。何为业务实体呢?U9中的单据、物料、BOM这些都是业务实体。通过BE插件,可以实现对业务实体的操作,比如根据客户业务逻辑重新计算单据数据字段值,通过BE插件实现单据对接三方系统等多种业务场景。
BE插件二开的原理实际上就是事件监听模型,类似于发布/订阅模式。二开的BE插件进行注册,注册的意思就是进行某个业务实体的事件监听,这些事件包括实体新建、修改、删除等事件。当对应BE事件发生时,插件平台会调用对应的BE插件,并完成代码的执行。
开发环境准备
IDE安装
U9系统是使用C#语言开发,数据库使用SQL Server。所以U9插件开发也是使用C#语言。C#语言开发主推的当然是微软本家的Visual Studio。其次推荐JetBrain的Rider IDE也是针对C#开发的集成开发环境。大家可以按需安装配置。
U9 Cloud安装
介绍完IDE,接下来需要有U9 Cloud服务,开发U9没有U9 Cloud也无法调试、测试不是:),而且U9的数据字典也依赖U9服务,U9数据字典提供了U9所有单据的字段信息、业务过程信息等,是U9二开必须的服务。而且U9开发需要调用U9相关API或BE类,这些dll文件都可以在U9安装目录找到。具体安装包可以到U9官方网站下载并安装。
U9 字典安装
U9字典代码下载地址:https://u9hub.yonyoucloud.com/a/tools/down#/,网址打开后如下图,点击ClassView进行字典代码下载

下载完成后,安装下图安装配置U9字典服务,注意字典服务需要和U9 Cloud安装在同一台机器上,因为字典服务会读取U9相关数据。

安装好后访问如下图,字典服务支持查询实体(各种单据、BOM、物料等,一个实体对应数据库一张表)、BP(业务流程,比如:销售订单提交、销售订单审核等相关业务逻辑的API以及所在dll文件名称)、View(数据库视图)、Form(表单)。

代码开发
使用Visual Studio或Rider创建一个C#项目,并导入BE开发需要依赖dll包,这些dll包包括:UBF.System.dll、UFIDA.UBF.SystemManage.Base.dll、UFSoft.UBF.AopFrame.dll、UFSoft.UBF.Business.dll、UFSoft.UBF.Execution.dll、UFSoft.UBF.PL.dll、UFSoft.UBF.Service.dll,这些是BE插件开发必须的依赖。然后针对哪种BE进行开发,再导入对应的依赖包。比如需要针对销售订单进行二开,则需要导入UFIDA.U9.SM.SMBE.dll依赖。
BE插件可插入的事件及事件顺序如下:
- 新增 :BeforeDefaultValue>>SetDefaultValue>>AfterDefaultValue>>BeforeValidate>>Validate>>AfterValidate>>BeforeInserting>>Inserting>>AfterInserting>>BeforeInserted>>Inserted>>AfterInserted
- 修改:BeforeDefaultValue>>SetDefaultValue>>AfterDefaultValue>>BeforeValidate>>Validate>>AfterValidate>>BeforeUpdating>>Updating>>AfterUpdating>>BeforeUpdated>>Updated>>AfterUpdated
- 删除: BeforeDeleting>>Deleting>>AfterDeleting>>BeforeDeleted>>Deleted>>AfterDeleted
依赖导入完成后,开始进行业务代码开发,首先需要创建模板类、编写模版代码。比如我需要针对销售订单进行开发,并监听销售订单的更新事件。
// 新建一个类AfterUpdated
// 命名空间和文件路径保持一致即可,这里不同的BE的插件最好放在不同命名空间下
namespace U9.CD.saleOrderPlugin.SO
{
// 模版类,监听单据修改后事件,即单据修改完成后,调用该类。都继承IEventSubscriber(事件订阅者),只是类名不同,比如监听单据修改前事件,类名可以是BeforeUpdated。类名没有强制要求
public partial class AfterUpdated : UFSoft.UBF.Eventing.IEventSubscriber
{
// 只需要实现这一个方法,并且所有BE插件这个方法的实现代码都是一样的
void UFSoft.UBF.Eventing.IEventSubscriber.Notify(object[] args)
{
// 具体插件逻辑在Do_Notify方法中实现
this.Do_Notify(args);
}
}
}
// 再新建一个类AfterUpdatedExtend。
using System;
using System.Web;
using Newtonsoft.Json;
using SAIGE.U9.CD.productionOrderSync;
using UFIDA.U9.Base.Profile;
using UFIDA.U9.SM.SO;
using UFSoft.UBF.Util.Log;
namespace U9.CD.saleOrderPlugin.SO
{
using UFSoft.UBF.Business;
// 将类定义改成分部类,且类名与AfterUpdated.cs文件中的一致
public partial class AfterUpdated
{
// 实现AfterUpdated类的Do_Notify方法,传入参数是BE相关的数据
private void Do_Notify(object[] args)
{
#region 从事件参数中取得当前业务实体
// 入参校验
if (args == null || args.Length == 0 || !(args[0] is UFSoft.UBF.Business.EntityEvent))
return;
BusinessEntity.EntityKey key = ((UFSoft.UBF.Business.EntityEvent)args[0]).EntityKey;
if (key == null)
return;
// 获取到销售订单数据
UFIDA.U9.SM.SO.SO holder = key.GetEntity() as UFIDA.U9.SM.SO.SO;
if (holder == null)
return;
// 销售订单处理逻辑
// 比如:单据状态检查,只处理审核通过的销售订单
if (holder.Status != SODocStatusEnum.Approved)
{
return;
}
// 针对销售订单做任意处理
#endregion
}
}
}
发布部署
插件代码编写完成后,就可以部署到U9 Cloud。首先将C#代码编译打包成dll文件。然后编写插件注册的配置文件。
代码部署
停止U9服务,然后将编译好的dll和pdb文件拷贝到U9安装路径/Portal\ApplicationServer\Libs路径下,完成代码部署。
配置文件
配置文件为xml,以上边销售订单插件为例,文件内容如下:
<?xml version="1.0" encoding="utf-16"?>
<pub-sub>
<!-- 订阅销售订单AfterUpdated事件,即销售订单修改后调用该插件,只需要修改event属性即可 -->
<subcription event="UFIDA.U9.SM.SO.SO.AfterUpdated" ContactInfo="" Developer="" FeatureSummary="" PublishTime="0001年1月1日">
<!-- 配置订阅者,即插件代码,type属性中逗号前为类名,逗号后为代码编译后的dll文件名 -->
<subscriber type="SAIGE.U9.CD.saleOrderSync.SO.AfterUpdated,SAIGE.U9.CD.saleOrderSync.dll" />
</subcription>
</pub-sub>
将编写好的配置文件拷贝到U9安装路径下的Portal\bin目录下。完成插件注册,这样U9启动时,就可以读取到配置文件中内容,将插件注册到U9,并在对应事件发生时,插件平台会回调插件代码。
插件注册验证
以上动作完成后,重启U9服务,使用管理员账号登录企业账套。在系统管理–>客开管理–>客开监控页面查看插件状态,比如插件是否注册成功、状态是否正常等信息。

