业务背景:公司目前的审批是走erp后台,然后还得走纸质的打印出来审批,影响效率,现在需要在企业微信直接提交申请单,然后审批,最后将审批数据同步到erp后台。
第一步:验证回调Url,在配置回调url时,企业微信后台需要验证,因此需要写一个回调验证接口
@GetMapping("/receiveData")
public void verifyURL(@RequestParam("msg_signature") String msgSignature,
@RequestParam("timestamp") Integer timestamp,
@RequestParam("nonce") String nonce,
@RequestParam("echostr") String echostr,HttpServletResponse response){
PrintWriter out=null;
try {
out = response.getWriter();
if(StringUtils.isNotEmpty(echostr)){
log.info("验证回调url有效性, 签名:{},时间戳:{},随机数:{},密文:{}", msgSignature,timestamp,nonce,echostr);
String sEchoStr=workWeiXinService.verifyURL(msgSignature,timestamp,nonce,echostr);
if(StringUtils.isNotEmpty(sEchoStr)){
out.write(sEchoStr);
out.flush();
}
}
} catch (IOException e) {
log.error("企业微信回调url验证错误",e.getMessage());
e.printStackTrace();
}finally {
out.close();
}
}
@Override
public String verifyURL(String msgSignature, Integer timestamp, String nonce, String echostr) {
String sEchoStr=null;
try {
WXBizJsonMsgCrypt wxBizJsonMsgCrypt = new WXBizJsonMsgCrypt(token, encodingAesKey, corpId);
sEchoStr = wxBizJsonMsgCrypt.VerifyURL(msgSignature, timestamp.toString(),
nonce, echostr);
log.info("verifyurl echostr:{}",sEchoStr);
} catch (Exception e) {
log.error("验证URL失败,错误原因请查看异常,{}",e.getMessage());
//验证URL失败,错误原因请查看异常
e.printStackTrace();
}
return sEchoStr;
}
第二步:给前端生成签名
@Override
public SignatureResponse getSignature(String url) {
String accessToken=getAccessToken();
String jsapiTicket=getJsapiTicket(accessToken);
String nonce=getNonce();
Long timeStamp=getTimeStamp();
String plainText= "jsapi_ticket=" + jsapiTicket +
"&noncestr=" + nonce +
"×tamp=" + timeStamp +
"&url=" + url;
String signature=null;
try{
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(plainText.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
SignatureResponse response=new SignatureResponse();
response.setSignature(signature);
response.setNonce(nonce);
response.setTimestamp(timeStamp);
response.setCorpId(corpId);
return response;
}catch (NoSuchAlgorithmException e){
e.printStackTrace();
}catch (UnsupportedEncodingException e){
e.printStackTrace();
}
return null;
}
private String getAccessToken() {
String reqAccessTokenUrl="https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid="+corpId+"&corpsecret="+corpSecret;
String reqAccessTokenResponse = HttpClient.sendGetRequest(reqAccessTokenUrl, Constants.ENCODE_UTF8);
String accessToken=null;
if(StringUtils.isNotEmpty(reqAccessTokenResponse)){
AccessTokenResponse accessTokenResponse = com.alibaba.fastjson.JSONObject.parseObject(reqAccessTokenResponse, AccessTokenResponse.class);
accessToken=accessTokenResponse.getAccess_token();
}
return accessToken;
}
private String getAccessToken() {
String reqAccessTokenUrl="https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid="+corpId+"&corpsecret="+corpSecret;
String reqAccessTokenResponse = HttpClient.sendGetRequest(reqAccessTokenUrl, Constants.ENCODE_UTF8);
String accessToken=null;
if(StringUtils.isNotEmpty(reqAccessTokenResponse)){
AccessTokenResponse accessTokenResponse = com.alibaba.fastjson.JSONObject.parseObject(reqAccessTokenResponse, AccessTokenResponse.class);
accessToken=accessTokenResponse.getAccess_token();
}
return accessToken;
}
private String getJsapiTicket(String accessToken) {
String reqJsapiTicketUrl="https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token="+accessToken;
String reqJsapiTicketResponse = HttpClient.sendGetRequest(reqJsapiTicketUrl, Constants.ENCODE_UTF8);
String jsapiTicket=null;
if(StringUtils.isNotEmpty(reqJsapiTicketResponse)){
JsapiTicketResponse response= com.alibaba.fastjson.JSONObject.parseObject(reqJsapiTicketResponse,JsapiTicketResponse.class);
jsapiTicket=response.getTicket();
}
log.info("accessToken:{},jsapiTicket:{}",accessToken,jsapiTicket);
return jsapiTicket;
}
private String byteToHex(byte[] hash) {
Formatter formatter = new Formatter();
for (byte b : hash)
{
formatter.format("%02x", b);
}
String result = formatter.toString();
formatter.close();
return result;
}
private Long getTimeStamp() {
return System.currentTimeMillis() / 1000;
}
private String getNonce() {
String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 16; i++) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
第三步:回调接口接受企业微信审批数据
@PostMapping("/receiveData")
public void receiveData(@RequestParam("msg_signature") String msgSignature,
@RequestParam("timestamp") Integer timestamp,
@RequestParam("nonce") String nonce,
@RequestBody(required=false) WorkWeiXinCallBack requestDto,HttpServletResponse response) {
log.info("回调接口接受企业微信审核数据信息, 信息:{}", JSONObject.toJSonString(requestDto));
workWeiXinService.receiveData(msgSignature,timestamp,nonce,requestDto);
PrintWriter out=null;
try {
out = response.getWriter();
out.write("SUCCESS");
out.flush();
}catch (IOException e) {
log.error("企业微信回调url验证错误",e.getMessage());
e.printStackTrace();
}finally {
out.close();
}
}
@Override
public void receiveData(String msgSignature,Integer timestamp,String nonce,WorkWeiXinCallBack requestDto) {
try {
WXBizJsonMsgCrypt wxBizJsonMsgCrypt = new WXBizJsonMsgCrypt(token, encodingAesKey, corpId);
String sReqData = com.alibaba.fastjson.JSONObject.toJSonString(requestDto);
String sMsg = wxBizJsonMsgCrypt.DecryptMsg(msgSignature, timestamp.toString(), nonce, sReqData);
log.info("after decrypt msg:{} ", sMsg);
JSonObject json = new JSonObject(sMsg);
String Content = json.getString("Content");
log.info("回调接口接受企业微信审核数据信息Content:{}",Content);
WorkWeiXinCallBackAuditInfo workWeiXinCallBackAuditInfo = com.alibaba.fastjson.JSONObject.parseObject(Content, WorkWeiXinCallBackAuditInfo.class);
//WorkWeiXinCallBackAuditInfo workWeiXinCallBackAuditInfo =(WorkWeiXinCallBackAuditInfo) JSON.parse(Content);
//申请单当前审批状态:1-审批中;2-已通过;3-已驳回;4-已撤销
if(workWeiXinCallBackAuditInfo.getApprovalInfo().getOpenSpStatus()!=2){
return;
}
String thirdNo = workWeiXinCallBackAuditInfo.getApprovalInfo().getThirdNo();
log.info("回调接口接受企业微信审核数据,审核订单号:{}",thirdNo);
//获取访问token
String accessToken=getAccessToken();
String reqApprovalInfoUrl="https://qyapi.weixin.qq.com/cgi-bin/oa/getapprovaldetail?access_token="+accessToken;
Map param=new HashMap<>();
param.put("sp_no",thirdNo);
Map result = HttpClient.sendPostRequestForJson(reqApprovalInfoUrl, param,Map.class);
if(result ==null || result.get("info") ==null){
return;
}
//-----------------------企业微信审核申请数据解析start-------------------------
String applyUserId = workWeiXinCallBackAuditInfo.getApprovalInfo().getApplyUserId();
String applyUserName = workWeiXinCallBackAuditInfo.getApprovalInfo().getApplyUserName();
Map info = (Map) result.get("info");
Map applyData = (Map) info.get("apply_data");
List
企业微信审批后 会自动回调企业服务器地址



