企业⾃建应⽤审批接⼝开发
再说⼀次,企业开发⽂档很坑,特别坑,坑成⿁了。
有时候浪费很长时间改bug,查来查去,都没有发现到底哪⾥错了,查资料,搜资料,询问⼤神,都没有发现bug。改到最后都抑郁了,才发现⽤浏览器访问根本就不会报出具体的错误,pc端的企业客户端也不⾏,只有⽤⼿机上的企业客户端访问才会有具体的错误信息,在这⽅⾯浪费了很长时间,感觉⾃⼰有点傻,但是内⼼不承认。
总之,要想⼀帆风顺开发,听起来像是开玩笑,总会遇到让⾃⼰怀疑⼈⽣的bug。
⽂档对于很多细节描述不具体,⽽且也有很多东西没有demo可以参观,有demo的还是PHP,怎么说呢,有些东西想在⽹上查查,都查不到,所有,在开始之前,请让我先好好吐槽⼀下,以解我这⼏天的⼼头之⽕。
好吧,废话不多说,总不能转⾏吧!所以还是好好学习吧!!
企业⾃建应⽤审批接⼝开发:
⾃带有审批接⼝,最主要是,使⽤企业审批能⼒,在⾮审批应⽤内设置流程、发起审批。还能订阅通知消息,接收审批状态变化情况。
现在很多企业都使⽤企业审批接⼝,使⽤企业审批接⼝,审批发⽣变化,会⾃动发送消息给审批⼈以及抄送⼈,⽐较⽅便。⾃带的审批接⼝适⽤于⼩企业,简单的业务。⼀般⼤公司都会开发适⽤于⾃⼰企业的OA系统。
企业⾃建应⽤审批接⼝开发:
1.⾸先在企业后端,创建应⽤,进⼊审批接⼝,添加模板
2.⾃建应⽤发起审批
通过JS-SDK,可在⾃建应⽤中发起审批,需要设置可信域名,花⽣壳免费域名,我试了,不⾏!
3.设置⼯作台应⽤主页,在主页内发起审批
注意:
1.测试时⼀定要⽤⼿机企业客户端,会显⽰详细错误信息,⽤浏览器或者pc端,⽐较坑爹。
2.善于利⽤签名⼯具,验证⾃⼰各数据是否正确⽣成
1.⾸先在企业后端,创建应⽤,进⼊审批接⼝,添加模板
2.⾃建应⽤发起审批
点击接⼊流程说明,进⼊开发API
开发逻辑为上图所⽰
2.1
通过JS-SDK,可在⾃建应⽤中发起审批。查看JS-SDK调⽤详细说明
具体步骤:
1.通过config接⼝注⼊权限验证配置
2.通过agentConfig注⼊应⽤的权限
3.调⽤审批流程引擎JS-API
1.通过config接⼝注⼊权限验证配置
beta: true,// 必须这么写,否则wx.invoke调⽤形式的jsapi会有问题
debug: true, // 开启调试模式,调⽤的所有api的返回值会在客户端alert出来,若要查看传⼊的参数,可以在pc端打开,参数信息会通过log 打出,仅在pc端时才会打印。
appId: '', // 必填,企业的corpID
timestamp:'' , // 必填,⽣成签名的时间戳
nonceStr: '', // 必填,⽣成签名的随机串
signature: '',// 必填,签名,见附录-JS-SDK使⽤权限签名算法
jsApiList: ['agentConfig','thirdPartyOpenPage','selectExternalContact'] // 必填,需要使⽤的JS接⼝列表,凡是要调⽤的接⼝都需要传进来
});
2.通过agentConfig注⼊应⽤的权限。
wx.agentConfig({
corpid: '', // 必填,企业的corpid,必须与当前登录的企业⼀致
agentid: '', // 必填,企业的应⽤id
timestamp: , // 必填,⽣成签名的时间戳
nonceStr: '', // 必填,⽣成签名的随机串
signature: '',// 必填,签名,见附录1
jsApiList: ['thirdPartyOpenPage','selectExternalContact'], //必填
success: function(res) {
3.调⽤审批流程引擎JS-API
wx.invoke('thirdPartyOpenPage', {
"oaType": "10001",// String
"templateId": "46af67a118a6ebf000002",// String
"thirdNo": "thirdNo",// String
"extData": {
'fieldList': [{
'title': '采购类型',
'type': 'text',
'value': '市场活动',
},
{
'title': '订单链接',
'type': 'link',
'value': 'work.weixin.qq',
}],
}
},
function(res) {
// 输出接⼝的回调信息
console.log(res);
});
},
fail: function(res) {
Msg.indexOf('function not exist') > -1){
alert('版本过低请升级')
}
}
});
});
各个接⼝都调⽤成功的话,那么离成功就不远了;
2.1.jsp页⾯主要代码
<script type="text/javascript">
function approval() {
//动态获取当前页⾯url
var link = window.location.href;
$.ajax({
type:"GET",
data:{"url":link},
url:"<%=ContextPath()%>/approval/send_approval.do", dataType:"json",
success:function (data) {
console.log(data);
beta: true,
debug: true,
appId: data.appId,
timestamp: fig_timestamp,
nonceStr: fig_nonceStr,
signature: fig_signature,
jsApiList: ['agentConfig','openUserProfile','thirdPartyOpenPage','selectExternalContact']
主页壁纸怎么设置
alert("config");
wx.agentConfig({
corpid: data.appId,
agentid: data.agentid,
timestamp: data.agent_timestamp,
nonceStr: data.agent_nonceStr,
signature: data.agent_signature,
jsApiList: ['thirdPartyOpenPage','selectExternalContact'],
success: function(res) {
//审批流程js调⽤
alert("agentConfig");
wx.invoke('thirdPartyOpenPage', {
"oaType": data.oaType,
"templateId": plateId,
"thirdNo": data.thirdNo,
"extData": {
'fieldList': [{
'title': '采购类型',
'type': 'text',
'value': '市场活动',
},
{
'title': '订单链接',
'type': 'link',
'value': 'work.weixin.qq',
}],
}
},
function(res) {
/
/ 输出接⼝的回调信息
alert("thirdPartyOpenPage");
alert(res);
}
);
},
fail: function(res) {
alert("approval提交不通过");
alert("agentConfig:"+Msg);
Msg.indexOf('function not exist') > -1){
alert('版本过低请升级')
}
}
});
});
<(function(res){
});
}
})
}
</script>
2.2后端主要代码
@RequestMapping(value = "send_approval.do")
public void sendApproval(HttpServletRequest request, HttpServletResponse response,String url)throws Exception{ request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
JSONObject jsonObject = iApprovalService.approvalCreate(url).getData();
//返回数据到jsp页⾯
public JSONObject approvalCreate(String url){
JSONObject object = new JSONObject();
//agentConfig接⼝下主要数据
String approval_ticket = ApprovalTicket();
JSONObject appJSONObject = Signature(url,approval_ticket);
object.put("agent_nonceStr",("nonceStr").toString());
object.put("agent_timestamp",("timestamp").toString());
object.put("agent_signature",("signature").toString());
System.out.println("===============================");
System.out.String());
//config接⼝下主要数据
String ticket = JsApiTicket();
JSONObject jsonObject = Signature(url,ticket);
object.put("config_nonceStr",("nonceStr").toString());
object.put("config_timestamp",("timestamp").toString());
object.put("config_signature",("signature").toString());
System.out.println("===========================");
System.out.String());
//invoke接⼝下主要数据
object.put("thirdNo",String.valueOf(generateOrderNo()));
object.put("appId",Property("corpid"));
object.put("agentid",Property("mycreateapp_agentid"));
object.put("templateId",Property("approval_id"));
object.put("oaType","10001");
return object;
}
signatrue的⽣成
可以使⽤签名⼯具,查看⽣成的signatrue是否正确,可以快速的排除⾃⼰代码的错误
signature⽣成
签名算法
签名⽣成规则如下:
参与签名的参数有四个: noncestr(随机字符串), jsapi_ticket, timestamp(时间戳), url(当前⽹页的URL,不包含#及其后⾯部分)
将这些参数使⽤URL键值对的格式(即 key1=value1&key2=value2…)拼接成字符串string1。
有两个注意点:1. 字段值采⽤原始值,不要进⾏URL转义;2. 必须严格按照如下格式拼接,不可变动字段顺序。
jsapi_ticket=JSAPITICKET&noncestr=NONCESTR×tamp=TIMESTAMP&url=URL
然后对string1作sha1加密即可。
注意事项
签名⽤的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
签名⽤的url必须是调⽤JS接⼝页⾯的完整URL。
出于安全考虑,开发者必须在服务器端实现签名的逻辑。
public class JS_Util {
private static Logger logger = Logger(JS_Util.class);
//获取企业的jsapi_ticket
private final static String GET_WX_TICKET = "qyapi.weixin.qq/cgi-bin/get_jsapi_ticket?access_token=ACCESS_TOKEN"; //应⽤jsapi_tictet
private final static String GET_APP_TICKET = "qyapi.weixin.qq/cgi-bin/ticket/get?
access_token=ACCESS_TOKEN&type=agent_config";
//获取企业的ticket
public static String getJsApiTicket(){
String access_token =
JSONObject jsonObject = WeiXinUtil.httpRequest(url,"GET",null);
String ticket = ("ticket").toString();
return ticket;
}
//获取审批流程ticket
public static String getApprovalTicket(){
String access_token =
JSONObject jsonObject = WeiXinUtil.httpRequest(url,"GET",null);
String ticket = ("ticket").toString();
return ticket;
}
/**
* 参与签名的参数有四个: noncestr(随机字符串), jsapi_ticket, timestamp(时间戳), url(当前⽹页的URL,不包含#及其后⾯部分)* 将这些参数使⽤URL键值对的格式(即 key1=value1&key2=value2…)拼接成字符串string1。
* 然后对string1作sha1加密即可。
* @return
*/
public static JSONObject getSignature(String url,String ticket){
JSONObject jsonObject = new JSONObject();
String noncestr = getRandomString(16);
String timestamp = String(System.currentTimeMillis()).substring(0,10);
// jsapi_ticket=JSAPITICKET&noncestr=NONCESTR×tamp=TIMESTAMP&url=URL 顺序不能更改
String str = "jsapi_ticket="+ticket+
"&noncestr="+noncestr+
"×tamp="+timestamp+
"&url="+url;
String signature = SHA1(str);
jsonObject.put("nonceStr",noncestr);
jsonObject.put("timestamp",timestamp);
jsonObject.put("signature",signature);
jsonObject.put("ticket",ticket);
return jsonObject;
}
private static String SHA1(String decript){
try{
MessageDigest md = Instance("SHA-1");
md.Bytes());
byte[] digest = md.digest();
StringBuffer hexstr = new StringBuffer();
for (int i = 0; i < digest.length; i++) {