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;
}
}