|
@ -1,29 +1,14 @@ |
|
|
package com.epmet.controller.dingtalk; |
|
|
package com.epmet.controller.dingtalk; |
|
|
|
|
|
|
|
|
import com.alibaba.fastjson.JSON; |
|
|
|
|
|
import com.alibaba.fastjson.JSONObject; |
|
|
|
|
|
import com.aliyun.dingtalk.util.DingCallbackCrypto; |
|
|
|
|
|
import com.epmet.commons.tools.constant.NumConstant; |
|
|
|
|
|
import com.epmet.commons.tools.dto.form.DingMiniInfoFormDTO; |
|
|
|
|
|
import com.epmet.commons.tools.redis.common.bean.DingMiniInfoCache; |
|
|
|
|
|
import com.epmet.commons.tools.utils.Result; |
|
|
|
|
|
import com.epmet.commons.tools.validator.ValidatorUtils; |
|
|
|
|
|
import com.epmet.dao.OpenSyncBizDataDao; |
|
|
import com.epmet.dao.OpenSyncBizDataDao; |
|
|
import com.epmet.dto.DingMiniInfoDTO; |
|
|
|
|
|
import com.epmet.dto.form.ExemptLoginUserDetailFormDTO; |
|
|
|
|
|
import com.epmet.entity.OpenSyncBizDataEntity; |
|
|
|
|
|
import com.epmet.redis.DingDingCallbackRedis; |
|
|
import com.epmet.redis.DingDingCallbackRedis; |
|
|
import com.epmet.service.DingTalkService; |
|
|
import com.epmet.service.DingTalkService; |
|
|
import com.epmet.service.OpenSyncBizDataService; |
|
|
import com.epmet.service.OpenSyncBizDataService; |
|
|
import org.apache.commons.collections4.CollectionUtils; |
|
|
|
|
|
import org.slf4j.Logger; |
|
|
import org.slf4j.Logger; |
|
|
import org.slf4j.LoggerFactory; |
|
|
import org.slf4j.LoggerFactory; |
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
import org.springframework.web.bind.annotation.*; |
|
|
import org.springframework.web.bind.annotation.RequestMapping; |
|
|
|
|
|
import org.springframework.web.bind.annotation.RestController; |
|
|
import java.util.ArrayList; |
|
|
|
|
|
import java.util.List; |
|
|
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* ISV 小程序回调信息处理 |
|
|
* ISV 小程序回调信息处理 |
|
@ -65,81 +50,81 @@ public class CallbackController { |
|
|
@Autowired |
|
|
@Autowired |
|
|
private DingTalkService dingTalkService; |
|
|
private DingTalkService dingTalkService; |
|
|
|
|
|
|
|
|
@PostMapping(value = "dingCallback") |
|
|
// @PostMapping(value = "dingCallback")
|
|
|
public Object dingCallback( |
|
|
// public Object dingCallback(
|
|
|
@RequestParam(value = "signature") String signature, |
|
|
// @RequestParam(value = "signature") String signature,
|
|
|
@RequestParam(value = "timestamp") Long timestamp, |
|
|
// @RequestParam(value = "timestamp") Long timestamp,
|
|
|
@RequestParam(value = "nonce") String nonce, |
|
|
// @RequestParam(value = "nonce") String nonce,
|
|
|
@RequestParam(value = "suiteKey") String suiteKey, |
|
|
// @RequestParam(value = "suiteKey") String suiteKey,
|
|
|
@RequestBody(required = false) JSONObject body |
|
|
// @RequestBody(required = false) JSONObject body
|
|
|
) { |
|
|
// ) {
|
|
|
String params = "signature:" + signature + " timestamp:" + timestamp + " nonce:" + nonce + " body:" + body + "suiteKey::"+suiteKey; |
|
|
// String params = "signature:" + signature + " timestamp:" + timestamp + " nonce:" + nonce + " body:" + body + "suiteKey::"+suiteKey;
|
|
|
try { |
|
|
// try {
|
|
|
log.info("begin callback:" + params); |
|
|
// log.info("begin callback:" + params);
|
|
|
DingMiniInfoDTO dingMiniInfo = openSyncBizDataDao.getDingMiniInfo(suiteKey); |
|
|
// DingMiniInfoDTO dingMiniInfo = openSyncBizDataDao.getDingMiniInfo(suiteKey);
|
|
|
DingCallbackCrypto dingTalkEncryptor = new DingCallbackCrypto(dingMiniInfo.getToken(), dingMiniInfo.getAesKey(), suiteKey); |
|
|
// DingCallbackCrypto dingTalkEncryptor = new DingCallbackCrypto(dingMiniInfo.getToken(), dingMiniInfo.getAesKey(), suiteKey);
|
|
|
|
|
|
//
|
|
|
// 从post请求的body中获取回调信息的加密数据进行解密处理
|
|
|
// // 从post请求的body中获取回调信息的加密数据进行解密处理
|
|
|
String encrypt = body.getString("encrypt"); |
|
|
// String encrypt = body.getString("encrypt");
|
|
|
String plainText = dingTalkEncryptor.getDecryptMsg(signature, timestamp.toString(), nonce, encrypt); |
|
|
// String plainText = dingTalkEncryptor.getDecryptMsg(signature, timestamp.toString(), nonce, encrypt);
|
|
|
JSONObject callBackContent = JSON.parseObject(plainText); |
|
|
// JSONObject callBackContent = JSON.parseObject(plainText);
|
|
|
|
|
|
//
|
|
|
log.info("推来的消息体:"+plainText); |
|
|
// log.info("推来的消息体:"+plainText);
|
|
|
|
|
|
//
|
|
|
// 根据回调事件类型做不同的业务处理
|
|
|
// // 根据回调事件类型做不同的业务处理
|
|
|
String eventType = callBackContent.getString("EventType"); |
|
|
// String eventType = callBackContent.getString("EventType");
|
|
|
if (EVENT_CHECK_CREATE_SUITE_URL.equals(eventType)) { |
|
|
// if (EVENT_CHECK_CREATE_SUITE_URL.equals(eventType)) {
|
|
|
log.info("验证新创建的回调URL有效性: " + plainText); |
|
|
// log.info("验证新创建的回调URL有效性: " + plainText);
|
|
|
} else if (EVENT_CHECK_UPADTE_SUITE_URL.equals(eventType)) { |
|
|
// } else if (EVENT_CHECK_UPADTE_SUITE_URL.equals(eventType)) {
|
|
|
log.info("验证更新回调URL有效性: " + plainText); |
|
|
// log.info("验证更新回调URL有效性: " + plainText);
|
|
|
} else if (EVENT_SUITE_TICKET.equals(eventType)) { |
|
|
// } else if (EVENT_SUITE_TICKET.equals(eventType)) {
|
|
|
// suite_ticket用于用签名形式生成accessToken(访问钉钉服务端的凭证),需要保存到应用的db。
|
|
|
// // suite_ticket用于用签名形式生成accessToken(访问钉钉服务端的凭证),需要保存到应用的db。
|
|
|
// 钉钉会定期向本callback url推送suite_ticket新值用以提升安全性。
|
|
|
// // 钉钉会定期向本callback url推送suite_ticket新值用以提升安全性。
|
|
|
// 应用在获取到新的时值时,保存db成功后,返回给钉钉success加密串(如本demo的return)
|
|
|
// // 应用在获取到新的时值时,保存db成功后,返回给钉钉success加密串(如本demo的return)
|
|
|
log.info("应用suite_ticket数据推送: " + plainText); |
|
|
// log.info("应用suite_ticket数据推送: " + plainText);
|
|
|
} else if (EVENT_TMP_AUTH_CODE.equals(eventType)) { |
|
|
// } else if (EVENT_TMP_AUTH_CODE.equals(eventType)) {
|
|
|
// 本事件应用应该异步进行授权开通企业的初始化,目的是尽最大努力快速返回给钉钉服务端。用以提升企业管理员开通应用体验
|
|
|
// // 本事件应用应该异步进行授权开通企业的初始化,目的是尽最大努力快速返回给钉钉服务端。用以提升企业管理员开通应用体验
|
|
|
// 即使本接口没有收到数据或者收到事件后处理初始化失败都可以后续再用户试用应用时从前端获取到corpId并拉取授权企业信息,进而初始化开通及企业。
|
|
|
// // 即使本接口没有收到数据或者收到事件后处理初始化失败都可以后续再用户试用应用时从前端获取到corpId并拉取授权企业信息,进而初始化开通及企业。
|
|
|
log.info("企业授权开通应用事件: " + plainText); |
|
|
// log.info("企业授权开通应用事件: " + plainText);
|
|
|
} else if (EVENT_SYNC_HTTP_PUSH_HIGH.equals(eventType)){ |
|
|
// } else if (EVENT_SYNC_HTTP_PUSH_HIGH.equals(eventType)){
|
|
|
List<Map<String, Object>> bizData = (List<Map<String, Object>>) callBackContent.get("bizData"); |
|
|
// List<Map<String, Object>> bizData = (List<Map<String, Object>>) callBackContent.get("bizData");
|
|
|
if (CollectionUtils.isNotEmpty(bizData)){ |
|
|
// if (CollectionUtils.isNotEmpty(bizData)){
|
|
|
List<OpenSyncBizDataEntity> list = new ArrayList<>(); |
|
|
// List<OpenSyncBizDataEntity> list = new ArrayList<>();
|
|
|
bizData.forEach(b -> { |
|
|
// bizData.forEach(b -> {
|
|
|
OpenSyncBizDataEntity e = new OpenSyncBizDataEntity(); |
|
|
// OpenSyncBizDataEntity e = new OpenSyncBizDataEntity();
|
|
|
e.setSuiteKey(suiteKey); |
|
|
// e.setSuiteKey(suiteKey);
|
|
|
e.setSubscribeId(b.get("subscribe_id").toString()); |
|
|
// e.setSubscribeId(b.get("subscribe_id").toString());
|
|
|
e.setCorpId(b.get("corp_id").toString()); |
|
|
// e.setCorpId(b.get("corp_id").toString());
|
|
|
e.setBizId(b.get("biz_id").toString()); |
|
|
// e.setBizId(b.get("biz_id").toString());
|
|
|
e.setBizData(b.get("biz_data").toString()); |
|
|
// e.setBizData(b.get("biz_data").toString());
|
|
|
e.setBizType(b.get("biz_type").toString()); |
|
|
// e.setBizType(b.get("biz_type").toString());
|
|
|
list.add(e); |
|
|
// list.add(e);
|
|
|
openSyncBizDataService.delete(e); |
|
|
// openSyncBizDataService.delete(e);
|
|
|
if (e.getBizType().equals(NumConstant.TWO_STR)){ |
|
|
// if (e.getBizType().equals(NumConstant.TWO_STR)){
|
|
|
Map<String,String> ticketMap = JSON.parseObject(e.getBizData(), Map.class); |
|
|
// Map<String,String> ticketMap = JSON.parseObject(e.getBizData(), Map.class);
|
|
|
dingCallbackRedis.set(suiteKey,ticketMap.get("suiteTicket")); |
|
|
// dingCallbackRedis.set(suiteKey,ticketMap.get("suiteTicket"));
|
|
|
} |
|
|
// }
|
|
|
}); |
|
|
// });
|
|
|
openSyncBizDataService.insertBatch(list); |
|
|
// openSyncBizDataService.insertBatch(list);
|
|
|
} |
|
|
// }
|
|
|
} else{ |
|
|
// } else{
|
|
|
// 其他类型事件处理
|
|
|
// // 其他类型事件处理
|
|
|
} |
|
|
// }
|
|
|
|
|
|
//
|
|
|
// 返回success的加密信息表示回调处理成功
|
|
|
// // 返回success的加密信息表示回调处理成功
|
|
|
return dingTalkEncryptor.getEncryptedMap("success", timestamp, nonce); |
|
|
// return dingTalkEncryptor.getEncryptedMap("success", timestamp, nonce);
|
|
|
} catch (Exception e) { |
|
|
// } catch (Exception e) {
|
|
|
//失败的情况,应用的开发者应该通过告警感知,并干预修复
|
|
|
// //失败的情况,应用的开发者应该通过告警感知,并干预修复
|
|
|
log.error("process callback fail." + params, e); |
|
|
// log.error("process callback fail." + params, e);
|
|
|
return "fail"; |
|
|
// return "fail";
|
|
|
} |
|
|
// }
|
|
|
} |
|
|
// }
|
|
|
|
|
|
|
|
|
@PostMapping("getExemptLoginUserDetail") |
|
|
// @PostMapping("getExemptLoginUserDetail")
|
|
|
public Result<Object> getExemptLoginUserDetail(@RequestBody ExemptLoginUserDetailFormDTO formDTO){ |
|
|
// public Result<Object> getExemptLoginUserDetail(@RequestBody ExemptLoginUserDetailFormDTO formDTO){
|
|
|
ValidatorUtils.validateEntity(formDTO, ExemptLoginUserDetailFormDTO.ExemptLoginUserDetailForm.class); |
|
|
// ValidatorUtils.validateEntity(formDTO, ExemptLoginUserDetailFormDTO.ExemptLoginUserDetailForm.class);
|
|
|
return new Result<Object>().ok(dingTalkService.getExemptLoginUserDetail(formDTO)); |
|
|
// return new Result<Object>().ok(dingTalkService.getExemptLoginUserDetail(formDTO));
|
|
|
} |
|
|
// }
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Desc: 获取钉钉小程序信息 |
|
|
* Desc: 获取钉钉小程序信息 |
|
@ -147,9 +132,9 @@ public class CallbackController { |
|
|
* @author zxc |
|
|
* @author zxc |
|
|
* @date 2022/9/15 10:46 |
|
|
* @date 2022/9/15 10:46 |
|
|
*/ |
|
|
*/ |
|
|
@PostMapping("getDingMiniInfo") |
|
|
// @PostMapping("getDingMiniInfo")
|
|
|
public Result<DingMiniInfoCache> getDingMiniInfo(@RequestBody DingMiniInfoFormDTO formDTO){ |
|
|
// public Result<DingMiniInfoCache> getDingMiniInfo(@RequestBody DingMiniInfoFormDTO formDTO){
|
|
|
ValidatorUtils.validateEntity(formDTO, DingMiniInfoFormDTO.DingMiniInfoForm.class); |
|
|
// ValidatorUtils.validateEntity(formDTO, DingMiniInfoFormDTO.DingMiniInfoForm.class);
|
|
|
return new Result<DingMiniInfoCache>().ok(dingTalkService.getDingMiniInfo(formDTO)); |
|
|
// return new Result<DingMiniInfoCache>().ok(dingTalkService.getDingMiniInfo(formDTO));
|
|
|
} |
|
|
// }
|
|
|
} |
|
|
} |
|
|