package com.chinacreator.video.restful.service;


import com.alibaba.fastjson.JSON;
import com.chinacreator.video.exception.BusinessException;
import com.chinacreator.video.exception.BussinessException;
import com.chinacreator.video.mapper.DictionaryDao;
import com.chinacreator.video.mapper.PointShopDao;
import com.chinacreator.video.restful.bean.OrderLog;
import com.chinacreator.video.restful.bean.PointShopOrderBean;
import com.chinacreator.video.restful.bean.ShopInObject;
import com.chinacreator.video.restful.bean.ShopOutObject;
import com.chinacreator.video.service.CommonService;
import com.chinacreator.video.util.URLUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.n3.ecs.open.util.HMACUtil;
import com.n3.ecs.open.util.SignUtil;
import net.sf.json.JSONObject;
import org.jboss.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import com.chinacreator.video.bean.OrderInfo;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

/**
 * 积分商城服务类
 * @author xu.zhou
 * @date 20190618
 */
@Component
public class PointShopService {
	
	@Autowired
	private PointShopDao pointShopDao;
	
	@Autowired
	private DictionaryDao dictionaryDao;

	@Autowired
	private CommonService commonService;
	
	private static Logger logger = Logger.getLogger(PointShopService.class);
	
	private static Logger log = Logger.getLogger("pointshop");
	
	/**
	 * 业务参数验证
	 * @param inputObj
	 */
	public void checkBusi(ShopInObject inputObj) throws Exception {
		checkTime(inputObj);
		checkAppId(inputObj);
		checkSign(inputObj);
		checkServiceCode(inputObj);
		checkParams(inputObj);
		checkMob(inputObj);
		checkGoodsCode(inputObj);
		checkOrderNo(inputObj);
	}
	
	/**
	 * 验证请求时间
	 * @param inputObj
	 * @throws Exception
	 */
	private void checkTime(ShopInObject inputObj)throws Exception {
		String time = inputObj.getTime();
		if(time == null || !this.isNumber(time)){
			throw new BussinessException("9050", "timestamp异常");
		}
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
		Date reqDate = formatter.parse(inputObj.getTime());
		long timetamp = reqDate.getTime()/1000;
		long localTimestamp = (System.currentTimeMillis())/1000;
		if((localTimestamp - timetamp) >300 || (localTimestamp - timetamp) <-300) {
			throw new BussinessException("9050", "timestamp已失效");
		}
	}
	
	/**
	 * 验证APPID
	 * @param inputObj
	 * @throws Exception
	 */
	private void checkAppId(ShopInObject inputObj)throws Exception {
		String appId = dictionaryDao.getValue("pointShopAppId");
		if(appId != null && !appId.equals(inputObj.getAppId())){
			throw new BussinessException("9065", "APPID验证失败");
		}
	}
	
	/**
	 * 检查签名
	 * @param inputObj
	 */
	private void checkSign(ShopInObject inputObj) throws Exception {
    	try {
        	 String signStr = "appId="+inputObj.getAppId()+"&params="+inputObj.getParams()+"&serviceCode="+inputObj.getServiceCode()+"&time="+inputObj.getTime();
    		 String secret = this.dictionaryDao.getValue("pointShopSecret");//"78nQJ+8BEjCk0w5CCqXvJ6lrpQ0/c7C/9MV0gAomiCU=";
    		 String sign = HMACUtil.encrypt(signStr, secret, "utf-8");
    		 logger.info("sign: "+sign);
    		 if(!sign.equals(inputObj.getSign())){
    			 throw new BussinessException("9060", "签名验证失败");
    		 }
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("验证签名出错，"+e.getMessage());
			if(e instanceof BussinessException) {
				throw e;
			}else {
				throw new BussinessException("9060", "签名验证出现异常，"+e.getMessage());
			}
		}
	}
	
	/**
	 * 检查服务编码
	 * @param inputObj
	 */
	private void checkServiceCode(ShopInObject inputObj) throws BussinessException {
		String serviceCode = inputObj.getServiceCode();
		//ZC2018JF001	会员充值
		//ZC2018JF002	订单查询
		if(!"ZC2018JF001".equals(serviceCode) && !"ZC2018JF002".equals(serviceCode)){
			throw new BussinessException("9062", "服务编码验证失败");
		}
	}
	
	/**
	 * 检查接口参数
	 * @param inputObj
	 */
	private void checkParams(ShopInObject inputObj) throws Exception {
		try {
			boolean result = true;
			decryptParams(inputObj); //解密参数
			String serviceCode = inputObj.getServiceCode();
			String params = inputObj.getParams();
			ObjectMapper mapper = new ObjectMapper();
			Map paramsMap = mapper.readValue(params, Map.class);
			//ZC2018JF001	会员充值
			//ZC2018JF002	订单查询
			if("ZC2018JF001".equals(serviceCode) && 
					(paramsMap.get("account") == null || paramsMap.get("orderNo") == null || paramsMap.get("goodsCode") == null || paramsMap.get("orderTime") == null)){
				result = false;
			}else if ("ZC2018JF002".equals(serviceCode) && 
					(paramsMap.get("orderId") == null || paramsMap.get("orderNo") == null)){
				result = false;
			}	
			if(!result){
				 throw new BussinessException("9064", "验证接口参数失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("验证接口参数出错，"+e.getMessage());
			if(e instanceof BussinessException) {
				throw e;
			}else {
				throw new BussinessException("9066", "验证接口参数出现异常，"+e.getMessage());
			}
		}
	}
	
	/**
	 * 检查手机号码
	 * @param inputObj
	 */
	private void checkMob(ShopInObject inputObj) throws Exception {
		 try {
			if("ZC2018JF001".equals(inputObj.getServiceCode())){//充值要验证手机号码
				String params = inputObj.getParams();
	            ObjectMapper mapper = new ObjectMapper();
	            Map paramsMap = mapper.readValue(params, Map.class);
	            /**
	             * 支持QQ号与手机号
	             * zzb 2020/02/18
	             */
	            String usermob = paramsMap.get("account").toString();
	            usermob = usermob.replaceAll("[\\s-]", "");
	            if(!usermob.matches("^[0-9]*$")){
	            	 throw new BussinessException("9057", "手机号码验证失败");
	            }else{
	            	if(usermob.length() < 11){//QQ号
	            		String goodsCode = paramsMap.get("goodsCode").toString();
	            		List<Map> goodsCodeList = pointShopDao.getPointShopConfigBySpid(goodsCode);
	                    if(goodsCodeList != null && goodsCodeList.size()>0){
	                    	Map goodsCodeMap = goodsCodeList.get(0);
	                		//判断是否配置netdays参数
	                		if(!"1".equals(goodsCodeMap.get("BUSITYPE"))){
	                			throw new BussinessException("9057", "QQ号只能订购纯会员产品");
	                		}
	                    }
	                }else if(!usermob.matches(".*(1\\d{10}).*")){
	                	throw new BussinessException("9057", "手机号码验证失败");
	                }
	            }
	            /*if(!isValid(paramsMap.get("account").toString())){
	            	 throw new BussinessException("9057", "手机号码验证失败");
	            }*/
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("验证手机号码出错，"+e.getMessage());
			if(e instanceof BussinessException) {
				throw e;
			}else {
				throw new BussinessException("9057", "验证手机号码出现异常，"+e.getMessage());
			}
		}
	}
	
	/**
	 * 检查商品编码
	 * @param inputObj
	 */
	private void checkGoodsCode(ShopInObject inputObj) throws Exception {
		if("ZC2018JF001".equals(inputObj.getServiceCode())){//充值要验证手机号码
			String params = inputObj.getParams();
            ObjectMapper mapper = new ObjectMapper();
            Map paramsMap = mapper.readValue(params, Map.class);
            String goodsCode = paramsMap.get("goodsCode").toString();
            //List<Map> goodsCodeList = pointShopDao.getPointShopConfig(goodsCode);
            //积分商城传的GOODSCODE是SPID,回调时GOODSCODE要传SPID值
            List<Map> goodsCodeList = pointShopDao.getPointShopConfigBySpid(goodsCode);
            if(goodsCodeList != null && goodsCodeList.size()>0){
            	Map goodsCodeMap = goodsCodeList.get(0);
        		//判断是否配置netdays参数
        		if(("2".equals(goodsCodeMap.get("BUSITYPE")) || "3".equals(goodsCodeMap.get("BUSITYPE"))) 
        				&& (goodsCodeMap.get("NETDAYS") == null || "".equals(goodsCodeMap.get("NETDAYS")))){
        			throw new BussinessException("9058", "无业务配置信息，NETDAYS");
        		}
            	inputObj.setGoodsCodeMap(goodsCodeMap);
            }else{
            	 throw new BussinessException("9058", "验证商品编码失败");
            }
		}
	}
	
	/**
	 * 判断是否有相同订单
	 * @param orderInfo
	 */
	private void checkOrderNo(ShopInObject inputObj) throws Exception {
		if("ZC2018JF001".equals(inputObj.getServiceCode())){//充值要验证重复
			String params = inputObj.getParams();
			JSONObject json = new JSONObject().fromObject(params);
			List<Map> list = pointShopDao.getOrderRecByOrderNo(json.getString("orderNo"));
			if(list != null && list.size() > 0){
				throw new BussinessException("9001", "重复订单，不处理");
			}
		}
	}
	
	/**
	 * 判断业务是否互斥
	 * @param orderInfo
	 * @return 返回互斥业务的ID，用于获取互斥业务名称发送短信
	 * @throws Exception
	 */
	private String checkMutual(ShopInObject inputObj) throws Exception {
		boolean result = false;
		String huchiSpid = "";
		if(!"ZC2018JF001".equals(inputObj.getServiceCode())){
			return huchiSpid;
		}
		Map goodsMap = getGoodsMap(inputObj);
		JSONObject paramsJson = getParams(inputObj);
		if(goodsMap != null && goodsMap.get("SPID") != null && paramsJson != null){
			String spid = goodsMap.get("SPID")+"";
			//查询SP产品信息
			List<HashMap> spList = pointShopDao.findSpInfo(spid);
			if(spList != null && spList.size()>0){
				if (spList.get(0).get("MUTEX") != null && !StringUtils.isEmpty(spList.get(0).get("MUTEX").toString())) {
					String[] mutexSpids = spList.get(0).get("MUTEX").toString().trim().split(",");
					//[{ORDERIDA=2019052, AREA=长沙, SPID=1167, PROVINCE=湖南, ID=201905241107578658666, ORDERCHANNEL=t, STATUS=1, ORDERTIME=20190524104129, USERID=18673197465, CPID=youtu}]
				    //查询用户本地订购关系表未失效的订购数据
				 	List<HashMap> list = pointShopDao.findOrderRelaAll(paramsJson.getString("account"));
					if (list != null && list.size() > 0) {
						for (String mutexSpid : mutexSpids) {
							for (HashMap hm : list) {
								if (hm.get("SPID") != null && !hm.get("SPID").equals(spid) && hm.get("SPID").equals(mutexSpid)
										&& !"2".equals(hm.get("STATUS"))) {
									huchiSpid = hm.get("SPID")+"";
									result = true;
									break;
								}
							}
							if(result){
								break;
							}
						}
					}
				}
			}
		}
		return huchiSpid;
	}
	
	/**
	 * 获取请求参数值
	 * @param inputObj
	 * @return
	 */
	private JSONObject getParams(ShopInObject inputObj){
		try {
        	String params = inputObj.getParams();
			JSONObject json = new JSONObject().fromObject(params);
			return json;
		} catch (Exception e) {}
		return null;
	}
	
	/**
	 * 获取商品信息
	 * @param inputObj
	 * @return
	 */
	private Map getGoodsMap(ShopInObject inputObj){
		try {
			if("ZC2018JF001".equals(inputObj.getServiceCode())){//充值要验证手机号码
				Map goodsMap = inputObj.getGoodsCodeMap();
				return goodsMap;
			}
		} catch (Exception e) {}
		return null;
	}
	
	/**
	 * 业务处理
	 * @param inputObj
	 * @return
	 * @throws Exception
	 */
	public ShopOutObject busiOper(ShopInObject inputObj){
		Map paramsLogMap = new HashMap();
		paramsLogMap.put("ENINPARAMS", JSON.toJSONString(inputObj)); //输入加密报文
		String errorcode = "-1";
		String errorinfo = "处理中";
		ShopOutObject outObj = new ShopOutObject();
		String requestId = this.getRequestId();
		String content = ""; //业务应答json加密串
		String huchiSpid = ""; //互斥业务ID
		String orderId = ""; //我侧订购流水号
		try {
			checkBusi(inputObj);
			huchiSpid = checkMutual(inputObj);
			if(!"".equals(huchiSpid)){
				throw new BussinessException("9003","已办理互斥业务");
			}
			String params = inputObj.getParams();
            ObjectMapper mapper = new ObjectMapper();
            Map paramsMap = mapper.readValue(params, Map.class);
            TreeMap<String, String> contentMap = new TreeMap<String, String>();
			if("ZC2018JF001".equals(inputObj.getServiceCode())){//充值要验证手机号码
	            String account = paramsMap.get("account").toString();
	            orderId = pointShopDao.getOrderId();
	            String orderNo = paramsMap.get("orderNo").toString();
	            contentMap.put("account", account);
	            contentMap.put("orderId", orderId);
	            contentMap.put("orderNo", orderNo);
	            content = mapper.writeValueAsString(contentMap);
	            PointShopOrderBean psoBean = this.fullPointShopOrderBean(inputObj);
	            
	            //办理省份限制验证开始
	            OrderInfo orderInfo = new OrderInfo();
	            orderInfo.setInvokeface("pointShop");
	            orderInfo.setSpid(psoBean.getSpid());
	            orderInfo.setProvince(psoBean.getProvince());
	            orderInfo.setArea(psoBean.getArea());
	            orderInfo.setChannel("pointShop");
	            commonService.valiProvinceLimit(orderInfo);
	            //办理省份限制验证结束
	            
	            psoBean.setId(orderId);
	            psoBean.setRequestId(requestId);
	            String starttime = "";
		        String endtime = "";
		        Map<String, String> reMap = this.getBusiTime(psoBean);
		        starttime = reMap.get("starttime");
		        endtime = reMap.get("endtime");
		        log.info("时间===="+reMap);
	            try{
	            	psoBean.setStarttime(starttime);
			        psoBean.setEndtime(endtime);
	            	pointShopDao.addBackOrderRec(psoBean); //添加到后向产品订购记录表
	            	pointShopDao.addOrderRec(psoBean); //添加积分商城订购记录表
	            }catch(Exception e){
	        		ByteArrayOutputStream buf=new ByteArrayOutputStream();
	    			e.printStackTrace(new PrintWriter(buf,true));
	    			String expMessage=buf.toString();
	    			if(expMessage.indexOf("ORA-00001")!=-1){  //超时异常}
	    				//System.out.println("=============+++++++++++++++====违反唯一约束");
	    				throw new BussinessException("9001", "重复订单，不处理");
	    			}else{
	    				throw e;
	    			}
	            }
	            
	            /*****20210119,不再推送队列，改为扫表异常处理
	            //actitve-process/src/com/chinacreator/process/job/PointShopSyncJob.java
	            inserPointShopMq(orderId, orderNo, requestId);//推送到队列异步处理
	            ******/

			}else{//查询订购信息
	            orderId = paramsMap.get("orderId").toString();
	            String orderNo = paramsMap.get("orderNo").toString();
	            PointShopOrderBean bean = pointShopDao.getOrderRecById(orderId);
	    		if(bean != null){
	    			contentMap.put("account",bean.getUserid());
	    			String orderStatus = "3";
	    			String reusltCode = bean.getResultCode();
	    			if("0".equals(reusltCode)){
	    				orderStatus = "2";
	    			}else if(bean.getFinishTime() == null || "null".equals(bean.getFinishTime()) || "".equals(bean.getFinishTime())
	    					|| "1".equals(reusltCode) || "2".equals(reusltCode)){
	    				orderStatus = "1";
	    			}else{ //充值失败，设置失败原因
	    				contentMap.put("failDesc",bean.getResultInfo());
	    			}
	    			contentMap.put("finishTime",bean.getFinishTime());
	    			contentMap.put("goodsCode",bean.getSpid());
	    			contentMap.put("orderId",bean.getId());
	    			contentMap.put("orderNo",bean.getOrderNo());
	    			contentMap.put("orderStatus",orderStatus);
	    			contentMap.put("orderTime",bean.getOrderTime());
	    			content = mapper.writeValueAsString(contentMap);
	    		}else{
	                errorcode = "9999";
	                errorinfo = "无此订单，"+orderId;
	    		}
			}
			
            errorcode = "0";
            errorinfo = "成功";
            
		} catch (Exception e) {
			e.printStackTrace();
			if(e instanceof BussinessException) {
				errorcode = ((BussinessException) e).getCode();
				errorinfo = ((BussinessException) e).getMessage();
				if(errorinfo.length()>250){
					errorinfo = errorinfo.substring(0, 250);
				}
				printLog(inputObj,errorcode,errorinfo);
				//throw e;
			}else {
				errorcode = "8000";
				errorinfo = "业务处理出现异常，"+e.getMessage();
				printLog(inputObj,errorcode,errorinfo);
				//throw new BussinessException(errorcode, "业务处理出现异常，"+e.getMessage());
			}
		} finally{
			outObj.setCode(errorcode);
			outObj.setContent(content);
			outObj.setMessage(errorinfo);
			outObj.setRequestId(requestId);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
			outObj.setTime(sdf.format(new Date()));
			
			paramsLogMap.put("REQUESTID", requestId);
			//参数未解密，先解密，用于记录日志
			if("9050".equals(errorcode) || "9060".equals(errorcode) || "9062".equals(errorcode)){
				try{
					this.checkParams(inputObj);
				}catch(Exception e){}
			}
			paramsLogMap.put("INPARAMS", JSON.toJSONString(inputObj));  //输入报文
			this.fullContent(inputObj,outObj);
			paramsLogMap.put("OUTPARAMS", JSON.toJSONString(outObj));//输出报文
			convertCode(outObj); //转换code
			this.setOutPutSign(outObj); //输出参数签名加密
			paramsLogMap.put("DNOUTPARAMS", JSON.toJSONString(outObj));//输出加密报文

			//记录输入输出报文
			this.addOrderParamsLog(paramsLogMap);
			if("9003".equals(errorcode)){ //业务互斥记录订购日志
				this.saveOrderLog(inputObj, errorcode, errorinfo);
			}
			//发送业务互斥短信
/*			if("9003".equals(errorcode)){ //业务互斥
				//取互斥产品名称，发送失败短信
				try {
					List<HashMap> spList = pointShopDao.findSpInfo(huchiSpid);
					if(spList != null && spList.size()>0 && spList.get(0).get("SPNAME") != null){
						String huchiSpName = spList.get(0).get("SPNAME").toString();
						this.inserSmstMq(inputObj,huchiSpName); //发送业务互斥短信
					}			
				} catch (Exception e) {
					log.error("requestId=>"+requestId+"，获取互斥业务名称出现异常，"+e.getMessage());
				}
			}*/
			log.info("requestId=>"+requestId+",errorcode=>"+errorcode+",errorinfo=>"+errorinfo);
		}
		return outObj;
	}

	/**
	 * 查询本地订购关系表当前是否有已生效的订购关系
	 * @param pointShopOrder
	 * @return
	 * @throws Exception
	 */
	private Map hasEffect(PointShopOrderBean pointShopOrder) throws Exception {
		Map reMap = new HashMap();
		boolean hasEffect = false;
        boolean hasEffectMonth=false;
		Map currOrderInfo = null;
		String currentTime = pointShopDao.currTime();
		log.info("pointShopOrder=>" + pointShopOrder.getUserid() + ", " + pointShopOrder.getCpid() + " , "
				+ pointShopOrder.getSpid());
		//查询用户本地订购关系表未失效的订购数据
		currOrderInfo = pointShopDao.findByUserAndSpid(pointShopOrder.getUserid(),pointShopOrder.getCpid(),pointShopOrder.getSpid());
		if(currOrderInfo != null){//本地有订购关系
			if(Long.parseLong(currOrderInfo.get("ENDTIME").toString()) >= Long.parseLong(currentTime)){ //结束时间大于或等于当前时间，订购关系有效
				hasEffect = true;
			}
            if(currentTime.substring(0,6).equals(currOrderInfo.get("ENDTIME").toString().substring(0,6))){ //本月订购的
                hasEffectMonth = true;
            }
		}
		reMap.put("hasEffect", hasEffect);
		reMap.put("currOrderInfo", currOrderInfo);
        reMap.put("hasEffectMonth",hasEffectMonth);
		return reMap;
	}
	
	private void convertCode(ShopOutObject outObj){
		/*
"9050", "timestamp已失效"
"9060", "签名验证失败"
"9062", "服务编码验证失败"
"9064", "验证接口参数失败"
"9066", "验证接口参数出现异常
"9057", "手机号码验证失败"
"9058", "验证商品编码失败"
"9001", "重复订单，不处理"
"9003", "已办理互斥业务"
"9065", "APPID验证失败"

"8000", "业务处理出现异常
		 */
		String code = outObj.getCode();
		if("0".equals(code)){
			code = "0000";
		}else if("9001".equals(code)){
			code = "0001"; //0001	原流水重发，成功
		}else if("9065".equals(code)){
			code = "1001"; //1001	无此渠道编码
		}else if("9060".equals(code)){
			code = "1002"; //1002	签名不正确
		}else if("9066".equals(code)){
			code = "1003"; //1003	解密失败
		}else if("9057".equals(code) || "9058".equals(code)){
			code = "1101"; //1101	参数格式不正确
		}else if("9064".equals(code)){
			code = "1102"; //1102	缺少参数
		}else if("9003".equals(code)){//业务互斥
			code = "1201"; //12**   下单失败
		}else if("9062".equals(code)){ //服务编码验证失败
			code = "1204"; //12**   下单失败	
		//}else if( "9051".equals(code) || "9053".equals(code)){
			//code = "1202"; //12**   下单失败	
		}else if("9050".equals(code)){ //timestamp已失效
			code = "1203"; //12**   下单失败			
		}else if("8000".equals(code)){
			code = "9999"; //内部服务异常
		}
		outObj.setCode(code);
	}
	
	/**
	 * 填充content
	 * @param inputObj
	 * @param outObj
	 */
	private void fullContent(ShopInObject inputObj, ShopOutObject outObj){
		try {
			String content = outObj.getContent();
			if("ZC2018JF001".equals(inputObj.getServiceCode()) 
					&& (content == null || "".equals(content))){
				JSONObject paramsJson = this.getParams(inputObj);
				if(paramsJson != null){
			        TreeMap<String, String> contentMap = new TreeMap<String, String>();
			        contentMap.put("account", paramsJson.getString("account"));
			        contentMap.put("orderNo", paramsJson.getString("orderNo"));
			        outObj.setContent(JSON.toJSONString(contentMap));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error("requestId=>"+outObj.getRequestId()+"，填充content出现异常"+e.getMessage());
		}		
	}
	
	/**
	 * 添加输出报文日志
	 * @param paramsLogMap
	 */
	private void addOrderParamsLog(Map paramsLogMap){
		try {
			pointShopDao.addOrderParamsLog(paramsLogMap);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("记录参数日志出现异常，"+e.getMessage());
		}
	}
	
	
	/**
	 * 获取系统时间，精确到毫秒
	 * @return
	 */
	private String getSystemTime(){
		SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		dateformat.setTimeZone(TimeZone.getDefault());
		String systemTime = String.valueOf(dateformat.format(System.currentTimeMillis()));
		return systemTime;
	}
	
	/**
	 * 获取6位随机数
	 * @return
	 */
	private String getRandNum(){
		int romNum = (int)((Math.random()*9+1)*100000);
		return romNum+"";
	}
	
	/**
	 * 获取请求ID
	 * @return
	 */
	private String getRequestId(){
		String requestId = this.getSystemTime()+this.getRandNum();
		return requestId;
	}
	
	/**
	 * 充值时填充PointShopOrderBean
	 * @param inputObj
	 * @return
	 */
	private PointShopOrderBean fullPointShopOrderBean(ShopInObject inputObj){
		PointShopOrderBean bean = new PointShopOrderBean();
		//bean.setId(pointShopDao.getRequestId());
		String params = inputObj.getParams();
		JSONObject json = new JSONObject().fromObject(params);
		//bean.setGoodsCode(json.getString("goodsCode"));
		bean.setOrderNo(json.getString("orderNo"));
		bean.setOrderTime(json.getString("orderTime"));
		bean.setUserid(json.getString("account"));
		List<Map> areaList = pointShopDao.getAreaInfo(bean.getUserid().substring(0,7));
		if(areaList != null && areaList.size()>0){
			Map areaMap = areaList.get(0);
			bean.setProvince(areaMap.get("PROVINCE")==null?"QQ号订购":areaMap.get("PROVINCE").toString());
			bean.setArea(areaMap.get("AREA")==null?"QQ号订购":areaMap.get("AREA").toString());
		}else{
			bean.setProvince("QQ号订购");
			bean.setArea("QQ号订购");
		}
		Map goodsCodeMap = inputObj.getGoodsCodeMap();
		String busiType = goodsCodeMap.get("BUSITYPE").toString();
		//赠送会员状态，0成功，1待赠送，2赠送中，3失败，4不赠送
		bean.setVipstatus("1");
		bean.setBusiType(busiType);
		if("2".equals(busiType)){
			bean.setVipstatus("4");
		}
		bean.setCpid((String)goodsCodeMap.get("CPID"));
		bean.setSpid((String)goodsCodeMap.get("SPID"));
		if(goodsCodeMap.get("GOODSCODE") == null){
			bean.setGoodsCode("");
		}else{
			bean.setGoodsCode((String)goodsCodeMap.get("GOODSCODE"));
		}
		
/*		if(goodsCodeMap.get("VIPPOOL") != null){
			bean.setVippool(goodsCodeMap.get("VIPPOOL").toString());
		}
		if(goodsCodeMap.get("VIPTYPE") != null){
			bean.setViptype(goodsCodeMap.get("VIPTYPE").toString());
		}*/
		//办理结果编码，0成功，1待处理，2处理中，其他为异常
		bean.setResultCode("1");
		bean.setResultInfo("待处理");
		bean.setServiceCode(inputObj.getServiceCode());
		bean.setAppId(inputObj.getAppId());

		
		return bean;
	}
	
	/**
	 * 解密参数
	 * @param inputObj
	 * @throws Exception
	 * @throws BussinessException
	 */
    private void decryptParams(ShopInObject inputObj) throws Exception {
    	Map paramMap = new HashMap();
    	String aeskey = this.dictionaryDao.getValue("pointShopAeskey");//"78nQJ+8BEjCk0w5CCqXvJw==";
    	String params = inputObj.getParams();
		String deparams = SignUtil.decrypt(params,aeskey);
		JSONObject json = new JSONObject().fromObject(deparams);
		if("ZC2018JF001".equals(inputObj.getServiceCode())){//充值
			paramMap.put("account", json.get("account"));
			paramMap.put("orderNo", json.get("orderNo"));
			paramMap.put("goodsCode", json.get("goodsCode"));
			paramMap.put("orderTime", json.get("orderTime"));
		}else{//查询
			paramMap.put("orderId", json.get("orderId"));
			paramMap.put("orderNo", json.get("orderNo"));
		}
		inputObj.setParams(JSON.toJSONString(paramMap));
    }
	
    /**
     * 设置返回签名数据，加密content
     * @param outObj
     */
    private void setOutPutSign(ShopOutObject outObj){
    	try {
    		String aeskey = this.dictionaryDao.getValue("pointShopAeskey");//"78nQJ+8BEjCk0w5CCqXvJw==";
    		if(outObj.getContent() != null && !"".equals(outObj.getContent())){
        		outObj.setContent(SignUtil.encrypt(outObj.getContent(),aeskey));
    		}
    	    String signStr = "code="+outObj.getCode()+"&content="+outObj.getContent()+"&message="+outObj.getMessage()+"&requestId="+outObj.getRequestId()+"&time="+outObj.getTime();
    		String secret = this.dictionaryDao.getValue("pointShopSecret");//"78nQJ+8BEjCk0w5CCqXvJ6lrpQ0/c7C/9MV0gAomiCU=";
    		String sign = HMACUtil.encrypt(signStr, secret, "utf-8");
    		outObj.setSign(sign);
    		logger.info("sign: "+sign);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("RequestId=>"+outObj.getRequestId()+", 设置返回签名数据出现异常，"+e.getMessage());
		}
    }
    
	/**
	 * 
	 * @param usermob
	 * @return
	 */
	private boolean isValid(String usermob){
        if (usermob == null) {
            return false;
        }
        usermob = usermob.replaceAll("[\\s-]", "");
        if(usermob.length() != 11){
        	return false;
        }
        return usermob.matches(".*(1\\d{10}).*");	    
	}
	
	/**
	 * 输出错误日志
	 * @param inputObj
	 * @param errorcode
	 * @param errorinfo
	 */
	private void printLog(ShopInObject inputObj, String errorcode, String errorinfo){
		String userid = "";
		String orderId = "";
		String serverCode = "";
		try {
			serverCode = inputObj.getServiceCode();
			String params = inputObj.getParams();
			ObjectMapper mapper = new ObjectMapper();
			if(params != null && !"".equals(params) && !"null".equals(params)){
				Map paramsMap = mapper.readValue(params, Map.class);
				userid = paramsMap.get("account")+"";
				orderId = paramsMap.get("orderId")+"";
			}
		}catch (Exception e) {
			
		}

		log.error("serviceCode:"+serverCode+", orderId:"+orderId+",userid:"+userid+"业务处理出现异常，"+errorcode+", "+errorinfo);
	}
		 
    /**
     * 推送到队列进行处理
     * @param orderId TD_POINTS_ORDER_REC表ID字段，我方生成的订单流水号
     * @param orderNo 积分商城订单号
     * @param requestId 返回给客户的请求ID
     */
	public void inserPointShopMq(String orderId, String orderNo, String requestId){
		try{
			Map<String, String> map = new HashMap<String, String>();
			map.put("orderId", orderId);
			map.put("orderNo", orderNo);
			map.put("requestId", requestId);
			map.put("type", "pointShop");	
			logger.info("积分商城推送到队列进行处理参数："+map);
			String mqReciveUrl = dictionaryDao.getValue("mqReciveUrl");
			//开发环境
			//URLUtil.post("http://127.0.0.1:8082/mq-service/recive.do", JSON.toJSONString(map));
			//测试环境
			//URLUtil.post("http://10.199.99.177:86/mq-service/recive.do", JSON.toJSONString(map));
			//生产环境				
			//URLUtil.post("http://10.199.99.144:8090/mq-service/recive.do", JSON.toJSONString(map));	
			
			URLUtil.post(mqReciveUrl, JSON.toJSONString(map));
		}catch (Exception e){
			e.printStackTrace();
		}
	}
	
	/**
	 * 发送业务互斥短信
	 * @param inputObj
	 * @param huchiSpName 互斥产品
	 */
	public void inserSmstMq(ShopInObject inputObj, String huchiSpName){
		try{
			String params = inputObj.getParams();
			ObjectMapper mapper = new ObjectMapper();
			Map paramsMap = mapper.readValue(params, Map.class);
			Map goodsCodeMap = inputObj.getGoodsCodeMap();
			String bt = goodsCodeMap.get("BUSITYPE").toString();
			//免流，或者免流+会员，业务互斥要发短信
			if(("2".equals(bt) || "3".equals(bt))){
				String succFlag = "fail";
				String busiType = "tran_cdn_fail"; //免流业务互斥短信
				if("3".equals(bt)){
					busiType = "tran_vipcdn_cdnfail"; //免流+会员业务互斥短信
				}

				Map<String, String> map = new HashMap<String, String>();
				map.put("userid", paramsMap.get("account").toString());
				map.put("cpid", goodsCodeMap.get("CPID").toString());
				map.put("spid", goodsCodeMap.get("SPID").toString());
				map.put("result", "0");
				map.put("channel", "");
				map.put("param1", huchiSpName);
				map.put("style","0000");
				map.put("times", "");
				map.put("orderType", "");
				map.put("type", "cssms");
				map.put("busiType", busiType);
				String mqReciveUrl = dictionaryDao.getValue("mqReciveUrl");
				//开发环境
				//URLUtil.post("http://172.16.33.16:8082/mq-service/recive.do", JsonUtil.objectToJson(map));
				//测试环境
				//URLUtil.post("http://10.199.99.177:86/mq-service/recive.do", JsonUtil.objectToJson(map));
				//生产环境				
				//URLUtil.post("http://10.199.99.144:8090/mq-service/recive.do", JsonUtil.objectToJson(map));
				
				URLUtil.post(mqReciveUrl, JSON.toJSONString(map));
			}
		}catch (Exception e){
			e.printStackTrace();
		}
	}
	
	/**
	 * 判断是否为数字格式不限制位数
	 * @param o
	 *     待校验参数
	 * @return
	 *     如果全为数字，返回true；否则，返回false
	 */
	private boolean isNumber(Object o){
	    return  (Pattern.compile("[0-9]*")).matcher(String.valueOf(o)).matches();
	}
	
	/**
	 * 写订购日志
	 * @param orderId 我侧订购流水号
	 */
	private void saveOrderLog(ShopInObject inputObj, String errorcode, String errorinfo){
		String userid = "";
		try {
			PointShopOrderBean psoBean = this.fullPointShopOrderBean(inputObj);
			OrderLog orderLog = new OrderLog();
			orderLog.setApptype("2");
			orderLog.setArea(psoBean.getArea());
			orderLog.setChannel(psoBean.getAppId());
			orderLog.setOrderstatus(0);
			orderLog.setStatus(0);
			orderLog.setCpid(psoBean.getCpid());
			orderLog.setIsexperience(0);
			orderLog.setOrdertype("0");
			orderLog.setProvince(psoBean.getProvince());
			orderLog.setSpid(psoBean.getSpid());
			orderLog.setErrorcode(errorcode);
			orderLog.setErrorinfo(errorinfo);		
			orderLog.setUserid(psoBean.getUserid());
			userid = orderLog.getUserid();
			this.pointShopDao.addOrderLog(orderLog);
		} catch (Exception e) {
			log.error("userid: "+userid+", 添加日志出现异常，"+e.getMessage());
			e.printStackTrace();
		}	
	}
	
/*	*//**
	 * 获取开始时间和结束时间
	 * @param orderInfo
	 * @return
	 * @throws Exception
	 *//*
	private Map<String, String> getBusiTime(PointShopOrderBean orderInfo)throws Exception{
		Map<String, String> resMap = new HashMap<String, String>();
		String starttime = ""; //业务开始时间
		String endtime = "";   //业务结束时间
		String currEndtime = "";
		Map reMap = this.hasEffect(orderInfo);
		if((Boolean)reMap.get("hasEffect")){ //存在有效订购关系
			Map currOrderInfo = (Map)reMap.get("currOrderInfo");
			currEndtime = (String)currOrderInfo.get("ENDTIME");
		}
		//[{PWD=kijkfds, NETDAYS=31, CHANNEL=test_01, NETDAYS=2, SPID=1168, BUSITYPE=3, CPID=youtu}]
		//HashMap confHm = backBusiOrderDao.getBackBusiConf(orderInfo.getCpid(), orderInfo.getSpid()).get(0);
		HashMap confHm = (HashMap)pointShopDao.getPointShopConfigBySpid(orderInfo.getSpid()).get(0);
		//String busiType = confHm.get("BUSITYPE")+"";
		//免流或免流+会员两种产品要以netdays参数来确定endtime
		if("2".equals(confHm.get("BUSITYPE")) || "3".equals(confHm.get("BUSITYPE"))){
			if(currEndtime != null && !"".equals(currEndtime)){			
				endtime = pointShopDao.endtimeParamDay(confHm.get("NETDAYS")+"", currEndtime);
			}else{
				endtime = pointShopDao.currParamDay(confHm.get("NETDAYS")+"");
			}
			
			starttime = pointShopDao.getStartTime(endtime,confHm.get("NETDAYS")+"");
		}

		resMap.put("starttime", starttime);
		resMap.put("endtime", endtime);
		return resMap;
	}*/
    /**
     * 获取开始时间和结束时间
     * @param orderInfo
     * @return
     * @throws Exception
     */
    private Map<String, String> getBusiTime(PointShopOrderBean orderInfo)throws Exception {
        Map<String, String> resMap = new HashMap<String, String>();
        String starttime = ""; //业务开始时间
        String endtime = "";   //业务结束时间
        String currEndtime = "";
        Map reMap = this.hasEffect(orderInfo);
        HashMap confHm = (HashMap) pointShopDao.getPointShopConfigBySpid(orderInfo.getSpid()).get(0);
        //只针对日包的
        if ((Boolean)reMap.get("hasEffectMonth")){
            if("4".equals(confHm.get("ENDTYPE"))){
                throw new BusinessException("9005","本月已订购，请勿重复订购");
            }
        }
        if((Boolean)reMap.get("hasEffect")){ //存在有效订购关系
            if("1".equals(confHm.get("ENDTYPE"))){
                throw new BusinessException("9005","本月已订购，请勿重复订购");
            }
            Map currOrderInfo = (Map)reMap.get("currOrderInfo");
            currEndtime = (String)currOrderInfo.get("ENDTIME");
        }
        //[{PWD=kijkfds, NETDAYS=31, CHANNEL=test_01, NETDAYS=2, SPID=1168, BUSITYPE=3, CPID=youtu}]
        //String busiType = confHm.get("BUSITYPE")+"";
        //业务类型，1会员，2免流，3会员+免流
        //ENDTYPE: 1:结束时间到月底且不能重复订购,2:结束时间到月底且能重复订购，结束时间累加一个月,3:结束时间到月底,能重复订购,结束时间不累加。其余结束时间按netdays算且能重复订购
        //免流或免流+会员两种产品要以netdays参数来确定endtime
        if("2".equals(confHm.get("BUSITYPE")) || "3".equals(confHm.get("BUSITYPE"))){
            if(currEndtime != null && !"".equals(currEndtime)){

                if("3".equals(confHm.get("ENDTYPE"))){
                    endtime = pointShopDao.endtimeTheMonthLastDay();
                }else if("2".equals(confHm.get("ENDTYPE"))){
                    endtime = pointShopDao.endtimeNextMonthLastDay(currEndtime);
                }else{
                    endtime = pointShopDao.endtimeParamDay(confHm.get("NETDAYS")+"", currEndtime);
                }
            }else{
                if("1".equals(confHm.get("ENDTYPE")) || "2".equals(confHm.get("ENDTYPE"))|| "3".equals(confHm.get("ENDTYPE"))){
                    endtime = pointShopDao.endtimeTheMonthLastDay(); //特殊产品的结束时间只到本月底
                }else {
                    endtime = pointShopDao.currParamDay(confHm.get("NETDAYS")+"");
                }
            }
            if("1".equals(confHm.get("ENDTYPE")) || "2".equals(confHm.get("ENDTYPE")) || "3".equals(confHm.get("ENDTYPE"))){
                starttime = pointShopDao.getKsStartTime(); //特殊产品开始时间就是当天
            }else{
                starttime = pointShopDao.getStartTime(endtime,confHm.get("NETDAYS")+"");
            }
        }

        resMap.put("starttime", starttime);
        resMap.put("endtime", endtime);
        return resMap;
    }
}
