package com.chinacreator.process.job; import java.net.URLEncoder; import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.apache.log4j.Logger; import org.quartz.DisallowConcurrentExecution; import org.quartz.PersistJobDataAfterExecution; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.chinacreator.common.exception.BusinessException; import com.chinacreator.common.util.DESUtil; import com.chinacreator.process.bean.KuaishouPushBean; import com.chinacreator.process.dao.DictionaryDao; import com.chinacreator.process.dao.KuaishouDao; import com.chinacreator.process.dao.VipSmsSpidSendDao; import com.chinacreator.process.util.JsonUtil; import com.chinacreator.process.util.SHAUtil; import com.chinacreator.process.util.URLUtil; import com.chinacreator.process.util.WriteLogUtil; /** * 手动领取会员短信发送 * 每10分钟执行一次 * @author xu.zhou * @date 20220407 */ @PersistJobDataAfterExecution @DisallowConcurrentExecution public class VipSmsSpidSendJob { private static Logger logger = Logger.getLogger("vipSmsSpidSend"); @Autowired private VipSmsSpidSendDao vipSmsSpidSendDao; // = new VipSmsSpidSendDao(); @Autowired private DictionaryDao dictionaryDao; // = new DictionaryDao(); public void doProcess() throws Exception { //System.out.println("VipSmsSpidSendJob定时任务开始"+new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())); WriteLogUtil.writeLong("VipSmsSpidSendJob定时任务开始", logger, "VipSmsSpidSendJob"); int count = 0; long beginTime = System.currentTimeMillis(); //当前月份 String currmonth = new SimpleDateFormat("yyyyMM").format(new Date()); int rows = 800; //每次取数据条数 //获取字典表的配置 String confrows = dictionaryDao.getValue("vipSmsSpidSendrows"); if (!StringUtils.isEmpty(confrows)) { try { rows = Integer.parseInt(confrows); } catch (Exception e) { rows = 800; } } //采集表分区标识,分区标识从T_HASH_P01到T_HASH_P50 String partition = "T_HASH_P"; for(int i = 1; i <= 50; i++){ count = 0; partition = "T_HASH_P"; try { if(i < 10){ partition = partition + "0" + i; }else{ partition = partition + i; } //按分区标识获取订购数据 List dataList = vipSmsSpidSendDao.getDataByPart(partition,rows, currmonth); count = (dataList != null ? dataList.size() : 0); logger.info(partition+",用户数:"+(dataList != null ? dataList.size() : "0")); if(dataList != null && dataList.size() > 0){ CountDownLatch threadSignal = new CountDownLatch(dataList.size()); ExecutorService executorService = new ThreadPoolExecutor(10, 20, 10L, TimeUnit.MINUTES, new LinkedBlockingQueue(), new ThreadPoolExecutor.CallerRunsPolicy()); //把数据更新为正在处理状态 for(HashMap hm : dataList){ boolean res = vipSmsSpidSendDao.updExecing(hm.get("ID").toString()); } for(HashMap hm : dataList){ VipSmsSpidSendService continueService = new VipSmsSpidSendService(dataList.size(),threadSignal,hm,currmonth,vipSmsSpidSendDao,dictionaryDao); executorService.execute(continueService); } executorService.shutdown(); try { executorService.awaitTermination(5L, TimeUnit.MINUTES); } catch (InterruptedException e) { e.printStackTrace(); } } } catch (Exception e) { logger.info(partition+",执行出现异常,"+e.getMessage()); e.printStackTrace(); } Thread.sleep(100); } WriteLogUtil.writeLong("VipSmsSpidSendJob定时任务完成,耗时:"+(System.currentTimeMillis()-beginTime)/1000+" 秒", logger, "VipSmsSpidSendJob"); } public static void main(String[] args) { VipSmsSpidSendJob job = new VipSmsSpidSendJob(); try { job.doProcess(); } catch (Exception e) { e.printStackTrace(); } } } class VipSmsSpidSendService implements Runnable { private static Logger logger = Logger.getLogger("vipSmsSpidSend"); private int totalSize; private CountDownLatch threadSignal; private List spidsList; private String currmonth; private VipSmsSpidSendDao vipSmsSpidSendDao; private HashMap hm; private DictionaryDao dictionaryDao; public VipSmsSpidSendService(int _totalSize,CountDownLatch _threadSignal,HashMap _hm,String _currmonth, VipSmsSpidSendDao _vipSmsSpidSendDao, DictionaryDao _dictionaryDao){ this.totalSize = _totalSize; this.threadSignal = _threadSignal; this.hm = _hm; this.currmonth = _currmonth; this.vipSmsSpidSendDao = _vipSmsSpidSendDao; this.dictionaryDao = _dictionaryDao; } @Override /** * 业务处理 * 1. 查询是否配置 * 2. 判断当前时间是否在指定时间 * 2. 查询当月是否已发送过短信 * 3. 发送短信 * 4. 更新处理结果 */ public void run() { long startime = System.currentTimeMillis(); Map logMap = new HashMap(); logMap.put("data", hm); String resultcode = "-1"; String errorinfo = ""; String id = hm.get("ID").toString(); try { String userid = hm.get("USERID").toString(); String confid = hm.get("CONFID").toString(); //获取所有配置信息 HashMap dataconf = vipSmsSpidSendDao.getVipsmsspidconf(confid); //System.out.println("配置数据"+dataconf); if(dataconf == null || dataconf.size() == 0){ throw new BusinessException("9057","无发送配置"); } String smstxt = (String)dataconf.get("SMSTXT"); if(!StringUtils.isEmpty(smstxt) && smstxt.trim().length()>0){ //替换手机号码 smstxt = smstxt.replaceAll("#USERID#", userid); }else{ throw new BusinessException("9053","无短信内容配置"); } //发送时间验证 String dateformat = (String)dataconf.get("DATEFORMAT"); String sendstarttime = (String)dataconf.get("SENDSTARTTIME"); String sendendtime = (String)dataconf.get("SENDENDTIME"); if(!StringUtils.isEmpty(dateformat)){ String currtime = new SimpleDateFormat(dateformat).format(new Date()); logMap.put("currtime", currtime); //有配置短信发送开始时间,但当前时间小于开始时间 if(!StringUtils.isEmpty(sendstarttime) && Long.parseLong(currtime) < Long.parseLong(sendstarttime)){ throw new BusinessException("9055","未到短信发送开始时间"); } //有配置短信发送结束时间,但当前时间大于结束时间 if(!StringUtils.isEmpty(sendendtime) && Long.parseLong(currtime) > Long.parseLong(sendendtime)){ throw new BusinessException("9054","已过短信发送结束时间"); } } if(vipSmsSpidSendDao.hasAlreadySend(userid,confid,currmonth)){ throw new BusinessException("9056","重复发送短信"); } HashMap params = new HashMap(); params.put("USERID", userid); params.put("CONFID", confid); params.put("SENDMONTH", currmonth); params.put("COLLECTID", id); //添加发送记录,有唯一约束,添加成功才发短信 vipSmsSpidSendDao.addSendLog(params); //发送短信 String result = send(userid,smstxt); errorinfo = result; if(!StringUtils.isEmpty(result)){ JSONObject obj = JSON.parseObject(result); resultcode = obj.getString("resultcode"); }else{ resultcode = "5000"; errorinfo = "调发送短信接口无返回信息"; } } catch (Exception e) { if (e instanceof BusinessException) { errorinfo = ((BusinessException) e).getMessage(); resultcode = ((BusinessException) e).getCode(); }else{ e.printStackTrace(); if (e.getMessage() != null && e.getMessage().contains("ORA-00001")) { resultcode = "6002"; errorinfo += "当月已发送"; }else{ resultcode = "8000"; errorinfo += "处理数据出现异常,"+e.getMessage(); } } }finally { threadSignal.countDown(); boolean updres = false; try{ if(!StringUtils.isEmpty(errorinfo) && errorinfo.length()>300){ errorinfo = errorinfo.substring(0,300); } if("-1".equals(resultcode)){ resultcode = "8001"; errorinfo = "处理异常"; } //更新处理结果 updres = vipSmsSpidSendDao.updExecRes(id,resultcode,errorinfo); }catch(Exception e){ e.printStackTrace(); errorinfo += "更新数据出现异常,"+e.getMessage(); resultcode = "8001"; } //写日志 logMap.put("jobname", "VipSmsSpidSendJob"); logMap.put("resultcode", resultcode); logMap.put("errorinfo", errorinfo); logMap.put("updres", updres); logger.info(JsonUtil.objectToJson(logMap)); } } //发送短信 public String send(String userid,String content) throws Exception { String url = dictionaryDao.getValue("contractpushurl"); // String url = "http://111.206.133.54/smsbusi/sms/send"; String smsid = "10655117"; String pwd = "wo6bslq2"; userid = DESUtil.encode(userid,pwd); String timestamp = System.currentTimeMillis()/1000+""; String sign = SHAUtil.shaEncode(smsid+userid+timestamp+content+pwd).toLowerCase(); userid = URLEncoder.encode(userid,"utf-8"); content = URLEncoder.encode(content,"utf-8"); url = url+"?smsid="+smsid+"&userid="+userid+"×tamp="+timestamp+"&sign="+sign+"&content="+content; String result = URLUtil.get(url); return result; } }