ERP集成平台产品手册

版本 作者 日期 说明
v1.0 刘登跃 20210218
v1.1 冯远华 20210414 修复目录跳转问题
v1.2 郑素兰 20210420 增加了配置demo的步骤

目录

[TOC]

一.对接OA设置

1 第一步 购买集成平台OA插件

找到对应的产品,下订单进行购买,则配置入口自动开通。 配置入口在 管理->系统对接管理 下面。

image-20210517162346658

2 第二步 账户绑定

进入集成平台-OA代办 ->账户绑定,可通过新建或导入将纷享员工与OA员工进行绑定

image-20210518162311976

3 第三步 发送消息到OA接口配置

提交普通审批,审批内容格式如下:

#crm代办灰度申请
麻烦开发同学配置CRM代办灰度
企业账号EA:xxxxxx
服务group:erpdss

审批人顺序:刘登跃、柯南颖、梁岩超

确认客户的接口调用方式,webservice和restful两种不同的调用方式在配置上稍微有些不同,下面的配置文档中将会对有区别的地方分别写清楚该如何配置;

3.1 通用参数配置

进入集成平台-OA代办 ->初始设置 ->通用参数配置,分为Headers参数设置和结果格式设置

image-20210518145904012

(1)Headers参数设置根据客户需求,自行增加。点击添加一行输入key和value,点击保存即可添加成功

image-20210518150130527

(2)结果格式设置中key已预置,value需根据客户接口调用的返回结果自行添加

image-20210518153813993

  • codeName:填写返回结果中的code字段名

  • msgName:填写返回结果中message信息的字段名

  • dataName:默认不填写

  • successCode:填写调用成功的code值

  • xmlJsonField: webservice接口调用方式默认填写out,restful接口调用方式默认不填写

    示例:如下图所示的返回结果,codeName填写code,msgName填写message,successCode填写0

    image-20210519192110405

3.2 场景参数设置

(1)进入集成平台-OA代办 ->初始设置 ->场景参数设置,可根据客户需求开启相应场景并进行配置。开启则推送相应的代办消息操作到OA系统,关闭则不会

image-20210518154123719

(2)下面以新增代办为例来进行配置讲解,点击新增代办的【设置】,进入新增代办设置页面

image-20210526155247564

  • 接口地址设置:配置OA系统新增代办的接口调用地址
  • 接口类型:配置调用接口的请求方法
  • Body参数设置: 配置调用接口需传递的参数,参数值填写对接CRM代办的字段,注意需填写以#开头的占位符,CRM代办字段及占位符可在右侧进行搜索。注意webservice接口调用方式,Body参数需为xml格式;restful接口调用方式,Body参数需为json格式
  • 编辑代办、删除代办根据客户接口文档相应更换接口地址、接口类型、Body参数设置

(3)新增代办配置示例

假设以下为客户给出的接口调用文档

  1. 请求方式: POST
  2. 请求地址:http://test.com.cn:909/rest/transmit/fxiaoke/create
  3. 请求参数:

image-20210519195355078

image-20210519195425550

按照以上给出的接口文档,则接口地址设置填写:http://test.com.cn:909/rest/transmit/fxiaoke/create,接口类型选择POST

Body参数填写给出的Post内容(如果客户接口是webservice调用方式,则需转换为xml格式),左边字段不变,把右边的值填写对应要映射的CRM字段-用占位符,则填写完后如下图所示

image-20210526155247564

4 第四步 验证OA消息推送接口

在纷享系统新增、编辑、删除代办消息后,查看同步记录,并在OA查看代办是否推送成功

image-20210518163028461

5 第五步 免登录对接

CRM的代办消息推送到OA以后,用户从OA点击消息,要能免登录到CRM。

根据不同厂商有不同的操作:

5.1 致远OA

致远OA认证方式选择:

应用注册:

image-20210729154802276

产品登记:

image-20210729154919732

在【应用对接】找到对应应用:

image-20210729155047971

配置用户绑定:

image-20210729155116373

待办集成:

image-20210729155134113

做完上述操作后,需要客户提供应用账号密码。

一、待办消息推送

使用致远OA里面的V5auth认证方式:

致远OA系统,推送待办需要先获取他们系统的token。需要让客户在致远OA系统上创建一个纷享的应用,并且提供对应的账号密码。每次调用接口的时候,需要在请求头拼接token。

OA平台有根据脚本生成url的功能,需要编写脚本获取带token的地址。

脚本模板:

import groovy.json.JsonSlurper
import [sun.net](http: //sun.net/).www.protocol.https.DelegateHttpsURLConnection

import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec

public String getToken() {
    String token = null;
    String userName = \"****\";       // 填写客户提供的账号
    String password = \"**********************\";   // 填写客户提供的密码
    String requestUrl = \"http://**********/seeyon/rest/token/\" + userName + \"/\" + password;  // 修改请求地址
    HttpURLConnection connection = (HttpURLConnection) new URL(requestUrl).openConnection();
    connection.setRequestMethod(\"GET\");
            // 设置连接主机服务器的超时时间:15000毫秒
            connection.setConnectTimeout(15000); connection.setUseCaches(false); connection.setRequestProperty(\"Content-Type\", \"text/xml; charset=UTF-8\");
                // 设置读取远程返回的数据时间:60000毫秒
                connection.setReadTimeout(60000); connection.setDoOutput(true); connection.setDoInput(true); connection.connect(); int code = connection.getResponseCode();
                if (code == 200) {
                    InputStream inputStream = connection.getInputStream();
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                    String line;
                    StringBuffer buffer = new StringBuffer();
                    while ((line = bufferedReader.readLine()) != null) {
                        buffer.append(line);
                    }
                    String str = buffer.toString();
                    def jsonSlurper = new JsonSlurper()
                    Map map = jsonSlurper.parseText(str)
                    token = map.get(\"id\")
                    }
                    else {
                        throw new RuntimeException(\"握手异常(\" + connection.getResponseCode() + \")!\" + connection.getResponseMessage())
                        }
                        return url + \"?token=\" + token;
                    }
                    url = getToken();
                    return url;

二、单点登录

image-20210729154828067

单点登录通过致远OA的门户认证机制认证。OA平台对外开放致远OA免登录接口:/authorizeWeb/SeeYon/{apiName}/{dataId}/{ei}/{isApp}

OA那边通过点击待办,或者纷享应用。会携带token给平台,平台通过拿到的token再去调用OA的门户认证接口,获取当前用户。最后重定向到

这个用户免登录的页面。

三、致远OA待办跳转CRM待办和跳转CRM主页面

单点登录成功后,可以获取到对应的用户信息。通过CRM的免登录接口,重定向到对应的页面。

跳转CRM待办接口:/authorizeWeb/SeeYon/{apiName}/{dataId}/{ei}/{isApp}

跳转CRM主页面接口:/authorizeWeb/SeeYon/login/{ei}/{isApp}

参考:

image-20210729155738164

{ "registerCode": "3004", "taskId": "#F012", "title": "#F054 #F056 #F053", "senderName": "#F054", "state": "0", "thirdSenderId": "#F049", "thirdReceiverId": "#F001", "creationDate": "#F009", "content": "", "h5url": "https://www.fxiaoke.com/erp/syncdata/open/oa/authorizeWeb/SeeYon/#F037/#F015/714439/true", "url": "https://www.fxiaoke.com/erp/syncdata/open/oa/authorizeWeb/SeeYon/#F037/#F015/714439/false", "noneBindingSender":"", "noneBindingReceiver":"#F001" }

5.2 泛微OA:

范围OA目前实现上有两种方式:

方案一:OA侧通过open api做免登

image-20210729155738164

1.提交审批,审批内容模板如下

#开通单点登录接口#
申请原因:客户**(eg:泛微OA)对接纷享,客户那边用openApi调用接口方式开发单点登路
客户:***(客户名称)
企业账号:***(企业账号)
审批人:刘登跃、钟兴、蒋小川

如何使用纷享openapi参考该文档: http://open.fxiaoke.com/wiki.html#artiId=215

2.通过纷享openapi实现免登进入CRM代办链接的时序图:

​ 跳转链接是有openapi的免登链接+OA消息跳转链接拼接而成:e.g:https://www.fxiaoke.com/FHH/EM0HXUL/SSO/Login?token=b772184123ec43b6a1fd1351be6f418e&source=跳转页面的url(注意跳转的url需要经过UrlEncode处理)

image-20210729155738164

3.参考代码示例:

package com.fxiaoke.open.oasyncdata.example;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.fxiaoke.open.erpsyncdata.apiproxy.manager.ProxyHttpClient;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @Author keny
 * @Date 2021/11/10 14:50 通过open api免登录纷享代办页面
 * @Version 1.0
   */
   @Service
   @Slf4j
   public class SSOLoginOASerivce {

   public static String domainUrl = "https://open.fxiaoke.com%s";
   public static String GET_ACCESS_TOKEN_UTL = "/cgi/corpAccessToken/get/V2";
   public static String SSO_LOGIN_URL = "/cgi/sso/loginurl/get";
   public static String APP_ID = "FSAID_13147c8";
   public static String APP_SECRET = "ea1fab3238484a918720680868657e5f";
   public static String PERMANENT_CODE = "8865799413C5221F03E665401C466A0F";
   //以上三个参数,参考openapi获取参数链接https://open.fxiaoke.com/wiki.html#artiId=1120
   public static String NONCE = "MT1ZFIFlPVSDmiJH"; //自定义 ,一分钟内不要重复

   @Autowired
   private ProxyHttpClient proxyHttpClient; //替换自己使用的http组件

   /**
    * 建议缓存 expireTime=7200s
    *
    * @return
    */
      public Map < String, String > getAccessToken() {

      String finalAccessTokenUrl = String.format(domainUrl, GET_ACCESS_TOKEN_UTL);
      Map < String, Object > paramsMap = Maps.newHashMap();
      paramsMap.put("appId", APP_ID);
      paramsMap.put("appSecret", APP_SECRET);
      paramsMap.put("permanentCode", PERMANENT_CODE);
      String result = proxyHttpClient.postUrl(finalAccessTokenUrl, paramsMap, Maps.newHashMap());
      Map < String, String > resultMap = JSONObject.parseObject(result, new TypeReference < Map > () {});
      return resultMap;
      }

   /**
    * 通过openapi获取免登token
    * @param account 三种传值方式
    *account的类型,当前支持三种类型:
    * 1 代表手机号
    * 2 代表纷享登录账号
    * 3 代表OpenUserId
    */
      public String skipLogin(String accessToken, String corpId, String account) {
      String finalLoginUrl = String.format(domainUrl, SSO_LOGIN_URL);
      Long timeStamp = System.currentTimeMillis();
      Map < String, Object > paramsMap = Maps.newHashMap();
      //生成鉴权
      String signature = generateSignature(accessToken, corpId, timeStamp.toString(), NONCE, empId.toString(), String.valueOf(2), APP_SECRET);
      paramsMap.put("corpAccessToken", accessToken);
      paramsMap.put("corpId", corpId);
      paramsMap.put("timestamp", timeStamp);
      paramsMap.put("nonce", NONCE);
      paramsMap.put("account", account);
      paramsMap.put("type", 2);
      paramsMap.put("signature", signature);
      String result = proxyHttpClient.postUrl(finalLoginUrl, paramsMap, Maps.newHashMap());
      Map < String, String > resultMap = JSONObject.parseObject(result, new TypeReference < Map > () {});
      return resultMap.get("loginUrl");
      }

   /**
    * 生成signature
    * 签名字符串,用来防篡改。签名规则为:
    * 1.首先将corpAccessToken、corpId、timestamp、nonce、account、type字段值以及appSecret(自建应用-开发者模式中可以查看)按照字符串值进行自然序排序。
    * 2.将排序后的字符串进行拼接。
    * 3.将拼接后的字符串进行SHA1计算进行16进制编码后获取签名。
    * @param  account 需要OA系统传递当前点击的用户在纷享的手机号码
    */
      public String generateSignature(String corpAccessToken, String corpId, String timestamp, String nonce, String account, String type, String appSecret) {
      List < String > params = Lists.newArrayList(corpAccessToken, corpId, timestamp, nonce, account, type, appSecret);

      //
      Collections.sort(params);
      String result = DigestUtils.shaHex(Joiner.on(StringUtils.EMPTY).join(params));
      return result;
      }

/**
 * 拼接详情的免登地址
 */
public String concatDetailUrl(String tokenUrl, String crmDetailUrl) {
    StringBuilder redirectUrl = null;
    try {
        redirectUrl = new StringBuilder().append(tokenUrl).append("&source=").append(URLEncoder.encode(crmDetailUrl, "UTF-8"));
        return redirectUrl.toString();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return StringUtils.EMPTY;
}
}

单测代码:

@Test
public void createSSOurl() {
    Map < String, String > getToken = ssoLoginOA.getAccessToken();
    String login = ssoLoginOA.skipLogin(getToken.get("corpAccessToken"), getToken.get("corpId"), "15816853xx1");
    String concatDetailUrl = ssoLoginOA.concatDetailUrl(login, "https://www.ceshi112.com/XV/Home/Index#crm/list/=/AccountObj"); //最终跳转的地址
}

方案二:OA侧提供身份验证接口,crm做免登

image-20210729155738164

客户在OA系统点击代办的链接的时候,在url携带额外对应的参数,纷享做对应的鉴权,鉴权通过则免登进入对应的详情页面

额外参数 参数说明 备注
loginid OA员工ID
stamp 时间戳
token sha加密后的结果 加密方式参数下列代码
secret 双方约定的密钥 纷享开发提供
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Sha1Util {
public static String getSha1(byte[] input) throws NoSuchAlgorithmException {
    MessageDigest mDigest = MessageDigest.getInstance("SHA1");
    byte[] result = mDigest.digest(input);
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < result.length; i++) {
        sb.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1));
    }
    return sb.toString();
}

/**
 * 示例加密过程
 * @param args
 */
public static void main(String[] args) {
    String secret = "d73ec6289574d272c9cc2df5ff70488b";
    String loginid = "0001";
    String stamp = "1634128095994";
    String encryptValue = secret + loginid + stamp;
    try {
        String getData = Sha1Util.getSha1(encryptValue.getBytes());
        System.out.println(getData);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
}
}

5.3 蓝凌OA:

联系集成开发沟通获取身份接口。

5.4 云之家OA:

依赖云之家的openapi接口,erp-oa可以针对云之家的客户统一做免登的操作:

1.客户需要提供对应的云之家的appid,appsecret给开发(柯南颖)配置,详情参看https://open.yunzhijia.com/opendocs/docs.html#/guide/lightapp/create

2.客户按照OA手册配置完后,目前需要提供审批让开发针对企业灰度代办推送

3.在推送云之家中需要填写url的参数:可以参考:

https://www.fxiaoke.com/erp/syncdata/open/oa/authorizeWeb/webhook/{占位符:流程apiname}/{占位符:发起流程数据ID}/{占位符 tenantId}

eg: https://www.fxiaoke.com/erp/syncdata/open/oa/authorizeWeb/webhook/#F037/#F015/#F028

5.5 其它OA:

联系集成开发沟通获取身份接口。

results matching ""

    No results matching ""