123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- package com.chinacreator.process.job;
- import com.chinacreator.common.exception.BusinessException;
- import com.chinacreator.common.util.DESUtil;
- import com.chinacreator.common.util.MD5;
- import com.chinacreator.process.dao.BackBusiVipAsynDao;
- import com.chinacreator.process.dao.DictionaryDao;
- import com.chinacreator.process.util.HttpInvoke;
- import com.chinacreator.process.util.JsonUtil;
- import com.chinacreator.process.util.URLUtil;
- import org.apache.log4j.Logger;
- import org.quartz.DisallowConcurrentExecution;
- import org.quartz.PersistJobDataAfterExecution;
- import org.springframework.beans.factory.annotation.Autowired;
- import java.net.URLEncoder;
- import java.text.SimpleDateFormat;
- import java.util.*;
- import java.util.concurrent.*;
- /**
- * 后向送会员异步处理
- * @author xu.zhou
- * @date 20200818
- */
- @PersistJobDataAfterExecution
- @DisallowConcurrentExecution
- public class BackBusiVipAsynJob {
- private static Logger logger = Logger.getLogger("backbusivipsyn");
-
- @Autowired
- private BackBusiVipAsynDao asyndao;
-
- @Autowired
- private DictionaryDao dictionaryDao;
-
- public void doProcess() throws Exception {
- String trycount = dictionaryDao.getValue("vipasyntrycount");//后向产品赠送会员异步处理重试次数
- if(trycount == null || "".equals(trycount)) trycount = "3";
- logger.info(Thread.currentThread().getName()+"定时任务开始");
- long beginTime = System.currentTimeMillis();
- List<HashMap> list = asyndao.getVipAsynData(trycount);
- if(list != null && list.size() > 0){
- //推送月份
- String pushmonth = new SimpleDateFormat("yyyyMM").format(new Date());
- CountDownLatch threadSignal = new CountDownLatch(list.size());
- ExecutorService executorService = new ThreadPoolExecutor(12, 16, 10L, TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>(), new ThreadPoolExecutor.CallerRunsPolicy());
- List<HashMap> dataList = paraseData(list);
- logger.info("数据库有效订购的用户数:"+dataList.size());
-
- for(HashMap vipmap : dataList){
- BackBusiVipSynService continueService = new BackBusiVipSynService(list.size(),threadSignal,vipmap,asyndao,dictionaryDao);
- executorService.execute(continueService);
- }
- executorService.shutdown();
- try {
- executorService.awaitTermination(5L, TimeUnit.MINUTES);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- logger.info(Thread.currentThread().getName()+"定时任务完成,耗时:"+(System.currentTimeMillis()-beginTime)/1000+" 秒");
- }
-
- /**
- * 去除重复数据,防止赠送会员接口被并发限制
- * @param dataList
- * @return
- */
- private List<HashMap> paraseData(List<HashMap> dataList){
- //去重复后的数据集
- List<HashMap> reDataList = new ArrayList<HashMap>();
- HashMap<String, List> tmpMap = new HashMap<String, List>();
- for (HashMap dataMap : dataList) {
- if(tmpMap.containsKey(dataMap.get("USERID").toString()+dataMap.get("CPID")+dataMap.get("SPID"))){
- logger.info("重复数据,"+dataMap.get("USERID")+dataMap.get("CPID")+dataMap.get("SPID"));
- }else{
- reDataList.add(dataMap);
- List tmpList = new ArrayList();
- tmpList.add(dataMap.get("SPID"));
- tmpMap.put(dataMap.get("USERID").toString()+dataMap.get("CPID")+dataMap.get("SPID"), tmpList);
- }
- }
- return reDataList;
- }
- }
- class BackBusiVipSynService implements Runnable {
- private static Logger log = Logger.getLogger("backbusivipsyn");
- private int totalSize;
- private CountDownLatch threadSignal;
- private HashMap vipmap;
- private DictionaryDao dictionaryDao;
- private BackBusiVipAsynDao asyndao;
-
- public BackBusiVipSynService(int totalSize,CountDownLatch threadSignal,HashMap vipmap,BackBusiVipAsynDao asyndao,DictionaryDao dictionaryDao){
- this.totalSize = totalSize;
- this.threadSignal = threadSignal;
- this.vipmap = vipmap;
- this.asyndao = asyndao;
- this.dictionaryDao = dictionaryDao;
- }
-
- @Override
- public void run() {
- long startime = System.currentTimeMillis();
- Map logMap = new HashMap();
- String id = vipmap.get("ID").toString();
- logMap.put("vipmap", vipmap);
- String resultcode = "-1";
- String errorinfo = "";
- String vipsendcode = "3"; //赠送会员结果标识,默认为失败
- try {
- //更新为正在赠送状态
- asyndao.updVipSendStatus(id);
- HashMap<String, String> remap = sendVip();
- if("0".equals(remap.get("vipsendcode"))){
- resultcode = "0";
- vipsendcode = "0";
- errorinfo = "赠送成功";
- }else{
- resultcode = remap.get("vipsendcode");
- errorinfo = remap.get("vipsendinfo");
- }
- } catch (Exception e) {
- if (e instanceof BusinessException) {
- errorinfo = ((BusinessException) e).getMessage();
- resultcode = ((BusinessException) e).getCode();
- }else{
- e.printStackTrace();
- resultcode = "8000";
- errorinfo = "处理数据出现异常,"+e.getMessage();
- }
- }finally {
- threadSignal.countDown();
- String time = System.currentTimeMillis()-startime+"";
- try{
- //更新赠送会员结果出现异常
- asyndao.updVipSendStatus(id, vipsendcode, time);
- }catch(Exception e){
- log.error(vipmap.get("USERID")+"更新赠送会员结果出现异常,"+e.getMessage());
- }
- //回调
- callBack(resultcode, errorinfo);
- //发送成功短信
- inserSmstMq(resultcode);
- //写日志
- logMap.put("resultcode", resultcode);
- logMap.put("errorinfo", errorinfo);
- logMap.put("time", time);
- logMap.put("count", totalSize+"/"+(totalSize - threadSignal.getCount()));
- log.info(JsonUtil.objectToJson(logMap));
- }
- }
-
- /**
- * 推送办理成功的短信到队列
- * @param orderInfo
- */
- private void inserSmstMq(String resultcode){
- try{
- //赠送成功才发短信
- if(!"0".equals(resultcode)) return;
-
- String userid = vipmap.get("USERID").toString();
- if(userid == null || userid.length() != 11) return;
- String channel = vipmap.get("CHANNEL").toString();
- String cpid = vipmap.get("CPID").toString();
- String spid = vipmap.get("SPID").toString();
- Map<String, String> map = new HashMap<String, String>();
- map.put("userid", userid);
- map.put("cpid", cpid);
- map.put("spid", spid);
- map.put("result", "0");
- map.put("channel", "");
- map.put("style","0000");
- map.put("times", "");
- map.put("orderType", "");
- map.put("type", "cssms");
- map.put("busiType", "tran_succ"); //订购成功短信
- if("TX20_twback_qc".equals(channel)){//女王卡领取会员发短信,同样的SPID短信内容不同
- map.put("busiType", "qc_tran_succ");
- }
- String mqReciveUrl = dictionaryDao.getValue("mqReciveUrl");
- URLUtil.post(mqReciveUrl, JsonUtil.objectToJson(map));
-
- //部分业务要发三条短信
- if(!"TX20_twback_qc".equals(channel)){
- map.put("busiType", "tran_succ2"); //订购成功短信
- }
- URLUtil.post(mqReciveUrl, JsonUtil.objectToJson(map));
-
- if(!"TX20_twback_qc".equals(channel)){
- map.put("busiType", "tran_succ3"); //订购成功短信
- }
- URLUtil.post(mqReciveUrl, JsonUtil.objectToJson(map));
- }catch (Exception e){
- e.printStackTrace();
- log.info(vipmap.get("ID")+",发送成功短信失败");
- }
- }
-
- /**
- * 调接口送会员
- * @param orderInfo
- * @return
- * @throws Exception
- */
- private HashMap<String, String> sendVip() throws Exception{
- HashMap<String, String> remap = new HashMap<String, String>();
- String vipsendcode = "3"; //默认失败
- String vipsendinfo = "赠送失败";
- try {
- //http://114.255.201.228:86/activity/youkuHX
- String vipurl = this.dictionaryDao.getValue("backBusiVipUrl");
- String timestamp = (System.currentTimeMillis() / 1000) + "";
- String userid = vipmap.get("USERID").toString();
- String orderid = vipmap.get("ORDERID").toString();
- String channel = vipmap.get("CHANNEL").toString();
- String cpid = vipmap.get("CPID").toString();
- String spid = vipmap.get("SPID").toString();
- String pwd = "";
- List<HashMap> confList = asyndao.getBackBusiConf(cpid, spid);
- pwd = confList.get(0).get("PWD").toString();
- if("0".equals(confList.get(0).get("HASFH"))){ //是复合产品
- vipurl = this.dictionaryDao.getValue("backBusiGroupVipUrl");
- }
- userid = DESUtil.encode(userid, pwd);
- //MD5(orderid+userid+goodscode+pwd+timestamp)转换为十六进制ASCII 码字符串,共32 个字符,全小写 userid= Des(手机号码,pwd)
- //MD5(orderid+userid+timestamp+pwd)转换为十六进制ASCII 码字符串,共32 个字符,全小写
- String signature = MD5.MD5Encode(orderid + userid + timestamp + pwd);
- signature = signature.toLowerCase();
- vipurl = vipurl + "?userid=" + URLEncoder.encode(userid, "utf-8")+ "&orderid="+ orderid + "&cpid=" + cpid + "&spid=" + spid + "×tamp="
- + timestamp + "&signature=" + signature+ "&apptype=2";
- log.info("vipurl: "+vipurl);
- //http://114.255.201.228:86/activity/eshop/vip?userid=iafPbU9aRLghY%2FEVMXFeag%3D%3D&orderid=201906231206498662914&goodscode=pointshop130×tamp=1561445765&signature=47fe0e3900b29ef88fd0889b7c0e4cc6&apptype=5
- String result = URLUtil.get(vipurl,30*1000); //调赠送会员接口,超时时间设置为10秒
- log.info("赠送会员重试结果=> userid: " +userid+", orderid: "+orderid+" , result: "+result);
- Map<?,?> map = JsonUtil.jsonToMap(result);
- //resultcode = (String)map.get("resultcode");
- // if("0".equals(map.get("resultcode"))){
- // vipsendcode = "0";
- // }
- vipsendcode = map.get("resultcode")+"";
- vipsendinfo = map.get("errorinfo")+"";
- } catch (Exception e) {
- e.printStackTrace();
- log.error("userid: "+vipmap.get("USERID")+"赠送会员失败,"+e);
- if(e.getMessage() != null && e.getMessage().indexOf("TimeoutException") != -1){//超时异常
- throw new BusinessException("9070","赠送会员超时", new String[0]);
- }else{
- throw new BusinessException("9002","赠送会员未成功", new String[0]);
- }
- }
-
- remap.put("vipsendcode", vipsendcode);
- remap.put("vipsendinfo", vipsendinfo);
-
- return remap;
- }
-
- /**
- * 回调通知
- * @param orderBean
- * @return 0成功,1未回调,2出现异常
- */
- private String callBack(String resultcode, String resultinfo){
- String res = "1";
- try {
- String trycountconf = dictionaryDao.getValue("vipasyntrycount");
- String trycount = vipmap.get("RETRYCOUNT").toString();
- String userid = vipmap.get("USERID").toString();
- String orderid = vipmap.get("ORDERID").toString();
- String channel = vipmap.get("CHANNEL").toString();
- String id = vipmap.get("ID").toString();
- //判断重试是否已是最大次数
- if(!"0".equals(resultcode) && Integer.parseInt(trycount)+1 < Integer.parseInt(trycountconf)){
- return null;
- }
- //当会员赠送失败时,反查一下会员赠送日志表,看是否真的赠送失败,防止调接口超时获取不到真实赠送结果
- if(!"0".equals(resultcode)){
- if(asyndao.getVipSendRes(orderid)){
- resultcode = "0";
- resultinfo = "OK";
- }
- }
- HashMap channelInfo = asyndao.getChannelPwdByChannel(channel);
- String pwd = channelInfo.get("PASSWORD")+"";
- userid = DESUtil.encode(userid, pwd);
- userid = URLEncoder.encode(userid, "utf-8");
- String vipRetryCallBackUrl = this.dictionaryDao.getValue("vipRetryCallBackUrl");//回调接口地址
- vipRetryCallBackUrl += "?orderid="+orderid+"&resultcode="+resultcode+"&resultinfo="+URLEncoder.encode(resultinfo,"utf-8")+"&userid="+userid;
- log.info("===========回调地址:"+vipRetryCallBackUrl);
- String result = HttpInvoke.sendhttpsReq("GET", vipRetryCallBackUrl, "", null, 60*1000, "TLSv1.2");
- //String result = URLUtil.get(vipRetryCallBackUrl,60*1000); //调赠送会员接口,超时时间设置为10秒
- log.info("回调通知接口返回信息=>userid: " +userid+", orderid: "+orderid+", result: "+result);
- Map<?,?> map = JsonUtil.jsonToMap(result);
- res = (String)map.get("result");
- } catch (Exception e) {
- res = "2";
- e.printStackTrace();
- log.error("id=>"+vipmap.get("ID")+",回调接口出现异常,"+e.getMessage());
- }
- return res;
- }
- }
|