package com.chinacreator.process.service; import java.sql.SQLException; import java.util.Date; import java.util.HashMap; import java.util.List; import org.apache.commons.lang.time.DateFormatUtils; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import com.alibaba.fastjson.JSONObject; import com.chinacreator.process.bean.NetOrderBean; import com.chinacreator.process.bean.OrderLog; import com.chinacreator.process.dao.DictionaryDao; import com.chinacreator.process.dao.NetOrderDao; import com.chinacreator.process.dao.NextMonthEffectDao; import com.chinacreator.common.exception.BusinessException; /** * 能力平台次月生效 * @author xu.zhou * @date 20220512 */ @Component public class NextMonthEffectService { private static Logger log = Logger.getLogger("nextMonthEffect"); @Autowired private NextMonthEffectDao nextMonthEffectDao; @Autowired private DictionaryDao dictionaryDao; @Autowired private NetOrderDao netOrderDao; /** * 计费点相同的产品SPID替换 * @param orderBean * @throws Exception */ public void replaceSameVacSpid(NetOrderBean netOrderBean)throws Exception{ //{"1215":"changshi#1249","1213":"changshi#1250","1212":"changshi#1251","1219":"changshi#1253","1217":"changshi#1255"} String spids = dictionaryDao.getValue("sameVacproductidRepSpids"); if(StringUtils.isEmpty(spids) || spids.trim().length() == 0) return; JSONObject jsonSpids = JSONObject.parseObject(spids); String replaceSpid = jsonSpids.getString(netOrderBean.getSpid()); if(!StringUtils.isEmpty(replaceSpid)){//有要替换的产品 log.info("相同计费点SPID替换=>"+netOrderBean.getUserid()+"替换前"+netOrderBean.getCpid()+":"+netOrderBean.getSpid()); netOrderBean.setCpid(replaceSpid.split("#")[0]); //替换CPID netOrderBean.setSpid(replaceSpid.split("#")[1]); //替换SPID log.info("相同计费点SPID替换=>"+netOrderBean.getUserid()+"替换后"+netOrderBean.getCpid()+":"+netOrderBean.getSpid()); } } /** * 替换SPID,指定产品如果次月生效,替换成次月生效产品 * @param netOrderBean * @throws Exception */ public void replaceSpid(NetOrderBean netOrderBean) throws Exception{ //{"1249":"changshi#1256","1250":"changshi#1257","1251":"changshi#1258","1253":"changshi#1260","1255":"changshi#1262"} String spids = dictionaryDao.getValue("nextMonthEffectRepSpids"); if(StringUtils.isEmpty(spids) || spids.trim().length() == 0) return; JSONObject jsonSpids = JSONObject.parseObject(spids); String currmonth = DateFormatUtils.format(new Date(), "yyyyMM"); String replaceSpid = jsonSpids.getString(netOrderBean.getSpid()); if(!StringUtils.isEmpty(replaceSpid)){//有要替换的产品 boolean res = false; if("0".equals(netOrderBean.getStatus())){//订购 String ordermonth = DateFormatUtils.format(netOrderBean.getOrdertime(), "yyyyMM"); //订购月份大于当前月份 if(Integer.parseInt(ordermonth) > Integer.parseInt(currmonth)){ res = true; } }else{//退订 String cancelmonth = DateFormatUtils.format(netOrderBean.getCanceltime(), "yyyyMM"); //退订月份大于当前月份 if(Integer.parseInt(cancelmonth) > Integer.parseInt(currmonth)){ res = true; } } if(res){ log.info("次月生效SPID替换=>"+netOrderBean.getUserid()+"替换前"+netOrderBean.getCpid()+":"+netOrderBean.getSpid()); netOrderBean.setCpid(replaceSpid.split("#")[0]); //替换成次月生效产品CPID netOrderBean.setSpid(replaceSpid.split("#")[1]); //替换成次月生效产品SPID log.info("次月生效SPID替换=>"+netOrderBean.getUserid()+"替换后"+netOrderBean.getCpid()+":"+netOrderBean.getSpid()); } } } /** * 判断是否能力平台次月生效产品 * @param spid * @return * @throws Exception */ public boolean hasNextMonthBusi(String spid) throws Exception { boolean res = false; //是否走次月生效业务流程开关,为off时为关闭,默认不配置,应急时使用 String nextMonthBusiSwitch = dictionaryDao.getValue("nextMonthBusiSwitchSjyyt"); if("off".equals(nextMonthBusiSwitch)){ return res; } //判断是否为能力平台次月生效产品 List dataList = nextMonthEffectDao.qryAopConf(spid); if(dataList != null && dataList.size()>0){ res = true; } return res; } /** =========订购: 1. 正式订购关系表为订购状态,不处理 2. 正式订购关系表无数据或为退订或失效状态, 2.1 中间表无数据, 2.1.1 正式表无数据 2.1.1.1 H5订购,则调能力平台,成功后在中间表生成订购关系 2.1.1.2 CAP反向通知订购,则直接在中间表生成订购关系 2.1.2 正式表有数据 2.1.2.1 H5订购,则调能力平台,成功后在中间表生成订购关系 2.1.2.2 CAP订购,判断此次订购时间是否大于正式表的退订时间,是,则直接在中间表生成订购关系,否,则不处理 2.2 中间表有数据 2.2.1 中间表为订购状态 2.2.1.1 正式表有数据 2.2.1.1.1 已同步,为历史数据 2.2.1.1.1.1 H5订购,调能力平台,成功后更新中间表订购关系 2.2.1.1.1.2 CAP反向通知,判断此次订购时间是否大于中间表的订购时间且大于订购关系表的退订时间,是,则更新数据,否,则不处理 2.2.1.1.2 未同步, 2.2.1.1.2.1 H5订购,判断中间表生效时间是否大于此次生效时间,是,则不调能力平台直接更新中间表数据(防止中间表数据为反向通知且生效时间非次月1号),否,则不处理 2.2.1.1.2.2 CAP订购,不处理 2.2.1.2 正式表无数据 2.2.1.2.1 已同步,为历史数据, 2.2.1.2.1.1 H5订购:调能力平台,成功后更新中间表订购关系 2.2.1.2.1.2 CAP反向通知:判断此次订购时间是否大于中间表的订购时间,是,则更新数据,否,则不处理 2.2.1.2.2 未同步,不处理 2.2.2 中间表为退订状态, 2.2.2.1 H5订购:调能力平台,成功后更新中间表订购关系 2.2.2.2 CAP反向通知:判断此次订购时间是否大于中间表的退订时间且大于订购关系表的退订时间,是,则更新数据,否,则不处理 2.2.2.2.1 正式表有数据,判断此次订购时间是否大于中间表的退订时间且大于订购关系表的退订时间,是,则更新数据,否,则不处理 2.2.2.2.2 正式表无数据,判断此次订购时间是否大于中间表的退订时间,是,则更新数据,否,则不处理 =========退订: 1. 正式订购关系表为订购状态, 1.1 H5退订,调能力平台,更新正式订购关系表 1.2 反向通知退订,判断此次退订时间是否大于订购关系表的订购时间,是,则直接更新正式订购关系表,否,则不处理 2. 正式订购关系表无数据或为退订或失效状态, 2.1 中间表有订购关系 2.2.1 中间表为订购状态 2.2.1.1 正式表有数据 2.2.1.1.1 H5退订: 2.2.1.1.1.1 未同步,判断此次退订时间是否大于中间表订购时间(正式表的退订时间如来自反向通知有可能会大于中间表的订购时间),是,则调能力平台,成功后更新中间表订购关系,否,则不处理 2.2.1.1.1.2 已同步,不处理 2.2.1.1.2 CAP反向通知:判断此次退订时间是否大于中间表订购时间且大于订购关系表的退订时间,是,则更新数据,否,则不处理。(如果已同步数据退订也无效) 2.2.1.2 正式表无数据 2.2.1.2.1 H5退订:判断此次退订时间是否大于订购时间,是,则更新数据,否,则不处理。(如果已同步数据退订也无效) 2.2.1.2.2 CAP反向通知:判断此次退订时间是否大于订购时间,是,则更新数据,否,则不处理。(如果已同步数据退订也无效) 2.2.2 中间表为退订状态,不处理(无订购不处理退订) 2.2 中间表无订购关系,则不处理 2.2.1 正式表有数据,不处理,返回已退订 2.2.2 正式表无数据,不处理,返回无订购关系 * @param orderBean * @throws Exception */ public void process(NetOrderBean orderBean) throws Exception { String operchannel = "CAP"; HashMap logMap = new HashMap(); String errorcode = ""; String errorinfo = ""; try { //获取正式关系表的数据 List orderProList = nextMonthEffectDao.findOrderRela(orderBean); HashMap orderProMap = null; if(orderProList != null && orderProList.size()>0){ orderProMap = orderProList.get(0); } //获取中间表的已有订购关系 List orderNmaList = nextMonthEffectDao.qryNmaOrder(orderBean); HashMap orderNmaMap = null; if(orderNmaList != null && orderNmaList.size()>0){ orderNmaMap = orderNmaList.get(0); } logMap.put("orderProMap", orderProMap); logMap.put("orderNmaMap", orderNmaMap); //手厅渠道替换 channelReplace(orderBean, orderProMap); if("0".equals(orderBean.getStatus())){//订购 //1. 正式订购关系表为订购状态,不处理 if(orderProMap != null && "0".equals(orderProMap.get("STATUS"))){ throw new BusinessException("9050", "您已订购,请不要重复订购!", new String[0]); //2. 正式订购关系表无数据或为退订或失效状态, }else{ //设置生效时间 orderBean.setEffecttime(nextMonthEffectDao.getEffecttime(orderBean.getOrdertimestr())); //2.1 中间表无数据, if(orderNmaMap == null || orderNmaMap.size() == 0){ //2.1.1 正式表无数据 if(orderProMap == null || orderProMap.size() == 0){ //2.1.1.1 H5订购,则调能力平台,成功后在中间表生成订购关系 if("H5".equals(operchannel)){ //2.1.1.2 CAP反向通知订购,则直接在中间表生成订购关系 }else{ orderBean.setSyncstatus("1");//设置待处理 nextMonthEffectDao.nmaOrder(orderBean); } //2.1.2 正式表有数据 }else{ //2.1.2.1 H5订购,则调能力平台,成功后在中间表生成订购关系 if("H5".equals(operchannel)){ //2.1.2.2 CAP订购,判断此次订购时间是否大于正式表的退订时间,是,则直接在中间表生成订购关系,否,则不处理 }else{ //此次订购时间是否大于正式表的退订时间 if(Long.parseLong(orderBean.getOrdertimestr()) > Long.parseLong((String)orderProMap.get("CANCELTIME"))){ orderBean.setSyncstatus("1");//设置待处理 nextMonthEffectDao.nmaOrder(orderBean); }else{ throw new BusinessException("9052", "订购失败,订购时间小于或等于本地退订时间", new String[0]); } } } //2.2 中间表有数据 }else{ //2.2.1 中间表为订购状态 if("0".equals(orderNmaMap.get("STATUS"))){ //2.2.1.1 正式表有数据 if(orderProMap != null && orderProMap.size() > 0){ //2.2.1.1.1 已同步,为历史数据 if("0".equals(orderNmaMap.get("SYNCSTATUS"))){ //2.2.1.1.1.1 H5订购,调能力平台,成功后更新中间表订购关系 if("H5".equals(operchannel)){ //2.2.1.1.1.2 CAP反向通知,判断此次订购时间是否大于中间表的订购时间且大于订购关系表的退订时间,是,则更新数据,否,则不处理 }else{ //次订购时间是否大于中间表的订购时间且大于订购关系表的退订时间 if(Long.parseLong(orderBean.getOrdertimestr()) > Long.parseLong((String)orderNmaMap.get("ORDERTIME")) && Long.parseLong(orderBean.getOrdertimestr()) > Long.parseLong((String)orderProMap.get("CANCELTIME"))){ orderBean.setSyncstatus("1");//设置待处理 nextMonthEffectDao.nmaOrder(orderBean); }else{ throw new BusinessException("9053", "订购失败,订购时间小于或等于本地退订时间或者小于或等于中间表订购时间。", new String[0]); } } //2.2.1.1.2 未同步,不处理 }else{ throw new BusinessException("9054", "订购失败,用户中间表已订购且暂未同步到正式表", new String[0]); } //2.2.1.2 正式表无数据 }else{ //2.2.1.2.1 已同步,为历史数据, if("0".equals(orderNmaMap.get("SYNCSTATUS"))){ //2.2.1.2.1.1 H5订购:调能力平台,成功后更新中间表订购关系 if("H5".equals(operchannel)){ //2.2.1.2.1.2 CAP反向通知:判断此次订购时间是否大于中间表的订购时间,是,则更新数据,否,则不处理 }else{ //此次订购时间是否大于中间表的订购时间 if(Long.parseLong(orderBean.getOrdertimestr()) > Long.parseLong((String)orderNmaMap.get("ORDERTIME"))){ orderBean.setSyncstatus("1");//设置待处理 nextMonthEffectDao.nmaOrder(orderBean); }else{ throw new BusinessException("9055", "订购失败,订购时间小于或等于中间表订购时间。", new String[0]); } } //2.2.1.2.2 未同步,不处理 }else{ throw new BusinessException("9056", "订购失败,用户中间表已订购且暂未同步到正式表。", new String[0]); } } //2.2.2 中间表为退订状态, }else{ //2.2.2.1 H5订购:调能力平台,成功后更新中间表订购关系 if("H5".equals(operchannel)){ //2.2.2.2 CAP反向通知:判断此次订购时间是否大于中间表的退订时间且大于订购关系表的退订时间,是,则更新数据,否,则不处理 }else{ //2.2.2.2.1 正式表有数据,判断此次订购时间是否大于中间表的退订时间且大于订购关系表的退订时间,是,则更新数据,否,则不处理 if(orderProMap != null && orderProMap.size() > 0){ //此次订购时间是否大于中间表的退订时间且大于订购关系表的退订时间 if(Long.parseLong(orderBean.getOrdertimestr()) > Long.parseLong((String)orderNmaMap.get("CANCELTIME")) && Long.parseLong(orderBean.getOrdertimestr()) > Long.parseLong((String)orderProMap.get("CANCELTIME"))){ orderBean.setSyncstatus("1");//设置待处理 nextMonthEffectDao.nmaOrder(orderBean); }else{ throw new BusinessException("9057", "订购失败,订购时间小于或等于中间表退订时间或者小于或等于正式表的退订时间。", new String[0]); } //2.2.2.2.2 正式表无数据,判断此次订购时间是否大于中间表的退订时间,是,则更新数据,否,则不处理 }else{ //此次订购时间是否大于中间表的退订时间 if(Long.parseLong(orderBean.getOrdertimestr()) > Long.parseLong((String)orderNmaMap.get("CANCELTIME"))){ orderBean.setSyncstatus("1");//设置待处理 nextMonthEffectDao.nmaOrder(orderBean); }else{ throw new BusinessException("9058", "订购失败,订购时间小于或等于中间表退订时间。", new String[0]); } } } } } } }else{//退订 //设置结束时间 orderBean.setEndtime(nextMonthEffectDao.getEndtime(orderBean.getCanceltimestr())); //1. 正式订购关系表为订购状态, if(orderProMap != null && "0".equals(orderProMap.get("STATUS"))){ //1.1 H5退订,调能力平台,更新正式订购关系表 if("H5".equals(operchannel)){ //1.2 反向通知退订,判断此次退订时间是否大于订购关系表的订购时间,是,则直接更新正式订购关系表,否,则不处理 }else{ //此次退订时间是否大于订购关系表的订购时间 if(Long.parseLong(orderBean.getCanceltimestr()) > Long.parseLong((String)orderProMap.get("ORDERTIME"))){ orderBean.setSyncstatus("5"); //设置为5,代表要把退订信息添加到活动关系待处理表TD_BUSSHANDLE_WAIT orderBean.setStatus("1"); orderBean.setOrderstatus(5); //本地退订 netOrderDao.cancelOrder(orderBean); //走本地退订流程 //localCancel(orderBean); }else{ throw new BusinessException("9059", "退订失败,退订时间小于或等于本地订购时间", new String[0]); } } //2. 正式订购关系表无数据或为退订或失效状态, }else{ //2.1 中间表有订购关系 if(orderNmaMap != null && orderNmaMap.size() > 0){ //2.2.1 中间表为订购状态 if("0".equals(orderNmaMap.get("STATUS"))){ //2.2.1.1 正式表有数据 if(orderProMap != null && orderProMap.size() > 0){ //2.2.1.1.1 H5退订:判断此次退订时间是否大于中间表订购时间且大于订购关系表的退订时间,是,则调能力平台,成功后更新中间表订购关系,否,则不处理 if("H5".equals(operchannel)){ //2.2.1.1.2 CAP反向通知:判断此次退订时间是否大于中间表订购时间且大于订购关系表的退订时间,是,则更新数据,否,则不处理。(如果已同步数据退订也无效) }else{ //此次退订时间是否大于中间表订购时间且大于订购关系表的退订时间 if(Long.parseLong(orderBean.getCanceltimestr()) > Long.parseLong((String)orderNmaMap.get("ORDERTIME")) && Long.parseLong(orderBean.getCanceltimestr()) > Long.parseLong((String)orderProMap.get("CANCELTIME"))){ orderBean.setSyncstatus("4");//设置不同步 nextMonthEffectDao.nmaCancel(orderBean); }else{ throw new BusinessException("9060", "退订失败,退订时间小于或等于中间表的订购时间或者小于正式订购关系表的退订时间。", new String[0]); } } //2.2.1.2 正式表无数据 }else{ //2.2.1.2.1 H5退订:判断此次退订时间是否大于订购时间,是,则更新数据,否,则不处理。(如果已同步数据退订也无效) if("H5".equals(operchannel)){ //2.2.1.2.2 CAP反向通知:判断此次退订时间是否大于订购时间,是,则更新数据,否,则不处理。(如果已同步数据退订也无效) }else{ //此次退订时间是否大于订购时间 if(Long.parseLong(orderBean.getCanceltimestr()) > Long.parseLong((String)orderNmaMap.get("ORDERTIME"))){ orderBean.setSyncstatus("4");//设置不同步 nextMonthEffectDao.nmaCancel(orderBean); }else{ throw new BusinessException("9061", "退订失败,退订时间小于或等于中间表订购时间。", new String[0]); } } } //2.2.2 中间表为退订状态,不处理(无订购不处理退订) }else{ throw new BusinessException("9062", "退订失败,本地表非订购状态且中间表无订购。", new String[0]); } //2.2 中间表无订购关系,则不处理 }else{ //2.2.1 正式表有数据,不处理,返回已退订 if(orderProMap != null && orderProMap.size() > 0){ throw new BusinessException("9063", "退订失败,正式订购关系表已退订或已失效。", new String[0]); //2.2.2 正式表无数据,不处理,返回无订购关系 }else{ throw new BusinessException("9064", "退订失败,正式订购关系表及中间表无订购。", new String[0]); } } } } errorcode = "0"; errorinfo = "ok"; } catch (Exception e) { if ((e instanceof BusinessException)) { errorcode = ((BusinessException) e).getCode(); errorinfo = ((BusinessException) e).getMessage(); }else{ e.printStackTrace(); errorcode = "8000"; errorinfo = "处理出现异常,"+e.getMessage(); log.error(orderBean.getUserid()+"出现异常"+e.getMessage(), e); } throw e; } finally { try { saveLog(orderBean, errorcode, errorinfo); } catch (Exception e) { e.printStackTrace(); errorinfo += ",写日志出现异常,"+e.getMessage(); } try{ logMap.put("orderBean", JSONObject.toJSON(orderBean)); } catch (Exception e) { e.printStackTrace(); } logMap.put("errorcode", errorcode); logMap.put("errorinfo", errorinfo); log.info("NextMonthEffectService=>"+logMap); } } /** * 渠道替换 * @param orderBean * @param orderProMap */ private void channelReplace(NetOrderBean orderBean, HashMap orderProMap){ if(orderProMap == null || orderProMap.size() == 0) return; try{ if("0".equals(orderBean.getStatus())){//订购 if ("0".equals(orderProMap.get("STATUS"))) { if("sjyyt".equals(orderBean.getOrderchannel())){ try { //订购渠道优先级更新 this.netOrderDao.orderUpdate(orderBean); } catch (Exception e) { e.printStackTrace(); } } }else{ if("sjyyt".equals(orderBean.getOrderchannel())){ if(Long.parseLong(orderBean.getOrdertimestr()) < Long.parseLong((String)orderProMap.get("CANCELTIME"))){ //if(orderBean.getOrdertime().getTime() < oldOrderBean.getCanceltime().getTime()){ //订购渠道优先级更新 this.netOrderDao.orderUpdate(orderBean); saveNetLog(orderBean, "9096", "[手厅订购渠道覆盖]已退订,且手厅订购时间小于退订时间,订购渠道更新为sjyyt", "1"); } } } }else{//退订 if (!"0".equals(orderProMap.get("STATUS"))) { if("sjyyt".equals(orderBean.getCancelchannel()) ){ //退订渠道优先级更新 this.netOrderDao.cancelUpdate(orderBean); } }else{ if("sjyyt".equals(orderBean.getCancelchannel()) ){ if(Long.parseLong(orderBean.getCanceltimestr()) < Long.parseLong((String)orderProMap.get("ORDERTIME")) && orderProMap.get("CANCELCHANNEL") != null){ //if(orderBean.getCanceltime().getTime() < oldOrderBean.getOrdertime().getTime() //&& oldOrderBean.getCancelchannel()!=null && !"".equals(oldOrderBean.getCancelchannel().trim())){ //退订渠道优先级更新 this.netOrderDao.cancelUpdate(orderBean); saveNetLog(orderBean, "9097", "[手厅退订渠道覆盖]已订购,且手厅退订时间小于订购时间,退订渠道更新为sjyyt", "2"); } } } } } catch (Exception e) { e.printStackTrace(); } } public void saveNetLog(NetOrderBean orderInfo, String errorcode, String errorinfo, String ordertype) throws SQLException { OrderLog orderLog = new OrderLog(); orderLog.setApptype(orderInfo.getApptype()); orderLog.setChannel(ordertype.equals("1") ? orderInfo.getOrderchannel() : orderInfo.getCancelchannel()); orderLog.setOrderstatus(orderInfo.getOrderstatus()); orderLog.setStatus(Integer.valueOf(orderInfo.getStatus()).intValue()); orderLog.setCpid(orderInfo.getCpid()); orderLog.setIsexperience(orderInfo.getIsexperience()); orderLog.setOrdertype(orderInfo.getOrdertype()); orderLog.setProvince(orderInfo.getProvince()); orderLog.setArea(orderInfo.getArea()); orderLog.setSpid(orderInfo.getSpid()); orderLog.setUserid(orderInfo.getUserid()); orderLog.setErrorcode(errorcode); orderLog.setErrorinfo(errorinfo); this.netOrderDao.addOrderLog(orderLog); } /** * 写订购日志 * @param orderInfo * @param errorcode * @param errorinfo * @throws SQLException */ public void saveLog(NetOrderBean orderBean, String errorcode, String errorinfo) throws SQLException { if("5".equals(orderBean.getSyncstatus())){ return; } OrderLog orderLog = new OrderLog(); orderLog.setApptype(orderBean.getApptype()); orderLog.setArea(orderBean.getArea()); orderLog.setChannel(orderBean.getOrderchannel()); orderLog.setOrderstatus(orderBean.getOrderstatus()); orderLog.setStatus(Integer.parseInt(orderBean.getStatus())); orderLog.setCpid(orderBean.getCpid()); orderLog.setIsexperience(orderBean.getIsexperience()); orderLog.setOrdertype(orderBean.getOrdertype() + ""); orderLog.setProvince(orderBean.getProvince()); orderLog.setArea(orderBean.getArea()); orderLog.setSpid(orderBean.getSpid()); orderLog.setUserid(orderBean.getUserid()); orderLog.setErrorcode(errorcode); orderLog.setErrorinfo(errorinfo); nextMonthEffectDao.addNmaOrderLog(orderLog); } }