泛微OA-推送数据至第三方系统案例
OA 系统调用第三方系统或者推送数据至第三方系统。
一、调用第三方系统
案例场景:根据表单输入的订单号,调用 SAP,判断订单号是否正确,如正确,把订单信息存储在表单中。
1 后端接口准备
前置条件:配置白名单,白名单配置地址: ecology/WEB-INF/lib/prop 底下的:weaver_session_filter.properties
在 unchecksessionurl 处末尾加上接口地址:
后端需准备四个类:
GetSapOrderByOrderId.java
package com.api.公司名.workflow.web;
/**
* 根据订单号id,向sap查询订单数据 注意看包路径
*/
@Path("/test/workflow/getSapOrderByOrderId")
public class GetSapOrderByOrderId extends OrderNumberAction {
}
OrderNumberAction.java
package com.公司名.workflow.web;
/**
* 根据订单号id,向sap查询订单数据
*/
public class OrderNumberAction {
private OrderNumberService getService() {
return ServiceUtil.getService(OrderNumberServiceImpl.class);
}
/**
* 获取sap订单数据
* @param params
* @return
*/
@POST
@Path("/getOrderInfo")
@Produces(MediaType.APPLICATION_JSON)
public String getOrderInfo(Map<String, Object> params) {
Map<String, Object> apiData = new HashMap<>();
try {
//获取当前用户
apiData = getService().getOrderInfo(params);
} catch (Exception e) {
e.printStackTrace();
apiData.put("api_status", false);
apiData.put("api_errormsg", "catch exception : " + e.getMessage());
}
return JSONObject.toJSONString(apiData);
}
}
OrderNumberService.java
package com.comen.workflow.service;
/**
* 根据订单号id,向sap查询订单数据
*/
public interface OrderNumberService {
/**
* 获取sap订单数据
* @param params
* @return
*/
Map<String, Object> getOrderInfo(Map<String, Object> params);
}
OrderNumberServiceImpl.java
package com.comen.workflow.service.impl;
/**
* 根据订单号id,向sap查询订单数据
* 判断SAP订单号是否存在
* SAP接口:ZOA_GET_SO_DATA
* OA表名:SAP_Order_Number
*/
public class OrderNumberServiceImpl extends Service implements OrderNumberService {
private String functionName = "ZOA_GET_SO_DATA"; // sap 接口名
private String rfcReturnTableName = "OUT_TAB"; // SAP输出表
private static final Logger logger = LoggerFactory.getLogger(OrderNumberServiceImpl.class);
@Override
public Map<String, Object> getOrderInfo(Map<String, Object> params) {
Map<String, Object> resData = new HashMap<>(3);
try {
logger.info(">>>根据订单号查询SAP订单号数据> " + " 开始...");
Map<String, Object> sapHead = new HashMap<>();
String orderId = params.get("ddh").toString();
orderId = "00".concat(orderId); // sap 必须要在前面补充两个0才能获取
sapHead.put("I_VBELN", orderId); // 订单号
SapRemoteFunctionCaller srfc = new SapRemoteFunctionCaller(functionName);
srfc.setInputParams(sapHead);
srfc.setOutputTableNames(new String[]{rfcReturnTableName});
// SAP返回的订单号对应的数据
List<Map<String, Object>> tableData = null;
// 调用函数返回的结果
Map<String, Object> result = null;
if (srfc.call()) {
result = srfc.getResult();
// E_CODE: E:无数据,S:获取成功
if(!"S".equals(result.get("E_CODE").toString())){
resData.put("api_status", false);
return resData;
}
tableData = (List<Map<String, Object>>) result.get(rfcReturnTableName);
// 全部数值转换成String,备用
for (Map<String, Object> rowData : tableData) {
for (Map.Entry<String, Object> entry : rowData.entrySet()) {
rowData.put(entry.getKey(), String.valueOf(entry.getValue()));
}
}
resData.put("api_status", true);
resData.put("data", tableData);
return resData;
}
resData.put("api_status", false);
} catch (Exception e) {
resData.put("api_status", false);
resData.put("error", e.getMessage());
}
return resData;
}
}
2 表单插入 js 请求接口
接口写的潦草,将就看即可,主要学习方法。
let ddhId = WfForm.convertFieldNameToId("ddh"); // 订单号
let KUNNRId = WfForm.convertFieldNameToId("KUNNR"); // 售达方
let NETWRId = WfForm.convertFieldNameToId("NETWR"); // 订单金额
let KNRZAId = WfForm.convertFieldNameToId("KNRZA"); // 业务员
let BZIRKId = WfForm.convertFieldNameToId("BZIRK"); // 办事处\大区
let ERDATId = WfForm.convertFieldNameToId("ERDAT"); // 订单创建时间
let NAME1Id = WfForm.convertFieldNameToId("NAME1"); // 办事处\大区
// 订单号字段值变化触发
WfForm.bindFieldChangeEvent(ddhId, function(obj,id,value){
// 只请求接口做订单号校验
sendPost(value)
.then(data => {
if (data.api_status) {
} else {
console.log('POST 请求失败');
}
})
.catch(error => {
console.error('发生错误:', error);
});
});
WfForm.registerCheckEvent(WfForm.OPER_SAVE+","+WfForm.OPER_SUBMIT,function(callback){
let ddhValue = WfForm.getFieldValue(ddhId);
sendPost(ddhValue)
.then(data => {
if (data.api_status) {
console.log('POST 请求成功');
// console.log(JSON.stringify(data))
WfForm.changeFieldValue(KUNNRId, {value:data.data[0].KUNNR});
WfForm.changeFieldValue(NETWRId, {value:data.data[0].NETWR});
WfForm.changeFieldValue(KNRZAId, {value:data.data[0].KNRZA});
WfForm.changeFieldValue(BZIRKId, {value:data.data[0].BZIRK});
WfForm.changeFieldValue(ERDATId, {value:data.data[0].ERDAT});
WfForm.changeFieldValue(NAME1Id, {value:data.data[0].NAME1});
// 正确的订单号,放行
callback();
} else {
console.log('POST 请求失败');
}
})
.catch(error => {
console.error('发生错误:', error);
});
});
// 根据订单号请求SAP,查询订单号是否存在
function sendPost(orderId) {
return new Promise((resolve, reject) => {
const api = "/api/comen/workflow/getSapOrderByOrderId/getOrderInfo";
fetch(api, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"ddh": orderId,
})
})
.then(response => response.json())
.then(data => {
if (data.api_status === false) {
alert("请检查订单号:" + orderId);
//resolve(false); // 返回 false
} else {
// ... 其他操作
//resolve(true); // 返回 true
}
resolve(data);
})
.catch(error => {
console.error('发送 POST 请求失败:', error);
reject(error); // 返回错误信息
});
});
}
二、流程归档推送 DMS
/**
* 灯塔桥项目全院勘察申请归档推送DMS
*/
public class LightHouseBridgeToDms implements Action {
private static final String API_ADDR = "/crm/equipment/equipmentSync"; // 目标接口
private static final Log logger = LogFactory.getLog(MaterialToSap.class);
private String env; // 流程传过来的动态参数
@Override
public String execute(RequestInfo requestInfo) {
String loggerHead = ">>>" + WorkflowFunction.printWorkflowTraceInfo(requestInfo);
// 获取流程基础信息
RequestManager requestManager = requestInfo.getRequestManager();
logger.info(loggerHead + " is starting...");
IWorkLogUtil logUtil = new IWorkLogUtil();
try {
// 获取主表数据
Map<String, String> mainTable = WorkflowFunction.getMainTable(requestInfo);
String KUNNR = mainTable.get("KUNNR"); // 售达方
String NAME1 = mainTable.get("NAME1"); // 售达方名称
String ERDAT = mainTable.get("ERDAT"); // 订单创建时间
String BZIRK = mainTable.get("BZIRK"); // 办事处\大区
String KNRZA = mainTable.get("KNRZA"); // 业务员
String NETWR = mainTable.get("NETWR"); // 订单金额
BigDecimal orderMoney = new BigDecimal(NETWR);
String ddh = mainTable.get("ddh"); // 订单号
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat inputDateFormat = new SimpleDateFormat("yyyyMMdd");
Date date = inputDateFormat.parse(ERDAT);
String orderCreatedTime = sdf.format(date);
Map<String, Object> toDmsBody = new HashMap<>();
toDmsBody.put("orderCode", ddh);
toDmsBody.put("bzirk", BZIRK);
toDmsBody.put("orderMoney", orderMoney);
toDmsBody.put("kunnr", KUNNR);
toDmsBody.put("orderCreatedTime", orderCreatedTime);
toDmsBody.put("salesman", KNRZA);
String createrId = String.valueOf(requestManager.getCreater());
// 获取人员信息,为的是获取DMS系统的 token
UserUtil creater = new UserUtil(Integer.parseInt(createrId));
String loginId = creater.getLoginid();
Map<String, String> dto = new HashMap<>();
String response = sendRequest(toDmsBody, dto, loginId);
// 构建日志对象,请求过后把日志存入表中,方便后期排查
logUtil.setRequest_url(API_ADDR);
logUtil.setRequestid(requestInfo.getRequestid());
logUtil.setUserid(loginId);
logUtil.setResponse(response);
logUtil.setParams(dto.toString());
if (!"true".equals(response.toString())){ // 调用dms失败
throw new RuntimeException(response);
}
logUtil.setStatus("true");
return Action.SUCCESS;
} catch (Exception e) {
logUtil.setStatus("false");
e.printStackTrace();
requestManager.setMessagecontent(e.toString());
return Action.FAILURE_AND_CONTINUE;
} finally {
logUtil.saveLog();
}
}
// 调用业务系统接口
private String sendRequest(Map<String, Object> toDmsBody, Map<String, String> dto, String loginId) {
// 获取oauth2 token
String token = "pre".equals(env) ? JwtClientAssertion.getToken(loginId, EnvConfig.getValue("oms.jwt.pre.address")) : JwtClientAssertion.getToken(loginId, EnvConfig.getValue("oms.jwt.test.address"));
String host = "pre".equals(env) ? EnvConfig.getValue("oms.pre.address") : EnvConfig.getValue("oms.test.address");
String result = HttpRequest.post(host + API_ADDR)
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + token)
.body(JSON.toJSONString(toDmsBody))
.execute().body();
return result;
}
}
此时流程归档就会触发。