package com.chinacreator.video.service;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.chinacreator.video.bean.ChannelBean;
import com.chinacreator.video.bean.OrderInfo;
import com.chinacreator.video.bean.OrderLog;
import com.chinacreator.video.exception.BussinessException;
import com.chinacreator.video.mapper.ChannelBusiLimitDao;
import com.chinacreator.video.mapper.CommConfDao;
import com.chinacreator.video.mapper.DictionaryDao;
import com.chinacreator.video.util.OtherProperties;
import com.chinacreator.video.util.RedisService;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 公共服务
 * @author xu.zhou
 * @date 20200326
 */
@Component
public class CommonService {

    private static final  Logger logger = LoggerFactory.getLogger(CommonService.class);
    
    private Logger calllogger = LoggerFactory.getLogger("callSendco");

    @Autowired
    private CommConfDao commConfDao;

    @Autowired
    private OtherProperties otherProperties;

    @Autowired
    RedisService redisService;
    
    @Autowired
    private DictionaryDao dictionaryDao;
    
	@Autowired
	private ChannelBusiLimitDao cblDao;

    /**
     * 获取业务互斥信息
     * @param spid
     * @throws Exception
     */
    public String getMutex(String spid) throws Exception {
        String mutex = "";
        List<HashMap> spInfoList = commConfDao.findSpInfo(spid);
        if (spInfoList != null && spInfoList.size() > 0) {
            HashMap hm = spInfoList.get(0);
            if(hm.get("MUTEX") != null && !"".equals(hm.get("MUTEX")) && !"null".equals(hm.get("MUTEX"))){
                mutex = hm.get("MUTEX").toString();
            }
        }
        return mutex;
    }

    /**
     * 判断业务是否互斥
     * @param userid 手机号码
     * @param spid spid
     * @return true互斥，false不互斥
     * @throws Exception
     */
    public boolean checkMutual(String userid, String spid) throws Exception{
        boolean result = false;
        String mutex = getMutex(spid);
        if(mutex != null && !"".equals(mutex)){
            String[] mutexSpids = mutex.trim().split(",");
            List<HashMap> orderList = commConfDao.findOrderRelaAll(userid);
            if (orderList != null && orderList.size() > 0) {
                for (String mutexSpid : mutexSpids) {
                    for (HashMap hm : orderList) {
                        if (hm.get("SPID") != null && !hm.get("SPID").equals(spid) && hm.get("SPID").equals(mutexSpid)
                                && !"2".equals(hm.get("STATUS"))) {
                            result = true;
                            break;
                        }
                    }
                }
            }
        }

        return result;
    }

    /**
     * 判断是否已订购
     * @param userid 手机号码
     * @param spid spid
     * @return true已订购，false未订购
     * @throws Exception
     */
    public boolean checkdupOrder(String userid, String spid) throws Exception{
        boolean result = false;

        List<HashMap> orderList = commConfDao.findOrderRelaAll(userid);
        if (orderList != null && orderList.size() > 0) {
            for (HashMap hm : orderList) {
                if (spid.equals(hm.get("SPID")) && "0".equals(hm.get("STATUS"))) {//已订购
                    result = true;
                    break;
                }
            }
        }

        return result;
    }

    /**
     * 获取当前订购关系表的业务状态，判断是否互斥
     * @param userid
     * @param spid
     * @return orderStatus 订购状态，空：未订购，0：已订购，1： 已退订，2已失效， hasMutual true已办理互斥业务，false未办理互斥业务, RELID订购关系表ID，canceltime退订时间，endtime结束时间
     * @throws Exception
     */
    public HashMap getOrderStatus(String userid, String spid)throws Exception{
        HashMap<String, Object> remap = new HashMap<String, Object>();
        List<HashMap> orderList = commConfDao.findOrderRelaAll(userid);
        String orderStatus = ""; //订购状态，空：未订购，0：已订购，1： 已退订，2已失效
        String orderTime = ""; //订购状态，空：未订购，0：已订购，1： 已退订，2已失效
        String cancelTime = ""; //退订时间
        String endTime = ""; //结束时间
        String relid = ""; //订购关系表ID
        boolean hasMutual = false; //是否办理了互斥业务
        if (orderList != null && orderList.size() > 0) {
            for (HashMap hm : orderList) {
                if (spid.equals(hm.get("SPID"))) {//已订购
                    relid = (String)hm.get("ID");
                    orderStatus = (String)hm.get("STATUS");
                    orderTime = (String)hm.get("ORDERTIME");
                    cancelTime = (String)hm.get("CANCELTIME");
                    endTime = (String)hm.get("ENDTIME");
                    if("1184".equals(spid) && "1".equals(orderStatus) && hm.get("CANCELTIME") == null){
                        orderStatus = "0";
                    }
                    break;
                }
            }
            String mutex = getMutex(spid);
            if(mutex != null && !"".equals(mutex)){
                String[] mutexSpids = mutex.trim().split(",");
                for (String mutexSpid : mutexSpids) {
                    for (HashMap hm : orderList) {
                        if (hm.get("SPID") != null && !hm.get("SPID").equals(spid) && hm.get("SPID").equals(mutexSpid)
                                && !"2".equals(hm.get("STATUS"))) {
                            hasMutual = true;
                            break;
                        }
                    }
                }
            }
        }
        remap.put("ORDERSTATUS", orderStatus);
        remap.put("HASMUTUAL", hasMutual);
        remap.put("RELID", relid);
        remap.put("orderTime", orderTime);
        remap.put("cancelTime", cancelTime);
        remap.put("endTime", endTime);
        
        return remap;
    }

    /**
     * 访问并发控制验证，KEY无固定前缀
     * @param params 要限制的参数，数组
     * @param params
     * @param invokename
     * @return false允许访问，true并发限制
     */
    public boolean vistVali(String [] params, String invokename) throws Exception{
        boolean res = false;
        if(params == null || params.length == 0){
            return res;
        }
        long expireTime = 0;
        try{
            //访问过期 时间，单位秒
            expireTime = Long.parseLong(otherProperties.getEnv().getProperty(invokename+"_vistexpireTime"));
        }catch(Exception e){
            expireTime = 60;
        }
        String vistkey = "";
        for(String param : params){
            vistkey += "_"+param;
        }
        vistkey = vistkey.substring(1);
        Object obj = redisService.get(vistkey);
        if(obj != null){
            //获取key的过期时间
            long expire = redisService.getExpire(vistkey);
            if(expire <= 0){//有可能KEY没有设置过期时间，移除些KEY
                redisService.remove(vistkey);
            }else{
                res = true;
            }
        }else{
            redisService.set(vistkey, new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()), expireTime);
        }

        return res;
    }

    /**
     * 访问并发验证限制 KEY带固定前缀为VIST："VIST_"+CHANNEL+"_"+USERID+"_"+SPID，值为 INCR 增值为1
     * @param params 要限制的参数，数组
     * @param params
     * @param invokename
     * @return false允许访问，true并发限制
     */
    public boolean vistVali2(String [] params, String invokename) throws Exception{
        boolean res = false;
        if(params == null || params.length == 0){
            return res;
        }
        String vistkey = "";
        try {
			long expireTime = 0;
			try{
			    //访问过期 时间，单位秒
			    expireTime = Long.parseLong(otherProperties.getEnv().getProperty(invokename+"_vistexpireTime"));
			}catch(Exception e){
			    expireTime = 60;
			}
			for(String param : params){
			    vistkey += "_"+param;
			}
			vistkey = vistkey.substring(1);
			vistkey = "VIST_"+vistkey;
			long userLock = redisService.incr(vistkey, 1); //加锁
			if(userLock == 1){ //正常锁定
				//设置KEY过期时间
				redisService.expire(vistkey, expireTime);
			}else if(userLock > 1){//并发
				long tmpexpire = redisService.getExpire(vistkey);
				if(tmpexpire <= 0){//过期时间未设置成功，删除key
					redisService.remove(vistkey); //删除
					logger.error("过期时间未设置成功，删除key，tmpexpire："+tmpexpire);
				}else{
					redisService.decr(vistkey, 1); //回退
					res = true;
				}
			}else{//异常
				redisService.remove(vistkey); //删除
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("设置并发控制出现异常，vistkey："+vistkey);
		}

        return res;
    }

    /**
     * 设置地市省份信息
     * @param orderInfo
     * @throws Exception
     */
    public void setAreaInfo(OrderInfo orderInfo)throws Exception{
        List<Map> areaList = null;
        Object i = commConfDao.getAreaInfo(orderInfo.getUserid().substring(0,7));
        if(i!=null) {
            logger.info(i.toString());
        }
        areaList = commConfDao.getAreaInfo(orderInfo.getUserid().substring(0,7));
        if(areaList != null && areaList.size()>0){
            Map areaMap = areaList.get(0);
            orderInfo.setProvince(areaMap.get("PROVINCE").toString());
            orderInfo.setArea(areaMap.get("AREA").toString());
        }else{
            orderInfo.setProvince("");
            orderInfo.setArea("");
        }
    }

    /**
     * 获取地市省份信息
     * @param userid
     * @return
     * @throws Exception
     */
    public HashMap<String, String> getAreaInfo(String userid)throws Exception{
        HashMap<String, String> remap = new HashMap<String, String>();
        List<Map> areaList = commConfDao.getAreaInfo(userid.substring(0,7));
        if(areaList != null && areaList.size()>0){
            Map areaMap = areaList.get(0);
            remap.put("PROVINCE", areaMap.get("PROVINCE").toString());
            remap.put("AREA", areaMap.get("AREA").toString());
        }
        return remap;
    }

    /**
     * 记录订购日志
     * @param orderInfo
     * @param errorcode
     * @param errorinfo
     */
    public void saveLog(OrderInfo orderInfo, String errorcode, String errorinfo) {
        try {
            OrderLog orderLog = new OrderLog();
            orderLog.setApptype(orderInfo.getApptype());
            orderLog.setArea(orderInfo.getArea());
            if(orderInfo.getOrderchannel() != null){
                orderLog.setChannel(orderInfo.getOrderchannel());
            }else{
                orderLog.setChannel(orderInfo.getCancelchannel());
            }
            orderLog.setOrderstatus(orderInfo.getOrderstatus());
            orderLog.setStatus(Integer.parseInt(orderInfo.getStatus()));
            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);
            if(!StringUtils.isEmpty(orderInfo.getTimes())){
                try {
					orderLog.setTimes((System.currentTimeMillis()-NumberUtils.toLong(orderInfo.getTimes()))+"");
				} catch (Exception e) {}
            }
            this.commConfDao.addOrderLog(orderLog);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("记录订购日志出现异常，"+e.getMessage());
        }
    }

    /**
     * 添加订单ID与订购关系的关联记录
     * @param orderInfo
     */
    public void addRelidRec(OrderInfo orderInfo){
        try {
            HashMap<String, String> params = new HashMap<String, String>();
            params.put("RELID", orderInfo.getId());
            params.put("STATUS", orderInfo.getType());
            if("0".equals(orderInfo.getType())){
                params.put("ORDERCHANNEL", orderInfo.getOrderchannel());
                params.put("ORDERID", orderInfo.getOrderid() != null ? orderInfo.getOrderid():"");
                params.put("ORDERNO", params.get("ORDERID"));
                params.put("CHANNEL", params.get("ORDERCHANNEL"));
                this.commConfDao.addOrderRelidRec(params);
            }else{
                params.put("CANCELCHANNEL", orderInfo.getCancelchannel());
                params.put("CANCELID", orderInfo.getOrderid() != null ? orderInfo.getOrderid():"");
                params.put("ORDERNO", params.get("CANCELID"));
                params.put("CHANNEL", params.get("CANCELCHANNEL"));
                this.commConfDao.addCancelRelidRec(params);
            }
            this.commConfDao.addRelidLog(params);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("添加订单ID与订购关系的关联记录出现异常，"+e.getMessage());
        }
    }

    /**
     * 设定操作时间及渠道信息
     * @param orderInfo
     */
    public void setOperTime(OrderInfo orderInfo) throws Exception {
        String currentTime = commConfDao.getCurrtime();
        if("1".equals(orderInfo.getType())){
            orderInfo.setStatus("1");
            orderInfo.setCancelchannel(orderInfo.getChannel());
            if (orderInfo.getCanceltime() != null) {
                orderInfo.setEndtime(getEndTime(orderInfo.getCanceltime()));
            }else{
                orderInfo.setCanceltime(currentTime);
            }
            if (orderInfo.getEffecttime() == null) {
                orderInfo.setEffecttime(currentTime);
            }
            if (orderInfo.getEndtime() == null) {
                orderInfo.setEndtime(commConfDao.getEndDayOfCurrentMonth());
            }
        }else if("0".equals(orderInfo.getType())){
            orderInfo.setOrdertime(currentTime);
            orderInfo.setStatus("0");
            orderInfo.setOrderchannel(orderInfo.getChannel());
            orderInfo.setEffecttime(currentTime);
        }
    }

    public String getEndTime(String endTimeStr) throws ParseException {
        Calendar calendar = Calendar.getInstance();
        Date date = DateUtils.parseDate(endTimeStr.substring(0, 8), new String[] { "yyyyMMdd" });
        calendar.setTime(date);
        String day = calendar.getActualMaximum(Calendar.DAY_OF_MONTH) + "";
        String year = calendar.get(Calendar.YEAR) + "";
        String month = calendar.get(Calendar.MONTH) + 1 < 10 ? "0" + (calendar.get(Calendar.MONTH) + 1)
                : calendar.get(Calendar.MONTH) + 1 + "";
        return year + month + day + "235959";
    }
    
	/**
	 * 根据渠道和接口标识验证访问次数验证限制
	 * @param orderInfo
	 * @throws Exception
	 */
	public void valiVisitLimit(OrderInfo orderInfo) throws Exception {
		String channel = "";
		try {
			channel = orderInfo.getChannel();
			if(StringUtils.isEmpty(channel)){ //渠道为空，不验证
				return;
			}
			//获取访问配置数据，有INTERFACENAME配置数据排在无INTERFACENAME配置数据之前
			List<Map> visitConf = commConfDao.getlimitQryConfByChannel(orderInfo.getChannel());
			if(visitConf == null || visitConf.size() == 0){ //无配置信息
				return;
			}
			
			Map visitMap = null;
			for(Map map : visitConf){
				//有INTERFACENAME配置，要匹配到(orderInfo.getInvokeface()
				if(orderInfo.getChannel().equals(map.get("CHANNEL")) && map.get("INTERFACENAME") != null){
					if(map.get("INTERFACENAME").equals(orderInfo.getInvokeface())){
						visitMap = map;
						break;
					}
				//无INTERFACENAME配置
				}else if(orderInfo.getChannel().equals(map.get("CHANNEL"))){
					visitMap = map;
					break;
				}
			}
			
			if(visitMap != null){
				//有INTERFACENAME配置
				if(!StringUtils.isEmpty((String)visitMap.get("INTERFACENAME"))){
					channel += "_"+visitMap.get("INTERFACENAME");
				}
				//[{MONTHLIMIT=6, CHANNEL=TX_2104, HOURLIMIT=2, DAYLIMIT=4, TOTALLIMIT=10, YEARLIMIT=8}]
				if(visitMap.get("HOURLIMIT") != null && !"".equals(visitMap.get("HOURLIMIT"))){
					long limitCount = Long.parseLong(visitMap.get("HOURLIMIT")+"");
					String limitKey = getLimitKey("yyyyMMddHH");
					String itemKey = getLimitKey("yyyyMMdd");
					Object obj = redisService.hmGet("univideo_visit_"+itemKey+"_"+channel,limitKey);
					if(obj != null && Long.parseLong(obj.toString()) >= limitCount){
						throw new BussinessException("10031", "访问次数超出最大次数");
					}
				}
				if(visitMap.get("DAYLIMIT") != null && !"".equals(visitMap.get("DAYLIMIT"))){
					long limitCount = Long.parseLong(visitMap.get("DAYLIMIT")+"");
					String limitKey = getLimitKey("yyyyMMdd");
					String itemKey = getLimitKey("yyyyMM");
					Object obj = redisService.hmGet("univideo_visit_"+itemKey+"_"+channel,limitKey);
					if(obj != null && Long.parseLong(obj.toString()) >= limitCount){
						throw new BussinessException("10032", "访问次数超出最大次数");
					}
				}
				if(visitMap.get("MONTHLIMIT") != null && !"".equals(visitMap.get("MONTHLIMIT"))){
					long limitCount = Long.parseLong(visitMap.get("MONTHLIMIT")+"");
					String limitKey = getLimitKey("yyyyMM");
					String itemKey = getLimitKey("yyyy");
					Object obj = redisService.hmGet("univideo_visit_"+itemKey+"_"+channel,limitKey);
					if(obj != null && Long.parseLong(obj.toString()) >= limitCount){
						throw new BussinessException("10033", "访问次数超出最大次数");
					}
				}
				if(visitMap.get("YEARLIMIT") != null && !"".equals(visitMap.get("YEARLIMIT"))){
					long limitCount = Long.parseLong(visitMap.get("YEARLIMIT")+"");
					String limitKey = getLimitKey("yyyy");
					Object obj = redisService.get("univideo_visit_year_"+limitKey+"_"+channel);
					if(obj != null && Long.parseLong(obj.toString()) >= limitCount){
						throw new BussinessException("10034", "访问次数超出最大次数");
					}
				}
				if(visitMap.get("TOTALLIMIT") != null && !"".equals(visitMap.get("TOTALLIMIT"))){
					long limitCount = Long.parseLong(visitMap.get("TOTALLIMIT")+"");
					Object obj = redisService.get("univideo_visit_total_"+channel);
					if(obj != null && Long.parseLong(obj.toString()) >= limitCount){
						throw new BussinessException("10035", "访问次数超出最大次数");
					}
				}				
			}
		} catch (Exception e) {
			if(e instanceof BussinessException) {
				throw e;
			}else {
				e.printStackTrace();
				throw new BussinessException("10030", channel+"验证访问数据限制出现错误，"+e.getMessage());
			}
		}
	}
	
	/**
	 * 根据渠道和接口标识设置访问数据
	 * @param orderInfo
	 * @throws Exception
	 */
	public void setVisitcount(OrderInfo orderInfo) throws Exception {
		String channel = "";
		try {
			channel = orderInfo.getChannel();
			if(StringUtils.isEmpty(channel)){ //渠道为空，不验证
				return;
			}
			//获取访问配置数据，有INTERFACENAME配置数据排在无INTERFACENAME配置数据之前			
			List<Map> visitConf = commConfDao.getlimitQryConfByChannel(orderInfo.getChannel());
			if(visitConf == null || visitConf.size() == 0){ //无配置信息
				return;
			}
			Map visitMap = null;
			for(Map map : visitConf){
				//有INTERFACENAME配置，要匹配到(orderInfo.getInvokeface()
				if(orderInfo.getChannel().equals(map.get("CHANNEL")) && map.get("INTERFACENAME") != null){
					if(map.get("INTERFACENAME").equals(orderInfo.getInvokeface())){
						visitMap = map;
						break;
					}
				//无INTERFACENAME配置
				}else if(orderInfo.getChannel().equals(map.get("CHANNEL"))){
					visitMap = map;
					break;
				}					
			}
			
			if(visitMap != null){
				//有INTERFACENAME配置
				if(!StringUtils.isEmpty((String)visitMap.get("INTERFACENAME"))){
					channel += "_"+visitMap.get("INTERFACENAME");
				}
				//[{MONTHLIMIT=6, CHANNEL=TX_2104, HOURLIMIT=2, DAYLIMIT=4, TOTALLIMIT=10, YEARLIMIT=8}]
				if(visitMap.get("HOURLIMIT") != null && !"".equals(visitMap.get("HOURLIMIT"))){
					String limitKey = getLimitKey("yyyyMMddHH");
					String itemKey = getLimitKey("yyyyMMdd");
					if(redisService.hincr("univideo_visit_"+itemKey+"_"+channel,limitKey,1) == 1){//第一次设置
						redisService.expire("univideo_visit_"+itemKey+"_"+channel, 86400*2); //设置过期 时间为两天
					}					
				}
				if(visitMap.get("DAYLIMIT") != null && !"".equals(visitMap.get("DAYLIMIT"))){
					String limitKey = getLimitKey("yyyyMMdd");
					String itemKey = getLimitKey("yyyyMM");
					if(redisService.hincr("univideo_visit_"+itemKey+"_"+channel,limitKey,1) == 1){//第一次设置
						redisService.expire("univideo_visit_"+itemKey+"_"+channel, 86400*62); //设置过期 时间为两个月
					}					
				}
				if(visitMap.get("MONTHLIMIT") != null && !"".equals(visitMap.get("MONTHLIMIT"))){
					String limitKey = getLimitKey("yyyyMM");
					String itemKey = getLimitKey("yyyy");
					redisService.hincr("univideo_visit_"+itemKey+"_"+channel,limitKey,1);
				}
				if(visitMap.get("YEARLIMIT") != null && !"".equals(visitMap.get("YEARLIMIT"))){
					String limitKey = getLimitKey("yyyy");
					redisService.incr("univideo_visit_year_"+limitKey+"_"+channel,1);
				}
				if(visitMap.get("TOTALLIMIT") != null && !"".equals(visitMap.get("TOTALLIMIT"))){
					redisService.incr("univideo_visit_total_"+channel,1);
				}				
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(channel + "设置访问数据出现错误，"+e.getMessage());
			//throw new BussinessException("10030", "验证访问数据限制出现错误，"+e.getMessage());
		}
	}
	
	private String getLimitKey(String dateFormat){
		 SimpleDateFormat formatter = new SimpleDateFormat(dateFormat); 
		 String limitKey = formatter.format(new Date());
		 return limitKey;
	}
	
	/**
	 * 分省分地市、分时段开放订购接口及订购达量限制
	 * @param orderinfo
	 * @throws Exception
	 */
	public void  valiChannelSpidLimit(OrderInfo orderInfo) throws Exception {
		
		//省份限制
		valiProvinceLimit(orderInfo);
		calllogger.info("============");
		boolean haspass = true; //是否通过，默认是
		String errorcode = "";
		String errorInfo = "";
		HashMap<String, String> confMap = null;
		List<HashMap<String, String>>  confList = null; //配置信息
		boolean twochannelsetnull = false; //二级渠道是否清空子渠道标识
		try{
			if(!"0".equals(orderInfo.getType()) || StringUtils.isEmpty(orderInfo.getInvokeface())){ 
				return; //订购，且invokeface不为空时验证			
			}

			String invokeface = orderInfo.getInvokeface();
			String cpid = orderInfo.getCpid();
			String spid = orderInfo.getSpid();
			String channel = orderInfo.getChannel();
			String subchannel = orderInfo.getSubchannel();
			String unifychannel = ""; //主渠道加子渠道合并标识
			
			
			//渠道建设新增加的渠道信息验证
			ChannelBean channelBean = cblDao.qryChannelConfById(channel);
			//是二级渠道
			if("1".equals(channelBean.getIspage()) && "对外接口类".equals(channelBean.getShape())){	
				twochannelsetnull = true;	
				subchannel = "";
			}
				
			if(!StringUtils.isEmpty(subchannel)){
				unifychannel = channel + subchannel;
			}

			if(!StringUtils.isEmpty(unifychannel)){
				//查询主渠道，和主渠道+子渠道的配置
				confList = commConfDao.qryUnifychannelSpidLimitConf(channel, unifychannel, cpid, spid, invokeface);		
			}else{
				//查询主渠道的配置
				confList = commConfDao.qryChannelSpidLimitConf(channel, cpid, spid, invokeface);
			}
			if(confList == null || confList.size() == 0){//无配置
				return;
			}
			//calllogger.info(channel+"，"+unifychannel+"，confList=>"+confList);
			//当前月份
			String currmonth = new SimpleDateFormat("yyyyMM").format(new Date());
			//当前日号
			String currday = new SimpleDateFormat("yyyyMMdd").format(new Date());
			//配置的渠道
			String channelconf = "";
			//HashMap<String, String> confMap = confList.get(0);
			for(int k = 0; k < confList.size(); k++){
				confMap = confList.get(k);
				channelconf = confMap.get("CHANNEL");
				JSONArray confArray = new JSONArray();
				//时间段限制
				if(haspass && !StringUtils.isEmpty(confMap.get("PERIODTIME"))){
					confArray = (JSONArray)confArray.parse(confMap.get("PERIODTIME"));
					JSONObject confObj;
					//[{"07:01:15":"09:20:00"},{"14:30:10":"16:25:11"}]
					String starttime = "";
					String endtime = "";
					String week = "";
					for(int i=0; i<confArray.size(); i++){
						confObj = confArray.getJSONObject(i);
						//System.out.println(confObj.getString("starttime").replaceAll(":", "") + "=========="+confObj.getString("endtime").replaceAll(":", ""));
						starttime = confObj.getString("starttime").replaceAll(":", "");
						endtime = confObj.getString("endtime").replaceAll(":", "");
						week = confObj.getString("week");
						if(valiStarttimeEndtime(starttime, endtime, week)){
							haspass = false;
							errorcode = "10040";
							errorInfo = "办理时间被限制，【"+confObj.getString("starttime")+"-"+confObj.getString("endtime")+"，week=>"+confObj.getString("week")+"】";
							break;
						}
					}
				}

				//省份地市限制
				if(haspass && !StringUtils.isEmpty(confMap.get("PROVINCEAREA"))){
					//[{"湖南":"郴州,常德,株洲,岳阳"},{"北京":""},{"江苏":"无锡,徐州,常州"},{"湖北":""}]
					String province = orderInfo.getProvince();
					String area = orderInfo.getArea();
					//省份地市为空，获取地市信息
					if(StringUtils.isEmpty(province) || StringUtils.isEmpty(area)){
						List<Map> areaList = commConfDao.getAreaInfo(orderInfo.getUserid().substring(0, 7));
						if(areaList != null && areaList.size()>0){
							Map areaMap = areaList.get(0);
							province = (String)areaMap.get("PROVINCE");
							area = (String)areaMap.get("AREA");
							orderInfo.setProvince(province);
							orderInfo.setArea(area);
						}
					}
					
					//省份及地市不为空
					if(!StringUtils.isEmpty(province) && !StringUtils.isEmpty(area)){	
						//得到所有的省份限制配置：[{"湖南":"郴州,常德,株洲,岳阳,长沙"},{"北京":""},{"江苏":"无锡,徐州,常州"},{"湖北":"黄冈"}]
						confArray = (JSONArray)confArray.parse(confMap.get("PROVINCEAREA"));
						JSONObject confObj;
						//遍历配置
						for(int i=0; i<confArray.size(); i++){
							confObj = confArray.getJSONObject(i);					
							Set<String> keyset = confObj.keySet();
							Iterator<String> it = keyset.iterator();
							String key = ""; //省份
							String value = "";//地市，可能有多个，为*时或为空时表示限制所有地市
							while(it.hasNext()){
								key = it.next();//配置的省份
								if(province.indexOf(key) != -1){//省份包含
									value = confObj.getString(key);//配置的地市
									if(StringUtils.isEmpty(value) || "*".equals(value)){ //地市为空或者为*，代表限制所有地市
										errorcode = "10042";
										errorInfo = "订购省份或地市被限制，【"+province+"】";
										haspass = false;
									}else{//有配置地市
										List<String> areaList =  Arrays.asList(value.split(","));
										for(String tmp : areaList){
											if(area.indexOf(tmp) != -1){
												errorcode = "10043";
												errorInfo = "订购地市被限制，【"+area+"】";
												haspass = false;
												break;
											}
										}
									}
									//匹配上了省份，中断while循环
									break;
								}						
							}
							//已被限制，中断for循环
							if(!haspass) break;
						}
					}					
				}
				
				//订购上限限制
				if(haspass && !StringUtils.isEmpty(confMap.get("UPPERCOUNT"))){
					String uppercount = confMap.get("UPPERCOUNT").trim();
					int currcount = 0;
					//所有接口
					if("*".equals(confMap.get("INVOKEFACE"))){
						String limitinvokefaceconf = dictionaryDao.getValue("limitinvokefaceconf");
						if(!StringUtils.isEmpty(limitinvokefaceconf)){
							JSONObject json = JSONObject.parseObject(limitinvokefaceconf);
							for (Map.Entry<String, Object> entry : json.entrySet()) {
							    String tmpinvokeface = entry.getKey(); //接口标识
							    Object tmpinvokefacename = entry.getValue(); //接口名称
							    if("*".equals(tmpinvokeface)) continue; //为*时不查询
								String mainkey = "univideo_invokecount_"+tmpinvokeface+"_"+currday;	
								//yyyymmdd_channel_CPID_SPID_order_succ_totalcount, 
								String itemkey = channelconf+"_"+cpid+"_"+spid+"_order_succ_totalcount";
								Object rediscurrcount = redisService.hmGet(mainkey, itemkey);
								if(rediscurrcount != null){//叠加订购成功量
									currcount += Integer.parseInt(rediscurrcount.toString());
								}
							}						
						}
					}else{//单个接口限制
						//handle接口渠道办理成功量计数					
						String mainkey = "univideo_invokecount_"+invokeface+"_"+currday;	
						//yyyymmdd_channel_CPID_SPID_order_succ_totalcount, 
						String itemkey = channelconf+"_"+cpid+"_"+spid+"_order_succ_totalcount";
						Object rediscurrcount = redisService.hmGet(mainkey, itemkey);
						if(rediscurrcount != null){
							currcount = Integer.parseInt(rediscurrcount.toString());
						}
					}
					//有值
					if(currcount != 0){
						if(currcount >= Integer.parseInt(uppercount)){
							haspass = false;
							errorcode = "10041";
							errorInfo = "办理个数已达到上限，【"+uppercount+"】";
						}
					}
				}
				//有限制，跳出最外层for循环
				if(!haspass){
					break;
				}
			}			
		}catch(Exception e){
			e.printStackTrace();
			if(orderInfo != null){
				calllogger.error(orderInfo.getUserid()+"，"+orderInfo.getSpid()+"，"+orderInfo.getInvokeface()+"，验证渠道办理限制出现异常，"+e.getMessage(),e);
			}
		}finally{
			if(!haspass){
				calllogger.info("confMap=>"+confMap+"，"+orderInfo.getUserid()+"，"+orderInfo.getInvokeface()+"，"+orderInfo.getChannel()+"，"+orderInfo.getSpid()+"，"+orderInfo.getProvince()+"办理限制返回信息：errorcode=>"+errorcode+"，errorInfo=>"+errorInfo);
			}
		}
		//被限制，则抛出异常
		if(!haspass){
			//calllogger.info(orderInfo.getUserid()+"，"+orderInfo.getInvokeface()+"，"+orderInfo.getChannel()+"，"+orderInfo.getSpid()+"，"+orderInfo.getProvince()+"办理限制返回信息：errorcode=>"+errorcode+"，errorInfo=>"+errorInfo);
			errorInfo = "抱歉，您当前暂不能参加此活动";
			errorcode = "80016";
			throw new BussinessException(errorcode, errorInfo);
		}
		
	}
	
	/**
	 * 验证当前时间是否在指定范围内
	 * @param starttime
	 * @param endtime
     * @param week	 
	 * @return 在指定范围内返回 true，否则返回false
	 */
	private boolean valiStarttimeEndtime(String starttime, String endtime, String week){
		boolean res = false;
		if(StringUtils.isEmpty(starttime) || StringUtils.isEmpty(endtime)){
			return res;
		}
		String currtime = new SimpleDateFormat("HHmmss").format(new Date());
		//当前时间大于或等于开始时间，且小于或等于结束时间
		if(Integer.parseInt(currtime) >= Integer.parseInt(starttime) && Integer.parseInt(currtime) <= Integer.parseInt(endtime)){
			res = true;
		}
		//当前时间包含在配置时间内，且有星期配置，且星期配置为*（全部）
		if(res && !StringUtils.isEmpty(week) && !"*".equals(week)){
			int weekDay = this.getWeekDay();
			//calllogger.info("starttime=>"+starttime+"，endtime=>"+endtime+"，week=>"+week+"，weekDay=>"+weekDay);
			List<String> weekList = Arrays.asList(week.trim().split(","));
			//当前星期不在配置范围内
			if(!weekList.contains(String.valueOf(weekDay))){
				res = false;
			}
		}
		
		return res;
	}
	
	/**
	 * 获取星期几，1至7
	 * @return
	 */
	private int getWeekDay(){
		Calendar cal = Calendar.getInstance();
		//一周第一天是否为星期天
		boolean isFirstSunday = (cal.getFirstDayOfWeek() == Calendar.SUNDAY);
		//获取周几
		int weekDay = cal.get(Calendar.DAY_OF_WEEK);
		//若一周第一天为星期天，则-1
		if(isFirstSunday){
			weekDay = weekDay - 1;
		    if(weekDay == 0){
		        weekDay = 7;
		    }
		}
		
		return weekDay;
	}
	
	/**
	 * 验证省份办理限制
	 * @param orderInfo
	 * @throws Exception
	 */
	public void  valiProvinceLimit(OrderInfo orderInfo) throws Exception {
		//验证是否通过，true是，false否
		boolean haspass = true;
		String errorInfo = "";
		String errorcode = "";
		List<HashMap> confList = null;
		try {
			//不限制办理的CPID
			String notProvinceLimitcpid = dictionaryDao.getValue("notProvinceLimitcpid");
			if(!StringUtils.isEmpty(notProvinceLimitcpid) && !StringUtils.isEmpty(orderInfo.getCpid())){ 
				List<String> cpids = Arrays.asList(notProvinceLimitcpid.split(","));
				if(cpids.contains(orderInfo.getCpid())){
					return;
				}
			}
			String province = orderInfo.getProvince();
			String area = orderInfo.getArea();
			String invokeface = orderInfo.getInvokeface();
			String type = orderInfo.getType();
			String channel = orderInfo.getChannel();
			
			if(StringUtils.isEmpty(province)){
				this.setAreaInfo(orderInfo);
				province = orderInfo.getProvince();
			}
			//接口标识为空，设置默认值
			if(StringUtils.isEmpty(invokeface)){ 
				invokeface = "*"; 
			}
			if(StringUtils.isEmpty(province)){ 
				province = "*";
			}
			if(StringUtils.isEmpty(type)){
				type = "*";
			}
			if(StringUtils.isEmpty(channel)){
				channel = "*";
			}
			//查询是否有省份限制
			confList = commConfDao.qryProvInvokeLimit(province, channel, invokeface, type);
			if(confList != null && confList.size() > 0){
				//渠道放开限制
				if(valiNoprovinceLimitChannel(orderInfo)){
					calllogger.info("province=>"+orderInfo.getProvince()+"，userid=>"+orderInfo.getUserid()+"，invokeface=>"+orderInfo.getInvokeface()+"，channel=>"+orderInfo.getChannel()+"。subchannel"+orderInfo.getSubchannel()+"，type=>"+orderInfo.getType()+"，"+"办理省份限制渠道被放开：");
					return;
				}
				haspass = false;
				errorcode = "9003";
				errorInfo = "您号码的归属地暂未开放该业务，敬请期待。";
				if(!"*".equals(province)){
					errorInfo = "您号码的归属地"+province+"暂未开放该业务，敬请期待。";
				}
				if("广东".equals(province) && "0".equals(type)){
					errorInfo = "业务平台满载，正在升级中，暂时无法受理新用户订购，敬请谅解！";
				}

				throw new BussinessException(errorcode, errorInfo);
			}
		} catch (Exception e) {
			if(e instanceof BussinessException) {
				throw e;
			}else{
				e.printStackTrace();
				if(orderInfo != null){
					calllogger.error(orderInfo.getUserid()+"，"+orderInfo.getSpid()+"，"+orderInfo.getInvokeface()+"，验证办理省份限制出现异常，"+e.getMessage(),e);
				}
			}
		} finally{
			if(!haspass){
				calllogger.info(haspass+"，confList=>"+confList+"，province=>"+orderInfo.getProvince()+"，userid=>"+orderInfo.getUserid()+"，invokeface=>"+orderInfo.getInvokeface()+"，channel=>"+orderInfo.getChannel()+"，type=>"+orderInfo.getType()+"，"+"办理省份限制返回信息：errorcode=>"+errorcode+"，errorInfo=>"+errorInfo);
			}
		}
	}
	
	/**
	 * 渠道是否放开了限制
	 * @param orderInfo
	 * @return true是，false否
	 */
	private boolean valiNoprovinceLimitChannel(OrderInfo orderInfo){
		boolean res = false;
		try {
			//不要限制 渠道配置
			String notProvinceLimitchannel = dictionaryDao.getValue("notProvinceLimitchannel");
			String channel = orderInfo.getChannel();
			String subchannel = orderInfo.getSubchannel();
			//如果省份为空，设置为*
			String province = orderInfo.getProvince();
			if(StringUtils.isEmpty(province)) {
				province = "*";
			}
			//不要限制的渠道
			String nolimitchannel = "";
			if(!StringUtils.isEmpty(channel)){
				nolimitchannel += channel;
			}
			if(!StringUtils.isEmpty(channel) && !StringUtils.isEmpty(subchannel)){
				nolimitchannel += subchannel;
			}
			if(!StringUtils.isEmpty(nolimitchannel) && !StringUtils.isEmpty(notProvinceLimitchannel)){
				JSONObject tmpobj = JSONObject.parseObject(notProvinceLimitchannel);
				if(tmpobj != null && tmpobj.get(province) != null && !StringUtils.isEmpty(tmpobj.getString(province))){
					List<String> channels = Arrays.asList(tmpobj.getString(province).split(","));
					if(channels != null && channels.contains(nolimitchannel)){
						res = true;
					}
				}
			}
			//calllogger.info(orderInfo.getUserid()+"，spid=>"+orderInfo.getSpid()+"，nolimitchannel=>"+nolimitchannel+"，notProvinceLimitchannel=>"+notProvinceLimitchannel+"，res=>"+res);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		return res;
	}
}