1. 项目背景与需求分析
在企业信息化建设过程中,OA系统与ERP系统的集成是提升业务流程效率的关键环节。我们最近接到一个实际需求:需要将用友NC系统中的各类业务单据(如请购单、付款单等)推送到泛微OA-E9系统进行审批,并在OA审批完成后将审批结果回写到NC系统。
这种集成场景在企业中非常典型。以请购流程为例,传统模式下业务人员在NC系统填写请购单后,需要手动通知审批人登录OA系统处理,审批人又需要返回NC系统更新状态。这种人工切换不仅效率低下,而且容易出错。通过系统间自动对接,可以实现以下核心价值:
- 审批流程自动化:NC单据自动触发OA审批流程,无需人工干预
- 状态实时同步:OA审批结果(同意/驳回)即时回传NC系统
- 操作痕迹完整:保留审批意见、操作人、时间等完整审计信息
- 业务闭环管理:形成从业务发起→审批→结果反馈的完整闭环
2. 技术方案设计
2.1 整体架构设计
系统集成采用"事件驱动+接口调用"的混合模式:
- NC→OA方向:通过NC系统的单据提交事件触发,调用OA提供的流程发起接口
- OA→NC方向:通过OA审批节点的附加操作机制,在审批完成时调用NC的回写接口
mermaid复制graph LR
NC系统 -->|1.提交单据| OA系统
OA系统 -->|2.发起审批| 审批人
审批人 -->|3.处理审批| OA系统
OA系统 -->|4.回传结果| NC系统
2.2 关键实现要点
2.2.1 接口协议选择
考虑到企业IT环境的异构性,采用以下技术标准:
- 通信协议:HTTP/HTTPS
- 数据格式:JSON(轻量级,易解析)
- 认证方式:基于Cookie的会话保持(示例中使用JSESSIONID)
2.2.2 异常处理机制
设计三级容错方案:
- 接口超时重试(3次,间隔5秒)
- 结果状态校验(检查返回JSON中的status字段)
- 异常日志记录(记录到OA系统日志和独立日志文件)
2.2.3 安全控制措施
- 敏感配置外置:接口URL等配置放在cust.properties文件
- 参数校验:对关键字段进行非空校验
- 错误隔离:单个单据回传失败不影响其他单据处理
3. 详细实现过程
3.1 核心类开发
开发ResultBackAction类实现审批结果回传功能,关键代码解析:
java复制public class ResultBackAction implements Action {
private static Logger logger = LoggerFactory.getLogger(ResultBackAction.class);
public static BaseBean bb = new BaseBean();
// 配置参数
public String spResult; // 审批状态(Y/N)
public String spcode; // 单据类型(qg/fkd等)
public String execute(RequestInfo requestInfo) {
// 获取当前操作用户信息
String oa_user = getOperatorWorkcode(requestInfo);
// 参数校验
if (StringUtils.isBlank(this.spcode)) {
actionInfo.addErrMessage("缺失单据类型参数");
return actionInfo.handleResultAndGetFlag();
}
// 构建请求参数
Map<String, String> params = buildRequestParams(requestInfo, oa_user);
// 调用NC接口
return callNcInterface(params);
}
// 其他辅助方法...
}
关键设计说明:
- 实现
Action接口而非继承BaseBean,更符合OA插件规范- 使用OkHttp3作为HTTP客户端(比HttpURLConnection更高效)
- 采用Alibaba FastJSON处理JSON数据(性能优于net.sf.json)
3.2 配置部署步骤
3.2.1 文件部署
-
编译后的class文件存放路径:
code复制weaver/ecology/classbean/weaver/workflow/action/ResultBackAction.class -
配置文件(cust.properties)示例:
properties复制# 请购单结果回传接口 urlqg=http://nc-server/api/purchase/approval/callback # 付款单结果回传接口 urlfk=http://nc-server/api/payment/approval/callback
3.2.2 服务重启注意事项
-
测试环境建议使用增量重启:
bash复制cd /weaver/ecology ./stop.sh && ./start.sh -
生产环境建议在业务低峰期操作
-
重启后检查日志文件确认加载成功:
code复制tail -f ../logs/action.log
3.3 流程节点配置
在OA流程设计器中配置节点附加操作:
-
同意归档节点:
- 类路径:
weaver.workflow.action.ResultBackAction - 参数配置:
code复制spcode=qg // 请购单标识 spResult=Y // 审批通过
- 类路径:
-
驳回归档节点:
- 类路径:同上
- 参数配置:
code复制spcode=qg spResult=N // 审批驳回
配置技巧:
- 不同类型单据应配置不同的spcode值
- 可通过"克隆操作"快速复制配置到其他类似节点
- 建议添加操作描述便于后续维护
4. 常见问题排查
4.1 典型问题汇总
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 接口返回404错误 | 1. URL配置错误 2. NC服务未启动 |
1. 检查cust.properties配置 2. 联系NC运维确认服务状态 |
| 返回结果解析失败 | 1. JSON格式不符 2. 编码问题 |
1. 使用Postman测试原始接口 2. 确认UTF-8编码 |
| 审批结果未更新 | 1. 参数传递错误 2. NC接口逻辑问题 |
1. 检查spResult参数 2. 查看NC接口日志 |
4.2 日志分析技巧
-
查看OA动作日志:
bash复制grep "ResultBackAction" ../logs/action.log -
解析日志关键信息:
- 请求参数:
logger.info("调用url:"+url+"参数"+json.toString()) - 返回结果:
logger.info("接口返回信息:" + result) - 异常信息:
logger.info("接口异常信息:" + e.getMessage())
- 请求参数:
4.3 性能优化建议
-
连接池配置:
java复制OkHttpClient client = new OkHttpClient.Builder() .connectionPool(new ConnectionPool(20, 5, TimeUnit.MINUTES)) .build(); -
异步调用改造:
java复制client.newCall(request).enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { // 处理响应 } }); -
批量回传机制:对于高频场景,可考虑攒批处理
5. 扩展应用场景
5.1 支持更多单据类型
通过扩展spcode参数实现多单据支持:
java复制// 在execute方法中扩展判断逻辑
if("cgd".equals(spcode)){ // 采购单
url=bb.getPropValue("cust", "urlcg");
}
5.2 审批意见格式化
对OA审批意见进行智能处理:
java复制String remark = requestInfo.getRequestManager().getRemark();
// 去除特殊字符
remark = remark.replaceAll("[\\t\\n\\r]", " ");
// 截取有效内容
remark = remark.length() > 200 ? remark.substring(0,200) : remark;
5.3 二次确认机制
对于重要单据,增加审批确认环节:
- 在OA审批表单添加确认对话框
- 只有确认后才执行结果回传
- 记录确认人和确认时间
java复制if("important".equals(requestInfo.getRequestManager().getIsconfirm())){
// 执行回传
}
6. 安全加固方案
6.1 接口安全增强
-
HTTPS加密:
java复制OkHttpClient client = new OkHttpClient.Builder() .sslSocketFactory(sslContext.getSocketFactory()) .build(); -
访问令牌机制:
java复制Request request = new Request.Builder() .addHeader("Authorization", "Bearer " + token) .build();
6.2 审计日志完善
-
记录完整操作轨迹:
java复制logger.info("操作人:{}, 单据ID:{}, 状态:{}, 时间:{}", oa_user, ygcode, spResult, operatortime); -
日志定期归档策略:
- 每日切割日志文件
- 保留最近30天日志
- 关键操作日志存入数据库
6.3 参数校验强化
java复制// 单据ID校验
if(!ygcode.matches("[A-Za-z0-9]{8}-[A-Za-z0-9]{4}")){
actionInfo.addErrMessage("单据ID格式错误");
return actionInfo.handleResultAndGetFlag();
}
// 用户工号校验
if(StringUtils.isBlank(oa_user) || !oa_user.startsWith("EMP")){
actionInfo.addErrMessage("无效的操作人工号");
return actionInfo.handleResultAndGetFlag();
}
7. 实际部署经验
7.1 测试环境验证
建议分三个阶段测试:
-
单元测试:使用Mock数据验证类逻辑
java复制@Test public void testExecute() { RequestInfo mockInfo = createMockRequest(); ResultBackAction action = new ResultBackAction(); action.setSpcode("qg"); action.setSpResult("Y"); String result = action.execute(mockInfo); assertEquals(Action.SUCCESS, result); } -
集成测试:连接真实NC测试环境
- 验证各种审批场景(同意、驳回、加签等)
- 模拟网络异常情况
-
压力测试:使用JMeter模拟并发审批
- 建议50并发起步
- 关注OA和NC的系统资源占用
7.2 生产上线checklist
- [ ] 核对cust.properties中的接口地址
- [ ] 确认class文件权限(应为weaver用户可读)
- [ ] 检查各流程节点的参数配置
- [ ] 准备回滚方案(禁用附加操作即可)
- [ ] 通知相关业务部门测试时间
7.3 运维监控建议
-
健康检查脚本:
bash复制#!/bin/bash response=$(curl -s http://oa-server/approval/health) if [[ $response != *"UP"* ]]; then echo "OA审批服务异常" | mail -s "告警" admin@company.com fi -
关键指标监控:
- 接口响应时间(应<1s)
- 成功率(应>99.9%)
- 并发数(峰值预警)
-
定期维护事项:
- 每月检查证书有效期
- 每季度更新接口令牌
- 每年演练灾备方案
8. 技术演进方向
8.1 服务化改造
将集成逻辑抽离为独立服务:
-
优点:
- 解耦OA和NC的直接依赖
- 便于集中管理接口协议
- 支持灵活扩展
-
架构示例:
code复制OA → 集成平台 → NC ↑ 监控中心
8.2 消息队列引入
使用RabbitMQ实现异步可靠传输:
- 审批完成后发送MQ消息
- 消费者负责结果回传
- 实现消息重试和死信处理
java复制// 发送消息示例
channel.basicPublish("approval.exchange",
"nc.callback",
new AMQP.BasicProperties.Builder()
.deliveryMode(2) // 持久化
.build(),
message.getBytes());
8.3 低代码配置
开发可视化配置界面:
- 单据类型映射配置
- 字段转换规则配置
- 审批路径可视化编排
最终实现"零代码"对接新业务单据