ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

用友 U8 CO 接口 HTTP 化实践:从 COM 晚绑定到 RESTful 单据服务

用友 U8 CO 接口 HTTP 化实践:从 COM 晚绑定到 RESTful 单据服务 用友 U8 CO 接口 HTTP 化实践从 COM 晚绑定到 RESTful 单据服务标签用友U8二次开发C#COMASP.NET CoreERP集成一、背景U8 集成为什么难做过用友 U8 二次开发的同学大概率踩过这些坑COM 组件依赖重U8Login、VoucherCO_PU、VoucherCO_SA等组件必须在本机安装 U8 客户端并注册进程还必须是x86。Interop DLL 版本碎片化%U8SOFT%\Interop\下几十个Interop.*.dll不同 U8 版本 ProgID 还带版本号如COMV1300_U8Login.clsLogin引用管理很痛苦。调用方式不统一官方文档里至少有三条路——U8API BrokerU8EnvContextU8APIBroker、CO 对象VoucherCO_* XML、以及较新的OpenAPI。各模块覆盖范围不同没有「一条 API 通吃」。客户端直连不可行业务系统Java、Python、前端无法直接调 COM必须有一层服务端中间件统一登录、封装业务、对外暴露 HTTP。网上常见方案是在 IIS 上部署 ASP.NET Web API引用Interop.U8Login.dllUFIDA.U8.U8APIFramework.dll按「七步调用法」走 Broker。这条路成熟但对采购/销售/库存等经典单据 CO来说直接操作VoucherCO往往更贴近 U8 客户端行为价税计算、BodyCheck、审核弃审等逻辑也更完整。下文以一套自研CO HTTP 中间层工程名YonyouErp.U8.CoApi为例说明CO XML 模板 HTTP 扁平路由的实现思路供 MES/WMS/OA 等系统对接 U8 时参考。二、U8 集成的三条路怎么选方式典型入口优点局限U8API BrokerU8EnvContextU8APIBroker.Invoke官方文档全、模块覆盖广参数是 BO/XML学习曲线陡部分能力走 OpenAPICO 对象VoucherCO_PU/VoucherCO_SA/USERPCO等与 U8 客户端同源价税/校验一致需构造 head/body XMLInit 参数因单据类型而异OpenAPIHTTP Token跨语言友好需 U8 版本授权并非所有单据都有该方案专注 CO 栈覆盖采购、销售、库存、应收应付、总账凭证、委外、质量、BOM、基础档案等生产订单等无经典 CO 的能力需走 OpenAPI Broker代码里已明确标注边界。三、工程架构一览外部系统 / 前端 / 脚本 │ ▼ HTTP (JSON) ┌───────────────────────────────────────┐ │ YonyouErp.U8.CoApi.Server │ │ ASP.NET Core net10.0 x86, :5080 │ │ Swagger Vue3 管理台 请求日志 │ └───────────────────────────────────────┘ │ 同进程引用 ▼ ┌───────────────────────────────────────┐ │ YonyouErp.U8.CoApi (net472 x86) │ │ ProgID 晚绑定 XML 模板 各 *Engine │ └───────────────────────────────────────┘ │ COM ▼ ┌───────────────────────────────────────┐ │ 用友 U8 客户端已注册组件 │ │ U8Login / VoucherCO_* / USERPCO … │ └───────────────────────────────────────┘核心设计决策原因无独立 Worker 进程Server 直接引用 CoApi 库同进程调 COM部署简单ProgID 晚绑定不引用 InteropType.GetTypeFromProgIDInvokeMember规避 Interop 版本合并问题net10 HTTP 壳 net472 COM 核CoreCLR 做现代 WebCOM 仍在 .NET Framework 4.7.2 程序集本地 XML 模板 z:row占位避免每次WHERE 10拉 Schema按账套缓存XML_{organCode}/扁平路由/api/{key}/{action}单据与档案统一入口Swagger 自描述四、核心技术实现4.1 COM 晚绑定不引用Interop.U8Login.dll直接按 ProgID 创建实例publicstaticTypeGetType(stringprogId){if(!TryGetType(progId,outTypetype)||typenull)thrownewInvalidOperationException(未注册 COM ProgIDprogId);returntype;}publicstaticobjectInvokeMethod(Typetype,objecttarget,stringmethod,object[]args,bool[]byRefnull,string[]namesnull){// byRef 处理 U8 常见的 error / voucherid 输出参// names 缓解 COM 重载匹配问题returntype.InvokeMember(method,BindingFlags.InvokeMethod,...);}这与网上教程「必须引用 Interop 才能 C# 开发」并不矛盾——Interop 本质是编译期类型提示运行时晚绑定同样可行且更抗版本差异。4.2 登录与会话每次 API 请求按organCode解析账套配置创建clsLogin并在请求结束后释放TypetypeComInvoker.GetType(ProgIds.U8Login);loginComInvoker.Create(type);ComInvoker.InvokeMethod(type,login,Login,args,byRef,names);appsettings.json支持多账套{ListenUrl:http://localhost:5080/,SharedKey:,U8:{Organizations:{301:{AccID:999,Server:127.0.0.1,UserID:demo,Password:DEMO}}}}4.3 写单流水线以采购为例登录 → 检查 XML 模板 → CoFactory.CreatePu → FillHead/FillBody → LoadXml(head/body DOM) → BodyCheck(价税) → VoucherSave采购订单新增请求示例{organCode:301,loginDate:2026-08-21,data:{cbustype:普通采购,dpodate:2026-08-19,cvencode:01001,nflat:1,rows:[{cinvcode:01001,iquantity:1,itaxprice:10,ipertaxrate:13}]}}调用POST /api/purchaseorder/create4.4 XML 模板机制首次对接某账套时初始化模板POST /api/templates/init?voucherpurchaseorderorganCode301流程登录账套查首张真实单据或指定billNoCOQuery拿到真实 XML将rs:data替换为z:row z_row /落盘到XML_301/PU/...日常写单只读本地模板 字段填充管理台http://localhost:5080/可图形化查看、重置各账套模板。五、REST API 设计5.1 主要端点方法路径说明GET/health探测 Server U8Login ProgIDGET/api/vouchers支持的单据清单GET/api/archives基础档案清单POST/api/{key}/queryOne单张查询POST/api/{key}/query列表查询POST/api/{key}/{action}写操作create/modify/delete/verify/abandonPOST/api/report/{name}SQL 报表现存量、往来账龄5.2 请求体约定位置字段说明顶层organCode组织/账套编码顶层userId/password可选覆盖配置顶层loginDate登录日期默认当天顶层billNo单号删/审/弃审filtercode/dateFrom/top…查询条件data表头平铺 rows写单载荷5.3 能力范围节选供应链采购订单/到货/入库/发票、销售订单/出库/发票、库存调拨/组装、委外全套财务收付款、付款申请、应收应付票据、总账凭证含现金流质量来料/成品/在库 报检、检验、拒收主数据部门、人员、客商、存货、仓库、计量单位、BOM 等查询报表单据列表、档案查询、现存量、应收应付账龄完整 key 列表以运行中GET /api/vouchers为准。六、部署与运行6.1 环境要求Windows 服务器已安装 U8 客户端COM 已注册进程必须 x86只需启动一个 Server 进程6.2 启动dotnet build src\YonyouErp.U8.CoApi.Server\YonyouErp.U8.CoApi.Server.csproj -c Release src\YonyouErp.U8.CoApi.Server\bin\Release\YonyouErp.U8.CoApi.Server.exe健康检查http://localhost:5080/healthSwaggerhttp://localhost:5080/swagger6.3 冒烟测试工程内置 PowerShell 冒烟脚本适合上线前回归、U8 升级后验证# 只读探测不改账套powershell-File scripts/smoke.ps1-ReadOnly# 完整冒烟采购订单全流程 重点 CRUDpowershell-File scripts/smoke.ps1# 全量 CRUDpowershell-File scripts/smoke-full.ps1-Organ 301七、与 IB 事件插件协作写单时 U8 内部会触发IB 事件插件。若需事件上报可在IB_Event_Plugin的 After 钩子里捕获 DOM、必要时 ADODB 回表再 HTTP 推送至业务系统。职责拆分示例层职责HTTP 写单服务调 CO 写单/查询IB 插件捕获事件、回表、上报HTTP 写单路径与 U8 客户端一致因此 IB 插件能正常触发两层可独立部署也可组合使用。八、常见问题 FAQQ1为什么不用 U8API BrokerBroker 适合模块多、官方示例全的场景CO 适合经典供应链单据价税BodyCheck、审核弃审与客户端一致。本文方案定位是 CO 的 HTTP 化中间层不是 Broker 通用封装。Q2Login 报0x80131700Automation 异常Server 需配置useLegacyV2RuntimeActivationPolicy且进程为x86。Q3modify 时表体为空需传body或确保billNo能查到原单并合并。Q4基础档案要不要 Init 模板档案用静态模板一般无需Init业务单据首次对接账套建议templates/init。Q5生产订单为什么没实现本机无VoucherCO_MO官方走 OpenAPIU8API/MOrder/MOrderAdd。委外订单outsourcingOrder用的是VoucherCO_OM不要与生产订单混淆。Q6如何对接 Java / Python任意语言发 HTTP JSON 即可若配置了SharedKey请求头带X-CoApi-Key。九、与常见自研方案的差异技术选型维度传统 Interop IIS WebAPI本文 CO HTTP 方案COM 绑定编译期引用 Interop DLLProgID 晚绑定单据构造常手写 Broker BO本地 XML 模板 JSON 填字段路由每模块自定义 Controller统一/api/{key}/{action}运行时.NET Framework 4.xnet10 Kestrel net472 COM 核文档手写Swagger 字段说明 API测试人工点 U8内置分层冒烟脚本十、总结将 U8 最常用的CO XML集成路径封装为 HTTP 服务核心要点如下ProgID 晚绑定降低 Interop 版本维护成本账套级 XML 模板兼顾正确性与性能扁平 REST 路由降低异构系统对接成本分层引擎Pu/Sa/St/Ap/Gl/Bd/Qm…按模块隔离 COM 细节Swagger 管理台 冒烟脚本支撑长期运维若你也在做 MES/WMS/OA 与 U8 的供应链打通希望少重复写 Login Init LoadXml VoucherSave可以把 COM 细节收敛到中间层业务侧只关心 HTTP 编排。参考资料U8API 开发手册C# 版七步调用法 —U8EnvContext、U8APIBroker标准流程C# 编写用友 U8 功能与 Interop 技术 — Interop DLL 与版本管理思路声明本文为 U8 CO 二次开发技术实践分享。用友 U8 为用友网络科技股份有限公司产品本文与用友官方无关。
返回列表