• CoreOnLineTransactionService.java


    package com.nantian.sms.service;

    import java.math.BigDecimal;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import com.nantian.common.util.SmsUtil;
    import com.nantian.sms.dao.mapper.CoreOnLineTransactionMapper;
    import com.nantian.sms.dao.model.CoreDataRealtime;
    import com.nantian.sms.dao.model.Dictionary;


    /**
    *
    * *************************************************************************
    * Copyright (c) :山西信合和云南南天电子信息产业股份有限公司. *
    * ProgramName :
    * SystemName : 消息平台
    * Version : 1.0
    * Language : JAVA
    * OS & Env : Window 10
    * MYSQL v 5.6:
    * Description : 核心实时交易类
    * History :
    * YYYY/MM/DD Position Author Description
    * -------------------------------------------------------------
    * 2020年1月14日 jianjun.xue 核心实时交易类
    *
    * **************************************************************************
    */
    @SuppressWarnings(value={"all"})
    @Service
    public class CoreOnLineTransactionService {
    @Autowired
    private CoreOnLineTransactionMapper coreOnLineTransactionMapper;
    //@Autowired
    //private DictionaryMapper dictionaryMapper;//@Author:libing
    /**
    * 调用SmsUtil的获取模板的方法
    */
    public static String getMessage(String messagecode, Map root) throws Exception {
    return SmsUtil.getMessage(messagecode, root);
    }

    /**
    * 获取实时表CoreDataRealtime
    * @author libing
    * @throws ParseException
    */
    public void getCoreRealtimeData(){
    System.out.println("==============================进入service方法");
    //(被注释)String cursor = "20200107" + "00000001"; //游标初始化,此处应可从内管系统进行修改,以便系统宕机时,重新配置

    //String cursor = dictionaryMapper.getCoreDataRealtimeInitialCursor().getDictionaryValue();
    //String pageSize = dictionaryMapper.getCoreDataRealtimePageSize().getDictionaryValue();
    //String sleep = dictionaryMapper.getCoreDataRealtimeSleep().getDictionaryValue();
    while(true) {
    List<CoreDataRealtime> coreData = new ArrayList<CoreDataRealtime>();
    //coreData = (List<CoreDataRealtime>) coreOnLineTransactionMapper.getCoreDataRealtime(cursor, pageSize); //输入游标,分段获取核心数据
    //jianjun.xue测试方法
    coreData = (List<CoreDataRealtime>) coreOnLineTransactionMapper.getCoreDataRealtimeByXjj();
    //jianjun.xue
    if(coreData.size()!=0) {
    System.out.println("======================================开始执行第1 步");
    //第1步:核心实时表传送数据
    try {
    findCoreTransactions(coreData);
    } catch (ParseException e) {
    System.out.println("交易日期格式化异常或第3步:没有重复记录,开始处理数据异常");
    e.printStackTrace();
    }
    //CoreDataRealtime lastData = coreData.get(coreData.size()-1); //获取该批次数据的最后一条
    //String customizeTime = "YYYYMMDD";
    //SimpleDateFormat sdf = new SimpleDateFormat(customizeTime);
    //String dateString=sdf.format(lastData.getS21TXDT());
    //根据最后一条数据,更新游标
    //cursor = dateString.substring(0,4)+dateString.substring(5,7)+dateString.substring(8,10)+String.valueOf(lastData.getS21NUM());
    }
    /*try {
    Thread.sleep(Integer.valueOf(sleep)); //本轮任务执行完毕,睡眠特定时长
    } catch (InterruptedException e) {
    e.printStackTrace();
    }*/
    }
    }

    /**
    * 第1步:核心实时表传送数据
    * @throws ParseException
    */
    public void findCoreTransactions(List<CoreDataRealtime> coreData) throws ParseException{
    System.out.println("=====================================进入第一步方法里");
    //遍历coreData中的数据
    Iterator<CoreDataRealtime> iterCoreData=coreData.iterator();
    while(iterCoreData.hasNext()) {
    CoreDataRealtime coreDataRealtime=iterCoreData.next();
    //判断插入重复,首先从库中获取的属性
    BigDecimal number=coreDataRealtime.getS21NUM();//序号//0
    String otherMsg=coreDataRealtime.getS21OTHDTL().toString();//其他信息S21OTHDTL(前十位肯定有,放的是日期) //19
    //实际交易日期(原来写的transDate)(存入失败表次数的失败日期)
    String transDate=otherMsg.substring(0,10);//********************************************************************************
    //交易日期 //2
    String strDateFormat = "yyyy-MM-dd";
    SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat);
    Date tradeDate=sdf.parse(transDate) ;
    String date=sdf.format(tradeDate);
    System.out.println(date);
    String year=date.substring(0, 4);//年
    String month=date.substring(5, 7);//月
    String day=date.substring(8, 10);//日
    //唯一确定查询码:变形日期+序号(失败4次,存入短信发送表)
    String acctOnlyFlag=(year+month+day)+number.toString();
    //传递判断插入重复的参数封装
    Map paras=new HashMap<>();
    paras.put("coreDataRealtime", coreDataRealtime);
    paras.put("number", number);
    paras.put("otherMsg", otherMsg);
    paras.put("transDate",transDate );
    paras.put("year", year);
    paras.put("month",month );
    paras.put("day", day);
    paras.put("acctOnlyFlag", acctOnlyFlag);
    //第2步:插入重复判断,避免从实时表获取的数据重复插入
    //查询字典表中dictionaryVaule值
    Map selectRepeatNum=coreOnLineTransactionMapper.selectDictionaryVaule();
    System.out.println("查询字典表中dictionaryVaule值="+selectRepeatNum);
    Long selelct=Long.parseLong((String) selectRepeatNum.get("dictionaryVaule")) ;//字典表中的唯一序列号 //???如果字典中没有dictonaryValue,会报空指针异常
    Long thisAcctOnlyFlag=Long.parseLong(acctOnlyFlag);//当前本次唯一序列号
    System.out.println("当前本次唯一序列号thisAcctOnlyFlag="+thisAcctOnlyFlag);
    System.out.println(thisAcctOnlyFlag>selelct);
    if(thisAcctOnlyFlag>selelct) {//如果本次的唯一序列号大于字典表中的序列号
    System.out.println("===========开始执行第3步,没有重复记录,开始处理数据=========");
    //第3步:没有重复记录,开始处理数据
    noDuplicateRecord(paras);
    }
    //更新字典表中的dictionaryVaule的值
    coreOnLineTransactionMapper.updateDictionaryVaule(thisAcctOnlyFlag);
    //如果执行报错,继续执行
    continue;
    }
    }

    /**
    * 第3步:没有重复记录,开始处理数据
    * @throws ParseException
    */
    private void noDuplicateRecord(Map paras) throws ParseException {
    //参数处理成Map传递
    Map allParas=new HashMap<>();
    //root为模板中放入数据
    Map root=new HashMap();
    //取出处理判断插入重复的参数Map paras;
    CoreDataRealtime coreDataRealtime=(CoreDataRealtime) paras.get("coreDataRealtime");
    BigDecimal number=(BigDecimal) paras.get("number");//序号//0
    String otherMsg=(String) paras.get("otherMsg");//其他信息//19
    String transDate=(String)paras.get("transDate");//实际交易日期(原来写的transDate)(存入失败表次数的失败日期)
    String year=(String)paras.get("year");//年
    String month=(String)paras.get("month");//月
    String day=(String)paras.get("day");//日
    String lastOtherMsg=(String) paras.get("otherMsg");//其他信息S21OTHDTL(前十位肯定有,放的是日期)
    String acctOnlyFlag=(String) paras.get("acctOnlyFlag");//日期+序号(唯一标识)
    System.out.println("acctOnlyFlag="+acctOnlyFlag);
    //判断短信签约失败与成功
    //从核心数据库获取值
    String type=coreDataRealtime.getS21TYPE();//类型//1 //交易类型
    Date runDate=coreDataRealtime.getS21TXDT();//跑批日期(注意:不是交易日期)//2
    BigDecimal formerTransNum=coreDataRealtime.getS21PTXSQ();//原交易流水号//3 //云闪付判断
    BigDecimal subTransNum=coreDataRealtime.getS21CTXSQ();//子交易顺序号//4 //云闪付判断
    String account= coreDataRealtime.getS21ACCT().toString();//获得账号//5
    String subAccount=coreDataRealtime.getS21ACCS();//分账号 //6
    String cardNumber=coreDataRealtime.getS21CRDNUM();//获得卡号S21CRDNUM //7
    String sign=coreDataRealtime.getS21KZFLG().toString();//卡折标志 //8
    //卡折标志,匹配模板处理
    String cfSign=null;
    if(sign!=null&&sign.length()!=0) {
    cfSign=sign;
    allParas.put("cfSign",cfSign );
    }else {
    cfSign="%";
    allParas.put("cfSign",cfSign );
    }
    String transCode= coreDataRealtime.getS21PTXCD();//交易代码 //核心6位交易码 //9
    String transName=coreDataRealtime.getS21PTXNAM();//交易名称 //10
    String subjectCod=coreDataRealtime.getS21SBNO();//科目代码 //核心科目代码 //11
    //科目代码,匹配模板处理
    String subjectCode=null;
    if (subjectCod!=null&&subjectCod.length()!=0) {
    subjectCode=subjectCod;
    allParas.put("subjectCode",subjectCode );//科目代码 //核心科目代码
    } else {
    subjectCode="%";
    allParas.put("subjectCode",subjectCode );//科目代码 //核心科目代码
    }
    String accountType=coreDataRealtime.getS21ACCTYP();//账户类型 //12
    String transTime=coreDataRealtime.getS21TXTM().toString();//交易时间(肯定有,不需要判断) //13
    System.out.println("transTime="+transTime);
    //交易时间(时/分/秒) //13
    String hour=transTime.substring(0, 2);//时
    String minutes=transTime.substring(3, 5);//分
    String second=transTime.substring(6, 8);//秒
    String transTimeNoColon=hour+minutes+second;//无冒号的交易时间//13-2
    BigDecimal transMoney=coreDataRealtime.getS21AMT();//交易金额 //14
    BigDecimal balance=coreDataRealtime.getS21BALE();//余额 //15
    String lSign=coreDataRealtime.getS21CRDRFG();//借贷方向 //借贷标志 //16
    ////借贷方向 //借贷标志,模板匹配处理
    String loanSign=null;
    if(lSign!=null&&lSign.length()!=0) {
    loanSign=lSign;
    allParas.put("loanSign",loanSign );//借贷方向 //借贷标志
    }else {
    loanSign="%";
    allParas.put("loanSign",loanSign );//借贷方向 //借贷标志
    }
    String digestCode=coreDataRealtime.getS21BRCOD();//摘要码 //17
    String digest=coreDataRealtime.getS21RMKS();//(中文)摘要(里面包含ETC) //18
    //合并卡号/账号为1个字段,即存库时卡号为空时存入账号
    String cardOrAccount=null;
    if(cardNumber!=null&&cardNumber.length()!=0) {
    //如果卡号不为空
    cardOrAccount=cardNumber;
    System.out.println("cardOrAccount卡号:"+cardOrAccount);
    String cutAccount=cardOrAccount.substring(cardOrAccount.length()- 4);//截取账号或卡号后四位
    System.out.println("cutAccount="+cutAccount);
    allParas.put("cutAccount",cutAccount);//账号或卡号后四位
    allParas.put("cardOrAccount", cardOrAccount);//卡号不为空,放入卡号
    }else {
    //卡号为空
    cardOrAccount=account;
    System.out.println("cardOrAccount账号:"+cardOrAccount);
    String cutAccount=cardOrAccount.substring(cardOrAccount.length()- 4);//截取账号或卡号后四位
    System.out.println("cutAccount="+cutAccount);
    allParas.put("cutAccount",cutAccount);//账号或卡号后四位
    allParas.put("cardOrAccount", cardOrAccount);//账号不为空,放入账号
    }
    allParas.put("lSign", lSign);//卡折标志;云闪付专用判断
    allParas.put("type",type );//交易类型
    allParas.put("formerTransNum", formerTransNum);//原交易流水号
    allParas.put("subTransNum", subTransNum);//子交易顺序号
    allParas.put("account",account );//账号
    allParas.put("subAccount", subAccount);//分账号
    allParas.put("transCode", transCode);//交易代码 //核心6位交易码
    allParas.put("accountType",accountType );//账户类型
    allParas.put("transTime",transTime );//交易时间(肯定有,不需要判断)
    allParas.put("transTimeNoColon", transTimeNoColon);//transTimeNoColon=hour+minutes+second;//无冒号的交易时间
    allParas.put("transMoney", transMoney);//交易金额
    allParas.put("balance",balance );//余额
    allParas.put("digest",digest );//摘要(里面包含ETC)
    allParas.put("transDate",transDate );//实际交易日期(原来写的transDate)(存入失败表次数的失败日期)S21OTHDTL前十位的截取日期
    allParas.put("year",year);//年
    allParas.put("month",month);//月
    allParas.put("day",day );//日
    allParas.put("hour",hour );//时
    allParas.put("minutes",minutes);//分
    allParas.put("second",second );//秒
    allParas.put("acctOnlyFlag", acctOnlyFlag);//唯一标识日期+序号
    allParas.put("lastOtherMsg", lastOtherMsg);//其他信息S21OTHDTL(前十位肯定有,放的是日期)
    //第4步:开始处理从实时表获取过来的数据
    dealCoreData(allParas,root);
    }

    /**
    * 第4步:开始处理从实时表获取过来的数据
    */
    private void dealCoreData(Map allParas,Map root) {
    if(allParas.get("type").equals("X99")) {
    //第4.1步:交易失败,数据存入失败次数表
    saveAdvancecontrol(allParas, root);
    }else {
    //第4.2步:交易成功(2.1 短信签约;2.2微信签约;2.3 其他查控签约;2.4 云闪付)
    //第4.2.1步: 判断是否短信签约相关操作
    querySignMsg(allParas,root);
    //第4.2.2步: 判断是否微信签约相关操作
    querySignWechat(allParas);
    //第4.2.3步: 判断是否查控签约相关操作,有手机号存入短信发送表,无手机号存入报文发送表
    querySignOther(allParas,root);
    //第4.2.4步: 判断云闪付的卡状态变动(原交易流水号formerTransNum和子交易顺序号subTransNum为0的状态)
    if(allParas.get("formerTransNum")==null&&allParas.get("subTransNum")==null) {
    cloudFlashover(allParas,root);
    }
    }
    }

    /**
    * 第4.2.4步: 判断云闪付的卡状态变动(原交易流水号formerTransNum和子交易顺序号subTransNum为0的状态)
    */
    private void cloudFlashover(Map allParas,Map root) {
    System.out.println("=================进入方法:判断云闪付的卡状态变动======================");
    String digest=(String) allParas.get("digest");//中文摘要
    //存入报文发送表
    Map cloudInsertSendPacketMsg=new HashMap<>();
    String cardOrAccount=(String) allParas.get("cardOrAccount");//(1)卡号
    String otherMsg=(String) allParas.get("otherMsg");//19其他信息
    String newCardNum=null;
    //新卡号非空处理
    if (otherMsg!=null&&otherMsg.length()>32) {
    newCardNum=otherMsg.substring(10,32);//(2)新卡号 newCardNum//**************************************************************************
    }
    String transCode=(String) allParas.get("transCode");//(3)交易代码S21PTXCD --自己的为transCode
    String formerTransNum=(String) allParas.get("formerTransNum");//(4)原交易流水号
    String cardStatus=null;//(5)状态操作(91-注销;92-挂失;93-解挂;94-冻结;95-解冻)cardStatus
    String type=(String) allParas.get("type");//交易类型
    if(allParas.get("loanSign")==null) {//loanSign为借贷标志
    if (type=="T01"||type=="T02"||type=="T03") {
    cardStatus="91";
    }
    int judge=digest.indexOf("解除");
    if (transCode=="113010"&&judge!=-1) {
    cardStatus="93";
    } else {
    cardStatus="92";
    }
    }
    cloudInsertSendPacketMsg.put("cardNum", cardOrAccount);
    cloudInsertSendPacketMsg.put("newCardNum", newCardNum);
    cloudInsertSendPacketMsg.put("cardStatus", cardStatus);
    cloudInsertSendPacketMsg.put("tradeAmount", allParas.get("transMoney"));//交易金额
    cloudInsertSendPacketMsg.put("tradeBalance",allParas.get("balance"));//余额
    cloudInsertSendPacketMsg.put("tradeDate",allParas.get("transDate"));//交易日期
    cloudInsertSendPacketMsg.put("tradeTime", allParas.get("transTime"));//交易时间
    cloudInsertSendPacketMsg.put("acctType", allParas.get("accountType"));//账户类型
    cloudInsertSendPacketMsg.put("currency","RMB" );//币种(默认RMB)
    //云闪付数据存入报文发送表
    coreOnLineTransactionMapper.cloudFlashoverInsertSendPacketMsg(cloudInsertSendPacketMsg);
    }

    /**
    * 第4.2.3步: 判断是否查控签约相关操作,有手机号存入短信发送表,无手机号存入报文发送表
    */
    private Map querySignOther(Map allParas,Map root) {
    System.out.println("============进入方法:判断是否查控签约相关操作=====================");
    //从其他查控签约表中获得数据
    String cardOrAccount=(String) allParas.get("cardOrAccount");
    Map signOtherList=new HashMap<>();
    try {
    System.out.println("======================查控签约有记录,开始执行查控签约代码===========================");
    signOtherList=coreOnLineTransactionMapper.selectSignOther(cardOrAccount);
    if(signOtherList.size()!=0) {
    String tradeRemark=((String)allParas.get("otherMsg")).substring(60);//商户名称
    //有手机号的签约数据
    Map haveMobilePhone=new HashMap<>();
    //无手机号的签约数据
    Map noMobilePhone=new HashMap<>();
    String sysCusNum=(String) signOtherList.get("sysCusNum");//银行为公积金中心分配的客户编号
    String acctName=(String) signOtherList.get("acctName");//户名
    String cardNum=(String) signOtherList.get("cardNum");//卡号
    String acctType=(String) signOtherList.get("acctType");//账户类型(2-对公 1-对私)
    String cardType=(String) signOtherList.get("cardType");//卡类型(0 存折/借记卡 1 信用卡)
    String aorcFlag=(String) signOtherList.get("aorcFlag");//卡折标志(1折 2卡)
    String opNum=(String) signOtherList.get("opNum");//操作员,公积金有值
    String signType=(String) signOtherList.get("signType");//签约类型
    String orgNum=(String) signOtherList.get("orgNum");//网点号
    String regTime=(String) signOtherList.get("regTime");//签约登记时间YYYYMMDDHHmmss
    String interceptionStartTime=(String) signOtherList.get("interceptionStartTime");//签约时:该字段代表监控开始时间 解约时:该字段代表为空
    String interceptionEndTime=(String) signOtherList.get("interceptionEndTime");//签约时:该字段代表监控结束时间;解约时:该字段代表解绑生效时间
    String rwSerialno=(String) signOtherList.get("rwSerialno");//电信诈骗、公安查控、国安查控、国监委查控时此字段有值
    String tel=(String) signOtherList.get("tel");//监控人接收消息手机号

    //存入报文发送表
    if(signType!=null) {
    // 电信诈骗:S0005;公安查控:S0006;国安查控:S0007;国监委查控:S0008
    if(signType=="S0005"||signType=="S0006"||signType=="S0007"||signType=="S0008") {
    //核心表db2中的交易日期+交易时间
    String transDate=(String) allParas.get("transDate");
    String transTimeNoColon=(String) allParas.get("transTimeNoColon");
    String transDateAddTime=transDate+transTimeNoColon;
    Long signDateAddTime=Long.parseLong(transDateAddTime);//将交易日期+时间转化为long类型
    Long startTime=Long.parseLong(interceptionStartTime);//签约开始时间
    Long endTime=Long.parseLong(interceptionEndTime);//签约结束时间
    Long left=signDateAddTime-startTime;
    Long right=endTime-signDateAddTime;
    if(left>=0&&right>=0) {//电信诈骗
    noMobilePhone.put("signType",signType);//签约类型
    noMobilePhone.put("tradeSerialno", allParas.get("formerTransNum"));//账务信息的交易流水号 );
    noMobilePhone.put("tradeAmount", allParas.get("transMoney"));//交易金额
    noMobilePhone.put("tradeBalance",allParas.get("balance") );//余额
    noMobilePhone.put("tradeDate",transDate );//交易日期
    noMobilePhone.put("tradeTime", allParas.get("transTime"));//交易时间
    noMobilePhone.put("tradeRemark", tradeRemark);//商户名称
    noMobilePhone.put("acctType", acctType);//账户类型
    noMobilePhone.put("cardNum", cardNum);//卡号/账号
    noMobilePhone.put("crdrFlag", allParas.get("loanSign") );//借贷标志
    noMobilePhone.put("currency","RMB" );//币种(默认RMB)
    noMobilePhone.put("rwSerialno", rwSerialno);//绑定时发送到短信平台的任务流水号(查控专用)(唯一)
    noMobilePhone.put("serviceScenario", "6001200001901");//查控专用字段,服务场景码固定值:6001200001901(固定值)
    //其它签约无手机号时,存入报文发送表
    coreOnLineTransactionMapper.signOtherInsertSendPacketMsg(noMobilePhone);
    }
    }
    if(tel!=null) {//如果有查控手机号,存入短信发送表
    //核心表db2中的交易日期+交易时间
    String transDate=(String) allParas.get("transDate");
    String transTime=(String) allParas.get("transTime");
    String transDateAddTime=transDate+transTime;
    Long signDateAddTime=Long.parseLong(transDateAddTime);//将交易日期+时间转化为long类型
    Long startTime=Long.parseLong(interceptionStartTime);//签约开始时间
    Long endTime=Long.parseLong(interceptionEndTime);//签约结束时间
    Long left=signDateAddTime-startTime;
    Long right=endTime-signDateAddTime;
    if(left>=0&&right>=0) {//电信诈骗
    root.put("account", allParas.get("cutAccount"));//账号后4位
    root.put("month",allParas.get("month"));//月
    root.put("day",allParas.get("day"));//日
    root.put("hour", allParas.get("hour"));//时
    root.put("minutes", allParas.get("minutes"));//分
    root.put("money", allParas.get("transMoney"));//交易金额
    root.put("balance", allParas.get("balance"));//余额
    try {
    //短信模板的配置方法,获得短信模板
    String getMsgTemp = dynamicMatchingMsgTemplate(allParas);
    //tempContent为短信内容
    String tempContent = CoreOnLineTransactionService.getMessage(getMsgTemp, root);
    //判断是否是长短信
    Integer islongMsg = judgeLongMsg(tempContent);
    haveMobilePhone.put("islongMsg", islongMsg);//是否长短信(1是 0否) 160个英文或数字字符,或者70个中文字符,islongMsg
    //数据存入短信发送表
    haveMobilePhone.put("acctOnlyFlag", allParas.get("acctOnlyFlag"));//日期+序号
    haveMobilePhone.put("mobile", tel);//手机号
    haveMobilePhone.put("msgConent", tempContent);//短信内容
    haveMobilePhone.put("tradeDate", transDate);//动账交易日期
    haveMobilePhone.put("tradeTime", transTime);//动账交易时间
    //入库时间
    Date now = new Date();
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    String insertTime = dateFormat.format( now );
    haveMobilePhone.put("insertTime", insertTime);//入库时间
    } catch (Exception e) {
    e.printStackTrace();
    System.out.println("============没有找到对应的短信模板============");
    }
    //查控有手机号数据存入短信发送表
    coreOnLineTransactionMapper.signMsgInsertSendMsgB(haveMobilePhone);
    //查控有手机号数据存入报文发送表
    coreOnLineTransactionMapper.signOtherInsertSendPacketMsg(haveMobilePhone);
    }
    }
    }
    }
    } catch (Exception e) {
    System.out.println("==========查控签约没有记录,准备进行云闪付判断===========");
    return signOtherList;
    }
    return signOtherList;
    }

    /**
    * 第4.2.2步: 判断是否微信签约相关操作
    * @return
    */
    private Map querySignWechat(Map allParas) {
    System.out.println("================进入方法: 判断是否微信签约相关操作==============");
    //存入报文发送表
    Map signWechatSaveSendPacketMsg=new HashMap<>();
    String cardOrAccount=(String) allParas.get("cardOrAccount");
    Map signWechat=new HashMap<>();
    try {
    //查询微信签约表封装成map
    signWechat=coreOnLineTransactionMapper.selectSignWechat(cardOrAccount);
    } catch (Exception e) {
    System.out.println("===================微信没有签约,准备进入查控签约方法===============");
    return signWechat;
    }
    System.out.println("signWechat.size()="+signWechat);
    if(signWechat!=null) {
    System.out.println("该用户微信已签约,开始执行微信签约逻辑");
    //如果微信签约
    if(((String) allParas.get("otherMsg"))!=null&&((String) allParas.get("otherMsg")).length()>60) {
    String tradeRemark=((String) allParas.get("otherMsg")).substring(60);//商户名称
    signWechatSaveSendPacketMsg.put("tradeRemark", "{"businessName": ""+tradeRemark+""}");//商户名称
    }
    //商户信息
    //Integer cardType=(Integer) signWechat.get("cardType");//卡类型??(没有使用)
    //String regTime=(String) signWechat.get("regTime");//签约登记时间YYYYMMDDHHmmss??(没有使用)
    //第4.2.2步: 判断是否微信签约相关操作;存入报文发送表的公共属性数据
    wechatAndAbnormalTransactionPublicData(allParas, signWechatSaveSendPacketMsg);
    }
    return signWechat;

    }
    /**
    * 第4.2.1步: 判断是否短信签约相关操作
    */
    private void querySignMsg(Map allParas,Map root) {
    System.out.println("allParas.get("cutAccount")="+allParas.get("cutAccount"));
    System.out.println("=====================进入第4.2.1步: 判断是否短信签约相关操作方法==================");
    //数据存入短信发送表
    Map signMsgSaveSendMsgB=new HashMap<>();
    String otherMsg=(String)allParas.get("otherMsg");//其他信息
    String transCode=(String) allParas.get("transCode");//(3)交易代码S21PTXCD --自己的为transCode
    String cardOrAccount=(String) allParas.get("cardOrAccount");//卡号或账号
    //根据实时表卡号或账号去查询短信签约信息
    Map signMsg=coreOnLineTransactionMapper.selectSignMsg(cardOrAccount);//根据卡号或账号查出整条记录
    System.out.println("======================根据实时表卡号或账号去查询短信签约信息,查询短信签约已完成: 短信已签约=====================");
    root.put("account", allParas.get("cutAccount"));//账号后4位
    root.put("month",allParas.get("month"));//月
    root.put("day",allParas.get("day"));//日
    root.put("hour", allParas.get("hour"));//时
    root.put("minutes", allParas.get("minutes"));//分
    root.put("money", allParas.get("transMoney"));//交易金额
    root.put("balance", allParas.get("balance"));//余额
    //第4.2.1.1步: 如果是ETC直接存入短信发送表
    if(allParas.get("digest")=="ETC") {
    //ETC模板的内容==tempContent为短信内容
    try {
    String tempContent = CoreOnLineTransactionService.getMessage("0001_ETC", root);//ETC短信内容
    //第4.2.1.1步 存入短信发送表公共属性内容
    saveSendMsgBPublicContent(allParas, signMsgSaveSendMsgB, signMsg, tempContent);
    } catch (Exception e) {
    e.printStackTrace();
    System.out.println("====================ETC模板0001_ETC.ftl,出现问题=====================");
    }
    //ETC数据签约的数据存入短信发送表
    coreOnLineTransactionMapper.signMsgInsertSendMsgB(signMsgSaveSendMsgB);
    }
    //第4.2.1.2步: 非ETC存入短信发送表
    //如果短信已签约
    if(signMsg!=null) {
    String tempContent;//短信模板内容
    String rev1=(String) allParas.get("digest");//交易摘要
    root.put("rev1", rev1);
    //匹配短信模板
    //第4.2.1.2.1步:
    if (transCode.equals("SMD100")) {//判断核心6位交易码是否是SMD100
    try {
    String thisReturnPrincipal=otherMsg.substring(10,25);//本次归还本金
    String thisReturnInterest=otherMsg.substring(25,40);//本次归还利息
    String notReturnPrincipal=otherMsg.substring(40,55);//未还款本金
    String amountOwed=otherMsg.substring(55,70);//欠息金额
    root.put("notReturnPrincipal", notReturnPrincipal);
    root.put("amountOwed", amountOwed);
    root.put("thisReturnPrincipal", thisReturnPrincipal);
    root.put("thisReturnInterest", thisReturnInterest);
    tempContent = CoreOnLineTransactionService.getMessage("SMD100_%_%_%", root);
    saveSendMsgBPublicContent(allParas, signMsgSaveSendMsgB, signMsg, tempContent);//存入短信发送表公共属性内容
    } catch (Exception e) {
    e.printStackTrace();
    System.out.println("没有找到SMD100_%_%_%模板");
    }
    }else if(transCode.equals("SMD101")) {//判断核心6位交易码是否是SMD101
    //第4.2.1.2.2步:
    try {
    String thisReturnPrincipal=otherMsg.substring(10,25);//本次归还本金
    String thisReturnInterest=otherMsg.substring(25,40);//本次归还利息
    String totalCreditLine=otherMsg.substring(40,55);//总授信额度
    String remainingCreditLine=otherMsg.substring(55,70);//剩余授信额度
    root.put("thisReturnPrincipal", thisReturnPrincipal);
    root.put("thisReturnInterest", thisReturnInterest);
    root.put("totalCreditLine",totalCreditLine );
    root.put("remainingCreditLine",remainingCreditLine );
    tempContent = CoreOnLineTransactionService.getMessage("SMD101_%_%_%", root);
    saveSendMsgBPublicContent(allParas, signMsgSaveSendMsgB, signMsg, tempContent);//存入短信发送表公共属性内容
    } catch (Exception e) {
    e.printStackTrace();
    System.out.println("没有找到SMD101_%_%_%模板");
    }
    }else if(transCode.equals("SVS110")) {//判断核心6位交易码是否是SVS110
    //第4.2.1.2.3步:
    try {
    tempContent = CoreOnLineTransactionService.getMessage("SVS110_%_%_%", root);
    saveSendMsgBPublicContent(allParas, signMsgSaveSendMsgB, signMsg, tempContent);//存入短信发送表公共属性内容
    } catch (Exception e) {
    e.printStackTrace();
    System.out.println("没有找到SVS110_%_%_%模板");
    }
    }else if(transCode.equals("113850")){
    //第4.2.1.2.4步:
    try {
    root.put("repaydate", otherMsg.substring(0,10));//交易日期
    root.put("money", allParas.get("transMoney"));//授信金额
    root.put("limittime", otherMsg.substring(10));//期限
    tempContent = CoreOnLineTransactionService.getMessage("113850_%_%_%", root);
    saveSendMsgBPublicContent(allParas, signMsgSaveSendMsgB, signMsg, tempContent);//存入短信发送表公共属性内容
    } catch (Exception e) {
    e.printStackTrace();
    System.out.println("没有找到113850_%_%_%模板");
    }
    }else if(transCode.equals("113020")){
    //第4.2.1.2.5步:
    try {
    root.put("newaccount", otherMsg.substring(10,32).trim());//新卡号/折号
    tempContent = CoreOnLineTransactionService.getMessage("113020_%_%_1", root);
    saveSendMsgBPublicContent(allParas, signMsgSaveSendMsgB, signMsg, tempContent);//存入短信发送表公共属性内容2
    } catch (Exception e) {
    e.printStackTrace();
    System.out.println("没有找到113020_%_%_1或113020_%_%_2的模板");
    }
    }else {
    System.out.println("===========================进入短信签约,通用模板匹配==========================");
    //第4.2.1.2.6步:
    try {
    //短信模板的配置方法,获得短信模板
    String getMsgTemplate = dynamicMatchingMsgTemplate(allParas);
    String getMsgTemp=null;
    if (getMsgTemplate!=null&&getMsgTemplate.length()!=0) {
    getMsgTemp=getMsgTemplate;
    //tempContent为短信内容
    tempContent = CoreOnLineTransactionService.getMessage(getMsgTemp, root);
    System.out.println("tempContent="+tempContent);
    //微信签约和异常交易提醒微信签约,存入报文发送表的公共属性数据
    saveSendMsgBPublicContent(allParas, signMsgSaveSendMsgB, signMsg, tempContent);
    }
    } catch (Exception e) {
    e.printStackTrace();
    System.out.println("==========没有找到对应的短信模板============");
    //tempContent为短信内容
    tempContent = "==========注意:没有找到对应的短信模板,短信无内容==========";
    System.out.println("tempContent="+tempContent);
    //微信签约和异常交易提醒微信签约,存入报文发送表的公共属性数据
    saveSendMsgBPublicContent(allParas, signMsgSaveSendMsgB, signMsg, tempContent);
    }
    System.out.println("==========短信已签约的数据signMsgSaveSendMsgB,准备开始存入短信发送表=================");
    //短信已签约的数据存入短信发送表
    coreOnLineTransactionMapper.signMsgInsertSendMsgB(signMsgSaveSendMsgB);
    System.out.println("==========短信已签约的数据signMsgSaveSendMsgB,已经存入短信发送表=================");
    }
    }
    }

    /**
    * 第4.2.1.1步+第4.2.1.2步(第4.2.1.2.1步+第4.2.1.2.2步+第4.2.1.2.3步+第4.2.1.2.4步+第4.2.1.2.5步+第4.2.1.2.6步)
    * 需存入短信发送表的公共内容
    */
    private void saveSendMsgBPublicContent(Map allParas, Map signMsgSaveSendMsgB, Map signMsg, String tempContent) {
    //判断是否是长短信
    Integer islongMsg = judgeLongMsg(tempContent);
    signMsgSaveSendMsgB.put("islongMsg", islongMsg);//是否长短信(1是 0否) 160个英文或数字字符,或者70个中文字符,islongMsg
    //数据存入短信发送表
    signMsgSaveSendMsgB.put("acctOnlyFlag",allParas.get("acctOnlyFlag"));//日期+序号
    signMsgSaveSendMsgB.put("mobile", signMsg.get("mobile"));//手机号,来源于短信发送表
    signMsgSaveSendMsgB.put("msgConent", tempContent);//短信内容
    signMsgSaveSendMsgB.put("tradeDate",allParas.get("transDate"));//动账交易日期
    signMsgSaveSendMsgB.put("tradeTime",allParas.get("transTime"));//动账交易时间
    //入库时间
    Date now = new Date();
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    String insertTime = dateFormat.format( now );
    signMsgSaveSendMsgB.put("insertTime", insertTime);//入库时间
    }

    /**
    * 第4.1步:交易失败,数据存入失败次数表
    */
    private void saveAdvancecontrol(Map allParas,Map root) {
    String cardOrAccount=(String) allParas.get("cardOrAccount");//卡号或账号
    String transDate=(String) allParas.get("transDate");//交易日期
    String lastOtherMsg=(String) allParas.get("lastOtherMsg");//其他信息
    String mobile=lastOtherMsg.substring(10,21);//手机号
    System.out.println("手机号mobile="+mobile);
    String transChannelCode=lastOtherMsg.substring(30,37);//交易渠道码(7位??)************************?????????????????
    String errorTypeCode=lastOtherMsg.substring(37,38);//错误类型码 (1位??)*************************************??????????????
    //数据存入失败次数表和失败次数达到3,5,10短信发送表
    Map advancecontrol=new HashMap<>();
    Map wechatAlertAbnormalTransaction=coreOnLineTransactionMapper.selectSignWechat(cardOrAccount);
    System.out.println("微信交易异常提醒wechatAlertAbnormalTransaction="+wechatAlertAbnormalTransaction);
    //异常交易提醒,查询微信表封装成map
    //失败次数达到3,5,10次,如果微信签约,则存入报文发送表
    Map signWechatSaveSendPacketMsg=new HashMap<>();
    String failDate=allParas.get("transDate").toString();//失败日期
    //封装查询失败次数表的参数
    Map updateAdvancecontrolParas=new HashMap<>();
    //第一次查询失败次数表,返回null值
    updateAdvancecontrolParas.put("transDate", transDate);//交易日期
    updateAdvancecontrolParas.put("cardOrAccount", cardOrAccount);//卡号或账号
    updateAdvancecontrolParas.put("transChannelCode", transChannelCode);//交易渠道码
    updateAdvancecontrolParas.put("errorTypeCode", errorTypeCode);//错误类型码
    System.out.println("开始执行方法:第一次查询失败次数表");
    Integer failureTimes=coreOnLineTransactionMapper.findAdvancecontrolFailures(updateAdvancecontrolParas);
    System.out.println("失败次数failureTimes="+failureTimes);
    if(failureTimes!=null) {
    //3.如果失败次数不为null,更新失败次数,每次加1
    coreOnLineTransactionMapper.secondUpdateAdvancecontrolFailures(updateAdvancecontrolParas);
    //4.查询失败次数表,如果失败次数为3、5、10次时下发提醒,将发送短信提醒
    int secondSelectFailureTimes=coreOnLineTransactionMapper.findAdvancecontrolFailures(updateAdvancecontrolParas);
    if(secondSelectFailureTimes==3||secondSelectFailureTimes==5||secondSelectFailureTimes==10) {
    root.put("failures", secondSelectFailureTimes);//失败次数
    root.put("account", allParas.get("cutAccount"));//账号或卡号的后4位
    try {
    //tempContent为短信内容
    String tempContent = CoreOnLineTransactionService.getMessage("0000_failures", root);
    advancecontrol .put("msgConent", tempContent);
    advancecontrol.put("tradeDate", transDate);//交易日期
    advancecontrol.put("tradeTime", allParas.get("transTime"));//动账交易时间tradeTime
    //入库时间
    Date now = new Date();
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    String insertTime = dateFormat.format( now );
    advancecontrol.put("insertTime", insertTime);//入库时间insertTime
    advancecontrol.put("msgConent", tempContent); //短信内容msgConent
    advancecontrol.put("acctOnlyFlag", allParas.get("acctOnlyFlag"));//账务信息日期+序号,非账务消息可为空acctOnlyFlag //就是唯一确定的东西
    Integer islongMsg = judgeLongMsg(tempContent);//判断是否是长短信
    advancecontrol.put("islongMsg", islongMsg);//是否长短信(1是 0否) 160个英文或数字字符,或者70个中文字符,islongMsg
    advancecontrol.put("mobile", mobile);//手机号
    //1.1保存入短信发送表
    coreOnLineTransactionMapper.failuresSaveSendMsgB(advancecontrol);
    if(wechatAlertAbnormalTransaction.size()!=0) {//异常提醒,微信已签约
    //第4.1步:交易失败,数据存入失败次数表;存入报文发送表的公共属性数据
    wechatAndAbnormalTransactionPublicData(allParas, signWechatSaveSendPacketMsg);
    }
    } catch (Exception e) {
    e.printStackTrace();
    System.out.println("==========没有找到对应的失败次数模板============");
    }
    }
    }else {
    System.out.println("进入failureTimes为空的条件判断");
    advancecontrol.put("cardNum", cardOrAccount);//卡号/账号
    advancecontrol.put("aorcFlag", allParas.get("cfSign"));//卡折标志
    advancecontrol.put("failDate", allParas.get("transDate"));//交易日期=失败日期
    advancecontrol.put("failures", 1);//失败次数
    advancecontrol.put("mobile",mobile );//手机号
    advancecontrol.put("transChannelCode",transChannelCode);//交易渠道码
    advancecontrol.put("errorTypeCode", errorTypeCode);//错误类型码
    //第一次将失败属性记录到失败次数表
    coreOnLineTransactionMapper.saveAdvancecontrol(advancecontrol);
    System.out.println("第一次将失败属性记录到失败次数表:成功插入到失败次数表");
    }
    }

    /**
    * 第4.1步+第4.2.2步
    * 微信签约和异常交易提醒微信签约,存入报文发送表的公共属性数据
    */
    private void wechatAndAbnormalTransactionPublicData(Map allParas, Map signWechatSaveSendPacketMsg) {
    System.out.println("进入方法: 判断是否微信签约相关操作;存入报文发送表的公共属性数据 ");
    signWechatSaveSendPacketMsg.put("acctOnlyFlag", allParas.get("acctOnlyFlag"));//账务信息日期+序号
    signWechatSaveSendPacketMsg.put("signType","S0002");//签约类型 微信签约:S0002
    signWechatSaveSendPacketMsg.put("tradeSerialno",allParas.get("subAccount"));//账务信息流水号
    signWechatSaveSendPacketMsg.put("tradeAmount", allParas.get("transMoney"));//交易金额
    signWechatSaveSendPacketMsg.put("tradeBalance", allParas.get("balance"));//余额
    signWechatSaveSendPacketMsg.put("tradeDate", allParas.get("transDate"));//动账交易日期
    signWechatSaveSendPacketMsg.put("tradeTime",allParas.get("transTime") );//动账交易时间
    signWechatSaveSendPacketMsg.put("acctType", allParas.get("accountType") );//账户类型
    signWechatSaveSendPacketMsg.put("cardNum", allParas.get("cardOrAccount"));//卡号或账号
    signWechatSaveSendPacketMsg.put("crdrFlag", allParas.get("loanSign"));//借贷标志
    signWechatSaveSendPacketMsg.put("currency", "RMB");//币种(默认RMB)
    System.out.println("微信签约和异常交易提醒微信签约,开始存入报文发送表");
    coreOnLineTransactionMapper.signWechatInsertSendPacketMsg(signWechatSaveSendPacketMsg);
    System.out.println("==========微信签约和异常交易提醒微信签约,成功保存到报文发送表");
    }

    /**
    * 动态拼接短信模板名称 transCode,subjectCode,loanSign,cfSign
    */
    private String dynamicMatchingMsgTemplate(Map allParas) {
    String transCode=(String) allParas.get("transCode");
    System.out.println("transCode="+transCode);
    String subjectCode=(String) allParas.get("subjectCode");
    System.out.println("subjectCode="+subjectCode);
    String loanSign=(String) allParas.get("loanSign");
    System.out.println("loanSign="+loanSign);
    String cfSign=(String) allParas.get("cfSign");
    System.out.println("cfSign="+cfSign);
    String getMsgTemp = transCode+"_"+subjectCode+"_"+loanSign+"_"+cfSign;
    System.out.println("getMsgTemp="+getMsgTemp);
    return getMsgTemp;
    }

    /**
    * 判断是否是长短信
    */
    private Integer judgeLongMsg(String tempContent) {
    //判断短信中有几个中文字符
    int count=0;
    String regex = "[u4e00-u9fa5]";
    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(tempContent);
    while (matcher.find()) {
    for (int i = 0; i <= matcher.groupCount(); i++) {
    count = count + 1;
    }
    }
    System.out.println("短信内容中共有 " + count + "个汉字 ");
    //判断是否是长短信
    int msgContentLength=tempContent.length();
    Integer otherChar=msgContentLength-count;//短信中除中文外有几个其他字符
    Integer judgeMsgContent=count*2+otherChar;
    Integer islongMsg;
    if(judgeMsgContent<=140) {//最多发送140个字节
    islongMsg=0;
    }else {
    islongMsg=1;
    }
    return islongMsg;
    }
    }

  • 相关阅读:
    在zookeeper集群的基础上,搭建伪solrCloud集群
    Spring Data Solr操作solr的简单案例
    solr的客户端操作:使用solrj进行curd操作
    solr配置相关:约束文件及引入ik分词器
    solr的简单部署:在tomcat中启动slor
    Lucene的查询及高级内容
    淘淘商城部署文档
    服务器负载均衡的部署方式
    反向代理和负载均衡有何区别?
    毕向东_Java基础视频教程第21天_IO流(1)
  • 原文地址:https://www.cnblogs.com/curedfisher/p/12243480.html
Copyright © 2020-2023  润新知