C# U9 二次开发

U9 是用友 U9 Cloud,基于BEAS 开发平台 ,底层 C# + .NET Framework,服务端是 IIS+WCF,数据库 SqlServer;二次开发分:插件扩展、WebService 接口、单据扩展、自定义页面、外部程序调用 U9 接口。 ⚠️ U9 二次开发不建议直接修改 U9 原代码,全部使用扩展、插件模式,升级不会覆盖。

一、开发环境准备

  1. 必备工具
  • Visual Studio(推荐 VS2019,.NET Framework 4.7,U9 老版本是 4.5)

  • U9 开发端环境:安装 U9 BEAS 开发工具(U9 客户端里的【开发平台】)

  • 引用 U9 核心 dll(从 U9 服务器 bin 目录拷贝,不要 NuGet 下载)

    U9.dll
    U9.Common.dll
    U9.DB.dll
    U9.Platform.dll
    U9.Shell.dll
    U9.BO.dll
    U9.WCF.dll
    BEAS.Core.dll

路径:U9 安装目录 U9\WebSite\bin,复制到本地项目引用,复制本地 = False,服务器上本身有。

  1. 两种开发模式 1)服务端插件开发(最常用) :单据保存前 / 后、审核前 / 后、按钮点击事件,C# 类库项目 2)外部程序调用 U9 :控制台 / WINFORM,调用 U9 WCF WebService 接口 3)BEAS 自定义页面:在 BEAS 平台拖拽,后台写 C# 脚本

二、模式 1:U9 服务端插件开发(C# 类库)

场景:销售订单、采购单,保存前校验、自动赋值、生成其他单据、审核后触发业务

1. 新建项目

VS 新建【类库 (.NET Framework)】,.NET4.7,引用上面 U9dll。

插件类必须继承 U9.Platform.Plugin.IBusinessPlugin

复制代码
using System;
using U9.Platform;
using U9.Platform.Plugin;
using U9.BO;
using U9.Common;

namespace U9Plugin.Demo
{
    /// <summary>
    /// 销售订单插件示例
    /// </summary>
    public class SaleOrderPlugin : IBusinessPlugin
    {
        //插件执行入口
        public void Execute(PluginContext context)
        {
            //获取当前业务对象
            var bo = context.BusinessObject as ISaleOrder;

            //区分事件类型
            switch (context.EventType)
            {
                case PluginEventType.BeforeSave:
                    //保存前事件
                    BeforeSave(bo, context);
                    break;
                case PluginEventType.AfterSave:
                    //保存后
                    break;
                case PluginEventType.BeforeAudit:
                    //审核前
                    break;
                case PluginEventType.AfterAudit:
                    //审核后
                    break;
            }
        }

        private void BeforeSave(ISaleOrder saleOrder, PluginContext ctx)
        {
            //示例校验:订单金额不能小于0
            if(saleOrder.TotalAmount < 0)
            {
                //抛出异常,阻止保存
                throw new U9Exception("订单总金额不能小于0!");
            }

            //给字段赋值
            saleOrder.Memo = "插件自动赋值备注";

            //遍历分录
            foreach(var line in saleOrder.Lines)
            {
                var qty = line.Qty;
            }
        }

        //插件描述,U9平台识别
        public PluginDescriptor GetDescriptor()
        {
            return new PluginDescriptor
            {
                Name = "SaleOrderDemoPlugin",
                DisplayName = "销售订单自定义插件",
                //绑定BO元数据ID,销售订单BO编码:SAL.SaleOrder
                BOName = "SAL.SaleOrder",
                //订阅哪些事件
                SubscribeEvents = new PluginEventType[]
                {
                    PluginEventType.BeforeSave,
                    PluginEventType.AfterSave,
                    PluginEventType.BeforeAudit
                }
            };
        }
    }
}

2. 部署插件

  1. 编译生成 dll,放到 U9 服务器 U9\WebSite\bin\Plugin 2. 登录 U9【开发平台】→【插件管理】→注册插件,填入类的完整名 U9Plugin.Demo.SaleOrderPlugin,U9Plugin.Demo 3. 启用插件,重启 U9 应用池(IIS 回收应用程序池) 4. 测试新建销售订单触发插件。

关键点:BO 名称,每个单据有自己 BOName,比如 PO.PurchaseOrder 采购订单;可以在 BEAS 元数据浏览器查询 BO 编码。

三、模式 2:外部 C# 程序调用 U9 WCF 接口

场景:外部系统,C# 控制台 / WPF,新增、查询 U9 单据,不写插件。 U9 对外提供 WCF 服务地址: http://ip/U9/Service/BusinessService.svc

方式 A:添加服务引用

VS 项目右键添加服务引用,填入上面地址,生成客户端代理。

简单调用示例:

复制代码
//创建销售订单
var client = new BusinessServiceClient();
client.Open();

//构造DTO,调用Create接口
var result = client.Create("SAL.SaleOrder", saleOrderDto);

client.Close();

方式 B:直接使用 U9SDK(需要引用 dll)

复制代码
//需要账号密码,U9用户编码+密码
var loginInfo = new LoginInfo(){UserCode="admin",Password="xxx",OrgId=1001};
BusinessService svc = new BusinessService();
svc.Login(loginInfo);

//创建销售订单
svc.Create("SAL.SaleOrder", dto);

注意:跨服务器调用,需要 U9 服务器开启 WCF 权限,防火墙开放端口。

四、模式 3:BEAS 平台自定义页面(内嵌 C# 脚本)

  1. 登录 U9,打开【开发平台】,新建【自定义页面】 2. 拖拽控件(文本框、按钮、表格) 3. 按钮事件写 C# 脚本,脚本可以直接操作 BO 对象。

脚本环境是 U9 内置,不能引用外部 dll;复杂逻辑建议独立插件。

五、常用核心 API 说明

  1. BO 查询数据

    //Query查询BO
    var list = U9.DB.DBContext.Current.Query("SAL.SaleOrder")
    .Where("DocNo=@DocNo", new {DocNo="SO202608001"})
    .ToList();

  2. 抛出业务提示

    throw new U9Exception("自定义提示信息");

  3. 创建其他单据(插件内部)

    //BOFactory创建采购订单
    var po = BOFactory.Create("PO.PurchaseOrder");
    po.SupplierID = 123;
    po.Save();

六、重要坑点(U9 开发高频踩坑)

  1. 版本兼容:U9 V2.8、V3.0、Cloud 版本 dll 不一样,开发机器 dll 版本必须和服务器版本一致,否则报错。
  2. 不要直接 SQL 操作数据库 !禁止 SqlConnection直接写 SQL 改 U9 表,必须走 BO 对象,否则缓存、触发器、业务逻辑失效,数据错乱。
  3. 插件部署后必须回收 IIS 应用池,dll 不会自动加载。
  4. 组织 OrgID:U9 是多组织,所有单据必须指定组织 ID,忘记会报权限错误。
  5. 事务:插件上下文是同一个事务,BeforeSave 抛出异常,全部回滚。
  6. 升级风险:所有业务逻辑写插件,不要修改 U9 原有 dll,不要修改 BEAS 元数据原始 BO,升级会覆盖。

七、调试技巧

  1. 服务器附加进程调试:VS 附加 w3wp.exe(IIS 进程),断点打插件代码。 2. 日志:U9 日志路径 U9\Log,可以代码写日志

    U9.Common.LogHelper.LogInfo("我的日志信息");

八、学习资料渠道

  1. U9 开发平台元数据浏览器:查看全部 BO、字段、事件。
  2. U9 二次开发文档(用友实施文档,BEAS 开发手册)
  3. BO 示例:系统自带的插件例子,在 U9 安装目录 Sample。