package com.house365.ws.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.house365.beans.entity.*;
import com.house365.commons.system.HttpClientUtil;
import com.house365.web.util.DateTimeUtils;
import com.house365.web.util.MemoryPropertyPlaceholderConfigurer;
import com.house365.ws.cached.RedisUtilsInterface;
import com.house365.ws.dao.mapper.*;
import com.house365.ws.interfaces.server.ICustomerProject;
import com.house365.ws.service.interfaces.*;
import com.house365.ws.util.Constant;
import com.house365.ws.util.OperateLogUtils;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 配置好表数据,定时轮询值日人员.onduty:是否值日,1:当前之日,0:不值日
 *
 * @author whh
 */
@Service("staffDuty")
public class StaffDuty implements IStaffDuty {

    private static final Logger logger = LoggerFactory.getLogger(StaffDuty.class);

    @Autowired
    private UserMapper usermapper;
    @Autowired
    private CloudActivityMapper activityMapper;
    @Autowired
    private RedisUtilsInterface redisUtil;
    @Autowired
    private DictionaryMapper dictionaryMapper;
    @Autowired
    private DutyStaffOtherMapper staffOtherMapper;
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private IProjectService<ProjectEntity> projectService;
    @Autowired
    private OperateLogUtils logUtils;

    @Autowired
    private CloudCustomerMapper cloudCustomerMapper;
    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
    private CustomerStatusLogMapper statusLogMapper;
    @Autowired
    private ExternalCustomerMapper externalCusMapper;
    @Autowired
    private CustomerCallbackMapper callbackMapper;
    @Autowired
    private CloudRuleMapper ruleMapper;
    @Autowired
    private ICustomerProject customerProject;
    @Autowired
    private CloudCountMapper cloudCountMapper;
    @Autowired
    private IMarketingActivityService<MarketingActivityEntity> marketingActivityService;

    @Autowired
    private CrmSourceMapper crmSourceMapper;
    @Autowired
    private IMarketCustomerService marketCustomer;
    @Autowired
    private ICrmSourceService<CrmSourceEntity> crmSourceService;
    @Autowired
    private DutyStaffMapper staffMapper;
    @Autowired
    private RedisUtilsInterface redisUtils;

    @Value("${CRM.CUSTOMERQUERY.URL}")
    private String crmQueryUrl;


    @Override
    public void updateDutyStaff() {
        List<DutyStaffEntity> list = usermapper.getStaffDutyList();
        Date date = new Date();
        if (CollectionUtils.isNotEmpty(list)) {
            int size = list.size();
            for (int i = 0; i < size; i++) {
                DutyStaffEntity staff = list.get(i);
                if ("1".equals(staff.getOnduty()) && staff.getId() == list.size()) {
                    staff.setOnduty("0");
                    staff.setUpdateTime(date);
                    usermapper.updateDutyStaff(staff);
                    list.get(0).setOnduty("1");//循环到第一个轮询值日
                    list.get(0).setUpdateTime(date);
                    usermapper.updateDutyStaff(list.get(0));
                    break;
                } else if ("1".equals(staff.getOnduty()) && staff.getId() != list.size()) {
                    staff.setOnduty("0");
                    staff.setUpdateTime(date);
                    usermapper.updateDutyStaff(staff);
                    list.get(i + 1).setOnduty("1");//下一个轮询值日
                    list.get(i + 1).setUpdateTime(date);
                    usermapper.updateDutyStaff(list.get(i + 1));
                    break;
                }
            }
        }
    }

    @Override
    public void addCloudActivity() {
        try {
            String key = "save_cloud_job";
            String value = "cloud";
            long seconds = 100;
            if (redisUtil.setNX(key, value, seconds)) {
                //获取云迹活动需要添加的城市
                Map<String, Object> dicMap = new HashMap<>(10);
                dicMap.put("city", "nj");
                dicMap.put("dicKey", "cloud.city");
                List<DictionaryEntity> dictionaryList = dictionaryMapper.getNoApproximateConfig(dicMap);
                if (CollectionUtils.isNotEmpty(dictionaryList)) {
                    String dutyCity = dictionaryList.get(0).getDicValue();
                    List<String> cityList = new ArrayList<>();
                    if (dutyCity.contains(",")) {
                        String[] dutyCitys = dutyCity.split(",");
                        for (String s : dutyCitys) {
                            cityList.add(s);
                        }
                    } else {
                        cityList.add(dutyCity);
                    }
                    if (CollectionUtils.isNotEmpty(cityList)) {
                        String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
                        date = date.replace("-", "");
                        Date now = new Date();
                        for (String city : cityList) {
                            //南京和其他城市区分
                            Map<String, Object> map = new HashMap<>(5);
                            if ("nj".equals(city)) {
                                map.put("onduty", 1);
                                List<DutyStaffEntity> list = usermapper.getDutyByCondition(map);
                                if (CollectionUtils.isNotEmpty(list)) {
                                    DutyStaffEntity staffEntity = list.get(0);
                                    //每天新增一个云迹活动
                                    CloudActivityEntity entity = new CloudActivityEntity();
                                    String name = "云迹数据" + date;
                                    entity.setName(name);
                                    entity.setCity(city);
                                    entity.setCreateId(Integer.valueOf(staffEntity.getUserId()));
                                    entity.setCreateName(staffEntity.getName());
                                    entity.setCreateTime(now);
                                    setData(entity);
                                    activityMapper.save(entity);
                                }
                            } else {
                                map.put("isDuty", 1);
                                map.put("city", city);
                                List<DutyStaffOtherEntity> dutyList = staffOtherMapper.queryByConditions(map);
                                if (CollectionUtils.isNotEmpty(dutyList)) {
                                    DutyStaffOtherEntity staffEntity = dutyList.get(0);
                                    //每天新增一个云迹活动
                                    CloudActivityEntity entity = new CloudActivityEntity();
                                    String name = "云迹数据" + date;
                                    entity.setName(name);
                                    entity.setCity(city);
                                    entity.setCreateId(staffEntity.getUserId());
                                    entity.setCreateName(staffEntity.getName());
                                    entity.setCreateTime(now);
                                    setData(entity);
                                    activityMapper.save(entity);
                                }
                            }
                        }
                    }
                }
            }
            String newKey = "save_cloud_job_new";
            String newValue = "cloud";
            if (redisUtil.setNX(newKey, newValue, seconds)) {
                addNewActivity();
            }
        } catch (Exception e) {
            logger.error("新增云迹轨迹活动失败");
        }
    }

    private void setData(CloudActivityEntity entity) {
        entity.setCustomerCount(0);
        entity.setWaitCount(0);
        entity.setSentCount(0);
        entity.setIsDelete(0);
        //新增字段赋值
        entity.setTotalPriceMin(0);
        entity.setTotalPriceMax(0);
        entity.setAreaMin(0);
        entity.setAreaMax(0);
        entity.setBlock("");
        entity.setBlockName("");
        entity.setDistrict("");
        entity.setDistrictName("");
        entity.setChannel("");
        entity.setChannelName("");
        entity.setSeeProjectName("");
        entity.setSeeStartTime(null);
        entity.setSeeEndTime(null);
        entity.setSeeCount(0);
        entity.setType(0);
    }

    /**
     * 定时新增定制云迹活动
     */
    @Override
    public void addCloudActivityNew() {
        try {
            String key = "save_cloud_job_new";
            String value = "cloud";
            long seconds = 100;
            if (redisUtil.setNX(key, value, seconds)) {
                addNewActivity();
            }
        } catch (Exception e) {
            logger.error("新增定制云迹轨迹活动失败");
        }
    }

    private void addNewActivity() {
        Map<String, Object> searchMap = new HashMap<>(10);
        searchMap.put("group", 1);
        List<CloudRuleEntity> list = ruleMapper.queryByConditions(searchMap);
        if (CollectionUtils.isNotEmpty(list)) {
            String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            date = date.replace("-", "");
            Date now = new Date();
            for (CloudRuleEntity c : list) {
                CloudActivityEntity entity = new CloudActivityEntity();
                String name = "定制云迹数据" + date;
                entity.setName(name);
                entity.setCity(c.getCityCode());
                entity.setCreateId(c.getUserId());
                entity.setCreateName(c.getCreateName());
                entity.setCreateTime(now);
                //新增字段赋值
                setData(entity);
                activityMapper.save(entity);
            }
        }
    }

    /**
     * 定时同步经管项目开启关闭状态
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateProjectStatus() {
        try {
            String key = "update_project_job";
            String value = "project";
            long seconds = 100;
            if (redisUtil.setNX(key, value, seconds)) {
                Map<String, Object> map = new HashMap<>(5);
                map.put("showStatus", 1);
                List<ProjectEntity> projectList = projectMapper.queryByConditions(map);
                if (CollectionUtils.isNotEmpty(projectList)) {
                    for (ProjectEntity p : projectList) {
                        List<NameValuePair> params = new ArrayList<>();
                        params.add(new BasicNameValuePair("s", "/Api/getProInfo"));
                        params.add(new BasicNameValuePair("city", p.getCity()));
                        params.add(new BasicNameValuePair("limit", "1"));
                        params.add(new BasicNameValuePair("contract", p.getContractCode()));
                        params.add(new BasicNameValuePair("isAccurate", "1"));

                        String result = HttpClientUtil.doGet(MemoryPropertyPlaceholderConfigurer.getContextProperty("projects.server.url"), params);
                        if (result != null) {
                            ObjectMapper objectMapper = new ObjectMapper();
                            Map<String, Object> resultMap = objectMapper.readValue(result, Map.class);
                            boolean status = (boolean) resultMap.get("status");
                            if (status) {
                                if (resultMap.get("data") != null) {
                                    List<Map<String, Object>> list = (List<Map<String, Object>>) resultMap.get("data");
                                    if (CollectionUtils.isNotEmpty(list)) {
                                        Map<String, Object> dataMap = list.get(0);

                                        String projectCode = dataMap.get("projectCode").toString();
                                        String projectName = dataMap.get("projectName").toString();
                                        String buildingId = dataMap.get("buildingId").toString();
                                        String buildingName = dataMap.get("buildingName").toString();
                                        String statusNew = dataMap.get("status").toString();
                                        String manager = dataMap.get("manager").toString();
                                        String type = dataMap.get("type").toString();
                                        String kfs = dataMap.get("kfs").toString();
                                        String district = dataMap.get("district").toString();
                                        String address = dataMap.get("address").toString();
                                        String startTime = dataMap.get("startTime").toString();
                                        String business = dataMap.get("business").toString();
                                        p.setProjectCode(projectCode);
                                        p.setProjectName(projectName);
                                        p.setBuildingId(Integer.valueOf(buildingId));
                                        p.setBuildingName(buildingName);
                                        p.setStatus(Integer.valueOf(statusNew));
                                        p.setManager(manager);
                                        p.setType(type);
                                        p.setKfs(kfs);
                                        p.setDistrict(district);
                                        p.setAddress(address);
                                        p.setStartTimeStr(startTime);
                                        p.setBusiness(business);
                                        ProjectEntity oldEntity = projectService.getById(p.getId());
                                        projectService.update(p);
                                        ProjectEntity newEntity = projectService.getById(p.getId());
                                        logUtils.recordOperateLog(oldEntity, newEntity, p.getId(), 0, "经管系统");
                                    }
                                }
                            }
                        }
                    }

                }
            }
        } catch (Exception e) {
            logger.error("同步经管状态信息定时任务失败", e);
            throw new RuntimeException();
        }
    }

    /**
     * 定时设置云迹客户报备redis缓存
     */
    @Override
    public void setCloudCount() {
        try {
            String key = "set_cloud_job";
            String value = "cloud";
            long seconds = 100;
            if (redisUtil.setNX(key, value, seconds)) {
                Map<String, Object> map = new HashMap<>(10);
                map.put("type", 0);
                List<CloudActivityEntity> list = activityMapper.queryByConditions(map);
                if (CollectionUtils.isNotEmpty(list)) {
                    for (CloudActivityEntity c : list) {
//                        if(c.getId() != 912){
//                            continue;
//                        }
                        //开启线程池跑定时，防止超时
                        final CloudActivityEntity a = c;
                        ExecutorService executor = Executors.newCachedThreadPool();
                        executor.execute(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    Map<String, Object> searchMap = new HashMap<>(10);
                                    searchMap.put("activeId", a.getId());
                                    searchMap.put("type", 2);
                                    List<CloudCustomerEntity> cloudList = cloudCustomerMapper.queryByConditions(searchMap);
                                    List<Integer> idList = new ArrayList<>();
                                    List<Integer> seaIdList = new ArrayList<>();
                                    List<Integer> idAllList = new ArrayList<>();
                                    if (CollectionUtils.isNotEmpty(cloudList)) {
                                        for (CloudCustomerEntity c : cloudList) {
                                            if (c.getManagerId() > 0) {
                                                idList.add(c.getCustomerId());
                                            } else {
                                                seaIdList.add(c.getCustomerId());
                                            }
                                        }
                                        //4.9需求 统计添加时间判断
                                        Date time = cloudList.get(0).getCreateTime();
                                        dealList(idList, idAllList, time, 1);
                                        dealSeaList(seaIdList, idAllList, time);
                                        idAllList = removeDuplicate(idAllList);
                                        //设置统计数目 已跟进  回公海  A/B意向数 约看数 到访数 认购数 签约数
                                        String backKey = "cloud_back_count" + a.getId();
                                        String abKey = "cloud_ab_count" + a.getId();
                                        String seeKey = "cloud_see_count" + a.getId();
                                        String daoKey = "cloud_dao_count" + a.getId();
                                        String buyKey = "cloud_buy_count" + a.getId();
                                        String signKey = "cloud_sign_count" + a.getId();

                                        String backIdKey = "cloud_back_id" + a.getId();
                                        String seeIdKey = "cloud_see_Id" + a.getId();
                                        String daoIdKey = "cloud_dao_Id" + a.getId();
                                        String buyIdKey = "cloud_buy_Id" + a.getId();
                                        String signIdKey = "cloud_sign_Id" + a.getId();
                                        String cancelIdKey = "cloud_cancel_Id" + a.getId();
                                        String renIdKey = "cloud_ren_Id" + a.getId();

                                        if (CollectionUtils.isNotEmpty(idAllList)) {
                                            //已跟进 不计算自动新增的回访
                                            Map<String, Object> backMap = new HashMap<>(10);
                                            backMap.put("idList", idAllList);
                                            backMap.put("notId", 1);
                                            StringBuilder builderBack = new StringBuilder();
                                            List<String> backKeyIdList = new ArrayList<>();
                                            List<Map<String, Object>> backList = callbackMapper.queryCloudBackCount(backMap);
                                            if (CollectionUtils.isNotEmpty(backList)) {
                                                redisUtil.setValueNew(backKey, String.valueOf(backList.size()));
                                                backList.forEach(s -> backKeyIdList.add(s.get("phone").toString()));
                                                backKeyIdList.forEach(s -> builderBack.append(s).append(","));
                                                redisUtil.setValueNew(backIdKey, builderBack.toString());
                                            }

                                            Map<String, Object> queryMap = new HashMap<>(5);
                                            queryMap.put("abType", 1);
                                            queryMap.put("idList", idAllList);
                                            List<CustomerEntity> abList = customerMapper.queryCloudCount(queryMap);
                                            redisUtil.setValueNew(abKey, String.valueOf(abList.size()));

                                            StringBuilder builder1 = new StringBuilder();
                                            List<String> seeKeyIdList = new ArrayList<>();
                                            StringBuilder builder2 = new StringBuilder();
                                            List<String> daoIdKeyList = new ArrayList<>();
                                            StringBuilder builder3 = new StringBuilder();
                                            List<String> buyIdKeyList = new ArrayList<>();
                                            StringBuilder builder4 = new StringBuilder();
                                            List<String> signIdKeyList = new ArrayList<>();
                                            StringBuilder builder5 = new StringBuilder();
                                            List<String> cancelIdKeyList = new ArrayList<>();
                                            StringBuilder builder6 = new StringBuilder();
                                            List<String> renIdKeyList = new ArrayList<>();

                                            queryMap.put("status", 1);
                                            List<Map<String, Object>> seeList = statusLogMapper.queryCloudCount(queryMap);
                                            seeList.forEach(s -> seeKeyIdList.add(s.get("phone").toString()));
                                            seeKeyIdList.forEach(s -> builder1.append(s).append(","));
                                            redisUtil.setValueNew(seeKey, String.valueOf(seeList.size()));
                                            redisUtil.setValueNew(seeIdKey, builder1.toString());

                                            queryMap.put("status", 2);
                                            List<Map<String, Object>> daoList = statusLogMapper.queryCloudCount(queryMap);
                                            daoList.forEach(s -> daoIdKeyList.add(s.get("phone").toString()));
                                            daoIdKeyList.forEach(s -> builder2.append(s).append(","));
                                            redisUtil.setValueNew(daoKey, String.valueOf(daoList.size()));
                                            redisUtil.setValueNew(daoIdKey, builder2.toString());

                                            queryMap.put("status", 4);
                                            List<Map<String, Object>> buyList = statusLogMapper.queryCloudCount(queryMap);
                                            buyList.forEach(s -> buyIdKeyList.add(s.get("phone").toString()));
                                            buyIdKeyList.forEach(s -> builder3.append(s).append(","));
                                            redisUtil.setValueNew(buyKey, String.valueOf(buyList.size()));
                                            redisUtil.setValueNew(buyIdKey, builder3.toString());

                                            queryMap.put("status", 5);
                                            List<Map<String, Object>> signList = statusLogMapper.queryCloudCount(queryMap);
                                            signList.forEach(s -> signIdKeyList.add(s.get("phone").toString()));
                                            signIdKeyList.forEach(s -> builder4.append(s).append(","));
                                            redisUtil.setValueNew(signKey, String.valueOf(signList.size()));
                                            redisUtil.setValueNew(signIdKey, builder4.toString());

                                            queryMap.put("status", 6);
                                            List<Map<String, Object>> cancelList = statusLogMapper.queryCloudCount(queryMap);
                                            cancelList.forEach(s -> cancelIdKeyList.add(s.get("phone").toString()));
                                            cancelIdKeyList.forEach(s -> builder5.append(s).append(","));
                                            redisUtil.setValueNew(cancelIdKey, builder5.toString());

                                            queryMap.put("status", 3);
                                            List<Map<String, Object>> renList = statusLogMapper.queryCloudCount(queryMap);
                                            renList.forEach(s -> renIdKeyList.add(s.get("phone").toString()));
                                            renIdKeyList.forEach(s -> builder6.append(s).append(","));
                                            redisUtil.setValueNew(renIdKey, builder6.toString());
                                        } else {
                                            redisUtil.setValueNew(backKey, "0");
                                            redisUtil.setValueNew(abKey, "0");
                                            redisUtil.setValueNew(seeKey, "0");
                                            redisUtil.setValueNew(daoKey, "0");
                                            redisUtil.setValueNew(buyKey, "0");
                                            redisUtil.setValueNew(signKey, "0");

                                            redisUtil.setValueNew(backIdKey, "");
                                            redisUtil.setValueNew(seeIdKey, "");
                                            redisUtil.setValueNew(daoIdKey, "");
                                            redisUtil.setValueNew(renIdKey, "");
                                            redisUtil.setValueNew(buyIdKey, "");
                                            redisUtil.setValueNew(signIdKey, "");
                                            redisUtil.setValueNew(cancelIdKey, "");
                                        }
                                    }
                                } catch (Exception e) {
                                    logger.error("设置云迹统计数据定时失败", e);
                                }
                            }
                        });

                    }
                }
            }
        } catch (Exception e) {
            logger.error("设置云迹统计数据定时失败", e);
        }

    }

    /**
     * 平台客户推送至CRM
     */
    @Override
    public void syncPlatCustomers() {
        //查询满一个月的平台客户
        List<CustomerEntity> list = customerMapper.queryMonthPlatCustomers();
        //同步通知CRM
        if (CollectionUtils.isNotEmpty(list)) {
            for (CustomerEntity ce : list) {
                try {
                    post2CRM(ce);
                    ce.setCrmSync("1");
                    customerMapper.updateSync(ce);
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }

    }

    private String post2CRM(CustomerEntity customer) throws Exception {

        if (Strings.isNullOrEmpty(customer.getPhone()) || Strings.isNullOrEmpty(
                customer.getCityCode()) || Strings.isNullOrEmpty(customer.getActSource())) {
            throw new Exception("平台客户-CRM-参数不完整");
        }
        String crmUrl = MemoryPropertyPlaceholderConfigurer.getContextProperty("CRM.CUSTOMER.ADD.URL");
        URLEncoder.encode(crmUrl);

        final String url = crmUrl;
        final String mobile = customer.getPhone();
        final String city = customer.getCityCode();
        final String activename = customer.getActSource();
        final String activefrom = "563";//新来源
        final String username = customer.getName();
        ExecutorService executor = Executors.newCachedThreadPool();
        executor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    List<NameValuePair> pairs = new ArrayList<>();
                    pairs.add(new BasicNameValuePair("mobile", mobile));
                    pairs.add(new BasicNameValuePair("city", city));
                    pairs.add(new BasicNameValuePair("activename", activename));
                    pairs.add(new BasicNameValuePair("activefrom", activefrom));
                    pairs.add(new BasicNameValuePair("username", username));
                    String result = HttpClientUtil.doGet(url, pairs);
                    logger.info("call CRM add customer status result:{}", result);
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
            }
        });

        return "";
    }

    /**
     * 推送外部客户至crm
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void putExterCusToCrm() {
        try {
            String key = "set_external_job";
            String value = "external";
            long seconds = 100;
            if (redisUtil.setNX(key, value, seconds)) {
                Date checkDate = DateTimeUtils.getYearsAgo(new Date(), 1);
                Map<String, Object> map = new HashMap<>(10);
                map.put("crmSync", 0);
                map.put("putTime", checkDate);
                List<ExternalCustomerEntity> list = externalCusMapper.queryByConditions(map);
                if (CollectionUtils.isNotEmpty(list)) {
                    for (ExternalCustomerEntity e : list) {
                        postToCrm(e);
                        e.setCrmSync(1);
                        externalCusMapper.update(e);
                    }
                }
            }
        } catch (Exception e) {
            logger.error("推送外部客户至crm失败", e);
        }
    }

    private void postToCrm(ExternalCustomerEntity customer) throws Exception {
        if (Strings.isNullOrEmpty(customer.getPhone()) || Strings.isNullOrEmpty(
                customer.getCityCode()) || Strings.isNullOrEmpty(customer.getActSource())) {
            throw new Exception("外部客户推送crm参数不完整");
        }
        String crmUrl = MemoryPropertyPlaceholderConfigurer.getContextProperty("CRM.CUSTOMER.ADD.URL");
        URLEncoder.encode(crmUrl);

        final String url = crmUrl;
        final String mobile = customer.getPhone();
        final String city = customer.getCityCode();
        final String activeName = customer.getActSource();
        final String activeFrom = "564";
        final String userName = customer.getName();

        ExecutorService executor = Executors.newCachedThreadPool();
        executor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    List<NameValuePair> pairs = new ArrayList<>();
                    pairs.add(new BasicNameValuePair("mobile", mobile));
                    pairs.add(new BasicNameValuePair("city", city));
                    pairs.add(new BasicNameValuePair("activename", activeName));
                    pairs.add(new BasicNameValuePair("activefrom", activeFrom));
                    pairs.add(new BasicNameValuePair("username", userName));
                    String result = HttpClientUtil.doGet(url, pairs);
                    logger.info("推送外部客户至crm result:{}", result);
                } catch (Exception e) {
                    logger.error("推送外部客户至crm失败", e);
                }
            }
        });
    }

    private static List removeDuplicate(List<Integer> list) {
        HashSet<Integer> h = new HashSet<>(list);
        list.clear();
        list.addAll(h);
        return list;
    }

    /**
     * 设置云迹年度报表
     */
    @Override
    public void setCloudReportCountYear() {
        String key = "set_cloud_create_year_job";
        String value = "cloudCreate";
        long seconds = 100;
        if (redisUtil.setNX(key, value, seconds)) {
            Date date = new Date();
            String now = DateTimeUtils.getDateString(date, DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_FULL);
            int year = Integer.parseInt(now.substring(0, 4));
            Date endDate = getCurrYearFirst(year);
            Date startDate = DateTimeUtils.getUpdateDateTime(endDate, Calendar.YEAR, -1);
            Date oldDate = DateTimeUtils.getUpdateDateTime(startDate, Calendar.DAY_OF_MONTH, 1);
            String startTime = DateTimeUtils.getDateString(startDate, DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_FULL);
            String endTime = DateTimeUtils.getDateString(endDate, DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_FULL);
            setReportCount(startTime, endTime, oldDate, 3);
        }
    }

    /**
     * 设置云迹季度报表
     */
    @Override
    public void setCloudReportCountJi() {
        String key = "set_cloud_create_Ji_job";
        String value = "cloudCreate";
        long seconds = 100;
        if (redisUtil.setNX(key, value, seconds)) {
            Date startDate = DateTimeUtils.getCurrentQuarterStartTime();
            Date endDate = DateTimeUtils.getCurrentQuarterEndTime();
            startDate = DateTimeUtils.getUpdateDateTime(startDate, Calendar.MONTH, -3);
            endDate = DateTimeUtils.getUpdateDateTime(endDate, Calendar.MONTH, -3);
            Date oldDate = DateTimeUtils.getUpdateDateTime(startDate, Calendar.DAY_OF_MONTH, 1);
            String startTime = DateTimeUtils.getDateString(startDate, DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_FULL);
            String endTime = DateTimeUtils.getDateString(endDate, DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_FULL);
            setReportCount(startTime, endTime, oldDate, 1);
        }
    }

    /**
     * 设置云迹半年报表
     */
    @Override
    public void setCloudReportCountBn() {
        String key = "set_cloud_create_Bn_job";
        String value = "cloudCreate";
        long seconds = 100;
        if (redisUtil.setNX(key, value, seconds)) {
            Date startDate = DateTimeUtils.getCurrentQuarterStartTime();
            Date endDate = DateTimeUtils.getCurrentQuarterEndTime();
            startDate = DateTimeUtils.getUpdateDateTime(startDate, Calendar.MONTH, -6);
            endDate = DateTimeUtils.getUpdateDateTime(endDate, Calendar.MONTH, -3);
            Date oldDate = DateTimeUtils.getUpdateDateTime(startDate, Calendar.DAY_OF_MONTH, 1);
            String startTime = DateTimeUtils.getDateString(startDate, DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_FULL);
            String endTime = DateTimeUtils.getDateString(endDate, DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_FULL);
            setReportCount(startTime, endTime, oldDate, 2);
        }
    }

    private Date getCurrYearFirst(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }

    /**
     * 设置云迹报表缓存（根据创建人） 月度报表
     */
    @Override
    public void setCloudReportCount() {
        String key = "set_cloud_create_job";
        String value = "cloudCreate";
        long seconds = 100;
        if (redisUtil.setNX(key, value, seconds)) {
            Date date = new Date();
            Map<String, String> monthMap = getMonthDate(date);
            Date oldDate = DateTimeUtils.getMonthAgo(date, 1);
            String startTime = monthMap.get("first");
            String endTime = monthMap.get("last");
            setReportCount(startTime, endTime, oldDate, 0);
        }
    }

    private void setReportCount(String startTime, String endTime, Date oldDate, final int type) {
        Map<String, Object> map = new HashMap<>(10);
        map.put("group", 1);
        map.put("startTime", startTime);
        map.put("endTime", endTime);
        map.put("type", 0);
        List<CloudActivityEntity> activeList1 = activityMapper.queryByConditions(map);
        if (CollectionUtils.isNotEmpty(activeList1)) {
            final List<CloudActivityEntity> activeList = activeList1;
            final String timeStart = startTime;
            final String timeEnd = endTime;
            final Date date1 = oldDate;
            ExecutorService executor = Executors.newCachedThreadPool();
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    for (final CloudActivityEntity e : activeList) {
                        //开启线程池跑定时，防止超时
                        int createId = e.getCreateId();
                        String createName = e.getCreateName();
                        String city = e.getCity();

                        List<Integer> actIdList = new ArrayList<>();
                        Map<String, Object> map = new HashMap<>(5);
                        map.put("group", 0);
                        map.put("createId", createId);
                        map.put("startTime", timeStart);
                        map.put("endTime", timeEnd);
                        List<CloudActivityEntity> activeListNew = activityMapper.queryByConditions(map);

                        Map<String, Object> map1 = new HashMap<>(5);
                        map.put("city", city);
                        map1.put("createId", createId);
                        map1.put("startTime", timeStart);
                        map1.put("endTime", timeEnd);
                        map1.put("type", type);
                        List<CloudCountEntity> cloudList = cloudCountMapper.queryByConditions(map1);
                        if (CollectionUtils.isNotEmpty(cloudList)) {
                            continue;
                        }
                        if (CollectionUtils.isNotEmpty(activeListNew)) {
                            for (CloudActivityEntity l : activeListNew) {
                                actIdList.add(l.getId());
                            }
                            Map<String, Object> searchMap = new HashMap<>(10);
                            searchMap.put("actIdList", actIdList);
                            searchMap.put("group", 1);
                            List<CloudCustomerEntity> countList = cloudCustomerMapper.queryByConditions(searchMap);
                            int count = countList.size();

                            searchMap.put("type", 1);
                            List<CloudCustomerEntity> waitList = cloudCustomerMapper.queryByConditions(searchMap);
                            searchMap.put("type", 2);
                            List<CloudCustomerEntity> sendGroupList = cloudCustomerMapper.queryByConditions(searchMap);

                            searchMap.put("group", 0);
                            List<CloudCustomerEntity> sendList = cloudCustomerMapper.queryByConditions(searchMap);
                            List<Integer> idList = new ArrayList<>();
                            List<Integer> seaIdList = new ArrayList<>();
                            List<Integer> idAllList = new ArrayList<>();
                            if (CollectionUtils.isNotEmpty(sendList)) {
                                for (CloudCustomerEntity c : sendList) {
                                    if (c.getManagerId() > 0) {
                                        idList.add(c.getCustomerId());
                                    } else {
                                        seaIdList.add(c.getCustomerId());
                                    }
                                }
                                Date time = sendList.get(0).getCreateTime();
                                dealList(idList, idAllList, time, 0);
                                dealSeaList(seaIdList, idAllList, time);
                                idAllList = removeDuplicate(idAllList);

                                //其中跟进数 跟进率 其中意向数（AB） 有效率	其中约看数	约看转化率	其中到访数	到访转化率	其中认购数	其中签约数	成交数	成交转化率
                                if (CollectionUtils.isNotEmpty(idAllList)) {
                                    //已跟进 不计算自动新增的回访
                                    Map<String, Object> backMap = new HashMap<>(10);
                                    backMap.put("idList", idAllList);
                                    backMap.put("notId", 1);
                                    backMap.put("startTime", timeStart);
                                    backMap.put("endTime", timeEnd);
                                    List<Map<String, Object>> backList = callbackMapper.queryCloudBackCount(backMap);
                                    int backCount = backList.size();

                                    Map<String, Object> queryMap = new HashMap<>(5);
                                    queryMap.put("abType", 1);
                                    queryMap.put("idList", idAllList);
                                    queryMap.put("startTime", timeStart);
                                    queryMap.put("endTime", timeEnd);
                                    List<CustomerEntity> abList = customerMapper.queryCloudCount(queryMap);
                                    int abCount = abList.size();

                                    queryMap.put("abType", 0);
                                    queryMap.put("status", 1);
                                    List<Map<String, Object>> seeList = statusLogMapper.queryCloudCount(queryMap);
                                    int seeCount = seeList.size();

                                    queryMap.put("status", 2);
                                    List<Map<String, Object>> daoList = statusLogMapper.queryCloudCount(queryMap);
                                    int daoCount = daoList.size();

                                    queryMap.put("status", 4);
                                    List<Map<String, Object>> buyList = statusLogMapper.queryCloudCount(queryMap);

                                    queryMap.put("status", 5);
                                    List<Map<String, Object>> signList = statusLogMapper.queryCloudCount(queryMap);

                                    queryMap.put("status", 0);
                                    queryMap.put("buyStatus", 1);
                                    List<Map<String, Object>> successList = statusLogMapper.queryCloudCount(queryMap);

                                    String paiRate = dealRate(sendGroupList.size(), count);
                                    String backRate = dealRate(backCount, sendGroupList.size());
                                    String abRate = dealRate(abCount, backCount);
                                    String seeRate = dealRate(seeCount, backCount);
                                    String daoRate = dealRate(daoCount, seeCount);
                                    String successRate = dealRate(successList.size(), daoCount);
                                    CloudCountEntity entity = new CloudCountEntity();
                                    entity.setName(createName);
                                    entity.setCount(count);
                                    entity.setWaitCount(waitList.size());
                                    entity.setSendCount(sendGroupList.size());
                                    entity.setPaiRate(paiRate);
                                    entity.setBackCount(backCount);
                                    entity.setBackRate(backRate);
                                    entity.setAbCount(abCount);
                                    entity.setAbRate(abRate);
                                    entity.setSeeCount(seeCount);
                                    entity.setSeeRate(seeRate);
                                    entity.setDaoCount(daoCount);
                                    entity.setDaoRate(daoRate);
                                    entity.setBuyCount(buyList.size());
                                    entity.setSignCount(signList.size());
                                    entity.setSuccessCount(successList.size());
                                    entity.setSuccessRate(successRate);
                                    entity.setCreateId(createId);
                                    entity.setCreateTime(date1);
                                    entity.setCity(city);
                                    entity.setType(type);
                                    cloudCountMapper.save(entity);
                                }
                            } else {
                                CloudCountEntity entity = new CloudCountEntity();
                                entity.setName(createName);
                                entity.setCount(count);
                                entity.setWaitCount(waitList.size());
                                entity.setSendCount(sendGroupList.size());
                                entity.setPaiRate("");
                                entity.setBackCount(0);
                                entity.setBackRate("");
                                entity.setAbCount(0);
                                entity.setAbRate("");
                                entity.setSeeCount(0);
                                entity.setSeeRate("");
                                entity.setDaoCount(0);
                                entity.setDaoRate("");
                                entity.setBuyCount(0);
                                entity.setSignCount(0);
                                entity.setSuccessCount(0);
                                entity.setSuccessRate("");
                                entity.setCreateTime(date1);
                                entity.setCreateId(createId);
                                entity.setCity(city);
                                entity.setType(type);
                                cloudCountMapper.save(entity);
                            }
                        }
                    }
                }
            });

        }
    }

    private String dealRate(int count1, int count2) {
        String rate = "";
        if (count1 > 0 && count2 > 0) {
            double d = (double) count1 / count2;
            DecimalFormat df = new DecimalFormat("0.00%");
            rate = df.format(d);
        }
        return rate;
    }

    private void dealList(List<Integer> idList, List<Integer> idAllList, Date time, int type) {
        for (Integer id : idList) {
            CustomerEntity entity = customerMapper.queryById(id);
            if (null != entity && StringUtils.isNotBlank(entity.getPhone()) && entity.getManagerId() != null) {
                String phone = entity.getPhone();
                Map<String, Object> map = new HashMap<>(10);
                map.put("phone", phone);
                map.put("isPrivate", 1);
                int managerId = entity.getManagerId();
                map.put("managerId", managerId);
                if (type == 1) {
                    map.put("createTime", time);
                }
                List<CustomerEntity> customerList = customerMapper.queryByConditions(map);
                if (CollectionUtils.isNotEmpty(customerList)) {
                    for (CustomerEntity c : customerList) {
                        idAllList.add(c.getId());
                    }
                }
            }
        }
    }

    private void dealSeaList(List<Integer> seaIdList, List<Integer> idAllList, Date time) {
        for (Integer id : seaIdList) {
            CustomerEntity entity = customerMapper.queryById(id);
            if (null != entity && StringUtils.isNotBlank(entity.getPhone()) && StringUtils.isNotBlank(entity.getLastManager())) {
                String phone = entity.getPhone();
                String lastManager = entity.getLastManager();
                Map<String, Object> map = new HashMap<>(10);
                map.put("phone", phone);
                map.put("isPrivate", 1);
                map.put("lastManager", lastManager);
                map.put("createTime", time);
                List<CustomerEntity> customerList = customerMapper.queryByConditions(map);
                if (CollectionUtils.isNotEmpty(customerList)) {
                    for (CustomerEntity c : customerList) {
                        idAllList.add(c.getId());
                    }
                }
            }
        }
    }

    @Override
    public List<Map<String, Object>> queryListByStatus(List<CloudCustomerEntity> sendList, Map<String, Object> queryMap) {
        List<Integer> idList = new ArrayList<>();
        List<Integer> seaIdList = new ArrayList<>();
        List<Integer> idAllList = new ArrayList<>();
        List<Map<String, Object>> list = new ArrayList<>();
        for (CloudCustomerEntity c : sendList) {
            if (c.getManagerId() > 0) {
                idList.add(c.getCustomerId());
            } else {
                seaIdList.add(c.getCustomerId());
            }
        }
        Date time = sendList.get(0).getCreateTime();
        dealList(idList, idAllList, time, 0);
        dealSeaList(seaIdList, idAllList, time);
        idAllList = removeDuplicate(idAllList);
        int createId = Integer.parseInt(queryMap.get("createId").toString());
        UserEntity user = usermapper.getById(createId);
        String createName = "";
        if (null != user) {
            createName = user.getRealName();
        }
        //姓名 手机号 安家顾问 创建人 到访项目 到访时间 现在状态
        if (CollectionUtils.isNotEmpty(idAllList)) {
            queryMap.put("idList", idAllList);
            List<Map<String, Object>> daoList = statusLogMapper.queryCloudCount(queryMap);
            if (CollectionUtils.isNotEmpty(daoList)) {
                for (Map<String, Object> d : daoList) {
                    Map<String, Object> putMap = new HashMap<>(20);
                    putMap.put("name", d.get("name"));
                    putMap.put("phone", d.get("phone"));
                    putMap.put("createName", createName);
                    int projectId = Integer.parseInt(d.get("projectId").toString());
                    ProjectEntity project = projectMapper.getById(projectId);
                    if (null != project) {
                        putMap.put("projectName", project.getProjectName());
                    } else {
                        putMap.put("projectName", "");
                    }
                    putMap.put("occurTime", d.get("occurTime"));
                    if (null != d.get("managerName") && StringUtils.isNotBlank(d.get("managerName").toString())) {
                        putMap.put("managerName", d.get("managerName"));
                        putMap.put("customerStatus", "私客");
                    } else {
                        putMap.put("managerName", "");
                        putMap.put("customerStatus", "公海");
                    }
                    list.add(putMap);
                }
            }
        }
        return list;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateJgStatus() {
        String key = "update_jg_status_job";
        String value = "jgStatus";
        try {
            long seconds = 100;
            if (redisUtil.setNX(key, value, seconds)) {
                List<Integer> list = new ArrayList<>();
                Map<String, Object> map = new HashMap<>(5);
                map.put("showStatus", 1);
                List<ProjectEntity> projectList = projectMapper.queryByConditions(map);
                if (CollectionUtils.isNotEmpty(projectList)) {
                    for (ProjectEntity p : projectList) {
                        list.add(p.getId());
                    }
                }
                customerProject.updateJgData(list, 2, "经管系统");
            }
        } catch (Exception e) {
            logger.error("定时同步经管状态失败", e);
        }
    }

    /**
     * 获取上个月第一天与最后一天
     *
     * @param date
     * @return
     */
    public static Map<String, String> getMonthDate(Date date) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -1);
        Date theDate = calendar.getTime();

        //上个月第一天
        GregorianCalendar gcLast = (GregorianCalendar) Calendar.getInstance();
        gcLast.setTime(theDate);
        gcLast.set(Calendar.DAY_OF_MONTH, 1);
        String dayFirst = df.format(gcLast.getTime());
        StringBuilder str = new StringBuilder().append(dayFirst).append(" 00:00:00");
        dayFirst = str.toString();

        //上个月最后一天
        calendar.add(Calendar.MONTH, 1);
        calendar.set(Calendar.DATE, 1);
        calendar.add(Calendar.DATE, -1);
        String dayLast = df.format(calendar.getTime());
        StringBuilder endStr = new StringBuilder().append(dayLast).append(" 23:59:59");
        dayLast = endStr.toString();

        Map<String, String> map = new HashMap<>(10);
        map.put("first", dayFirst);
        map.put("last", dayLast);
        return map;
    }

    /**
     * 定时添加营销活动并拉取数据，只针对南京站
     */
    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void addMarketActivity() {
        int sendUserId = 1;
        try {
            String city = "nj";
            Map<String, Object> queryMap = new HashMap<>(5);
            queryMap.put("onduty", 1);
            List<DutyStaffEntity> list = staffMapper.queryByConditions(queryMap);
            if (CollectionUtils.isNotEmpty(list)) {
                DutyStaffEntity dutyStaffEntity = list.get(0);
                sendUserId = Integer.parseInt(dutyStaffEntity.getUserId());
                int userId = Integer.parseInt(dutyStaffEntity.getUserId());
                String userName = dutyStaffEntity.getName();
                MarketingActivityEntity entity = new MarketingActivityEntity();
                setMarketActivity(entity, userId, userName);
                int id = marketingActivityService.save(entity);
                addMarketCustomer(id, city, entity);
                //通知CRM所使用的数据
                MarketCustomerEntity mce = new MarketCustomerEntity();
                mce.setActiveId(id);
                List<MarketCustomerEntity> useList = marketCustomer.getUseMarketingActivity(mce);
                System.out.println("success" + useList.size());
                if (CollectionUtils.isNotEmpty(useList)) {
                    String confirmUrl = MemoryPropertyPlaceholderConfigurer.getContextProperty("CRM.CONFIRM.URL");
                    List<NameValuePair> inParam = new ArrayList<>();
                    inParam.add(new BasicNameValuePair("city", city));
                    inParam.add(new BasicNameValuePair("timestamp", String.valueOf(System.currentTimeMillis() / 1000)));
                    JSONArray array = new JSONArray();
                    useList.forEach(u -> {
                        JSONObject jo = new JSONObject();
                        jo.put("phone", u.getPhone());
                        jo.put("crm_id", u.getCrmId());
                        array.add(jo);
                    });
                    inParam.add(new BasicNameValuePair("data", array.toString()));
                    String confirmResult = HttpClientUtil.doPost(confirmUrl, inParam);
                    logger.info("******通知CRM营销拉取客户信息返回结果:" + confirmResult);
                }

                entity.setGainCount(redisUtils.getIntegerByKey("active:done:" + id));
                entity.setProtectCount(redisUtils.getIntegerByKey("active:protect:" + id));
                marketingActivityService.update(entity);
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("创建营销活动失败", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            sendErrorMsg(sendUserId);
        }
    }

    private void sendErrorMsg(int userId) {
        try {
            String city = "nj";
            //发送短信修改
//            String mobile = "18862152977";
            UserEntity userEntity = usermapper.getById(userId);
            String mobile = userEntity.getMobile();
            String msg = "定时营销活动拉取失败";
            msg = URLEncoder.encode(msg, "GBK");
            String smUrl = "http://mysms.house365.com/index.php/Interface/apiSendMobil/jid/104/depart/1/city/";
            smUrl = smUrl + city + "/" + "mobileno/" + mobile;
            List<NameValuePair> params = new ArrayList<>();
            params.add(new BasicNameValuePair("msg", msg));
            String result = HttpClientUtil.doGet(smUrl, params, null);
            if (result != null) {
                logger.info("定时发送拉取提醒短信成功");
            } else {
                logger.error("定时发送拉取提醒短信失败");
            }
            System.out.println(msg);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("发送营销提醒短信失败");
        }
    }

    private void setMarketActivity(MarketingActivityEntity entity, int userId, String userName) {
        String source = "2,3,29,30,31";
        Date now = new Date();
        now = DateTimeUtils.getDaysAgo(now, 1);
        String date = new SimpleDateFormat("yyyy-MM-dd").format(now);
        date = date.replace("-", "");
        String name = "系统自动抓取" + date;
        entity.setName(name);
        entity.setType(1);
        entity.setCycle(10);
        entity.setExpectExtractCount(999);
        entity.setProjectName("");
        entity.setMobileType(null);
        entity.setApplyStartTime(now);
        entity.setApplyEndTime(now);
        setApplySource(source, entity);
        entity.setActiveType(null);
        entity.setTotalPriceLower(null);
        entity.setTotalPriceHigher(null);
        entity.setAreaLower(null);
        entity.setAreaHigher(null);
        entity.setReturnVisitTimeStart(null);
        entity.setReturnVisitTimeEnd(null);
        entity.setReturnVisitStatus(null);
        entity.setReturnVisitResult(null);
        entity.setCreateBy(userId);
        entity.setCreateName(userName);
        entity.setCreateTime(new Date());
        entity.setUpdateBy(userId);
        entity.setUpdateTime(new Date());
        entity.setGainCount(0);
        entity.setOverTimeCount(0);
        entity.setVisitBackCount(0);
        entity.setWaitVisitCount(0);
        entity.setBoughtCount(0);
        entity.setProtectCount(0);

        entity.setActiveTypeName(null);
        entity.setReturnVisitStatusName("");
        entity.setStatus(1);
        entity.setFinishTime(DateTimeUtils.getTimeAfterDays(now, 20));
        entity.setCity("nj");
        entity.setBlock("");
        entity.setBlockName("");
        entity.setDistrict("");
        entity.setDistrictName("");
        entity.setChannel("");
        entity.setChannelName("");
        entity.setActivityName("");
        entity.setMobile("");
        entity.setCallNum("");
        entity.setSeeProjectName("");
        entity.setSeeStartTime(null);
        entity.setSeeEndTime(null);
        entity.setSeeCount(0);
    }

    private void addMarketCustomer(int activeId, String city, MarketingActivityEntity entity) throws Exception {
        try {
            if (redisUtils.hasKey("active:protect:" + activeId)) {
                redisUtils.deleteByKeyNew("active:protect:" + activeId);
            }
            if (redisUtils.hasKey("active:done:" + activeId)) {
                redisUtils.deleteByKeyNew("active:done:" + activeId);
            }
            List<NameValuePair> pairList = new ArrayList<>();
            wrapNameValuePairList(pairList, entity);
            pairList.add(new BasicNameValuePair("page", "1"));
            pairList.add(new BasicNameValuePair("limit", "1000"));
            pairList.add(new BasicNameValuePair("city", city));
            String result = HttpClientUtil.doGet(crmQueryUrl, pairList, 60000, "utf-8");
            String url = crmQueryUrl + "?";
            List<String> params = new ArrayList<>();
            pairList.forEach(p -> params.add(p.getName() + "=" + p.getValue()));

            url += Joiner.on("&").join(params);
            logger.warn("定时营销拉取URL===[{}]", url);

            logger.warn("定时营销拉取线程:" + "-" + " -> 运行..." + "result:" + result);
            JSONObject resobj = JSONObject.fromObject(result);
            if (resobj.containsKey("docs") && resobj.get("docs") != null) {
                JSONArray objArray = (JSONArray) resobj.get("docs");

                Map<String, Object> dicMap = new HashMap<>(10);
                dicMap.put("city", city);
                dicMap.put("dicKey", "customer.protect.day");
                List<DictionaryEntity> dictionaryList = dictionaryMapper.getNoApproximateConfig(dicMap);
                List<CustomerEntity> list = new ArrayList<>();
                if (CollectionUtils.isNotEmpty(dictionaryList) && !"0".equals(dictionaryList.get(0).getDicValue())) {
                    Map<String, Object> hotMap = new HashMap<>(10);
                    hotMap.put("status", 0);
                    hotMap.put("createSource", "HOTLINE");
                    hotMap.put("isProtect", dictionaryList.get(0).getDicValue());
                    hotMap.put("isAdd", 1);
                    hotMap.put("city", city);
                    list = customerMapper.queryForAddHot(hotMap);
                }
                if (CollectionUtils.isNotEmpty(list)) {
                    try {
                        for (CustomerEntity c : list) {
                            Iterator<Map<String, Object>> iterator = objArray.iterator();
                            while (iterator.hasNext()) {
                                Map<String, Object> iterMap = iterator.next();
                                if (iterMap.get("phone").toString().equals(c.getPhone())) {
                                    iterator.remove();
                                }
                            }
                        }
                    } catch (Exception e) {
                        throw new Exception("去重失败");
                    }
                }
                for (Object c : objArray) {
                    JSONObject cu = (JSONObject) c;
                    MarketCustomerEntity customerEntity = getCustomer(cu);

                    //check protect customer and save
                    if (marketCustomer.queryProtectCount(customerEntity.getPhone()) > 0) {
                        increaseProtectKey(activeId);
                        continue;
                    } else {
                        increaseDoneKey(activeId);
                        customerEntity.setActiveId(activeId);
                        //同时获取signupSourceName
                        setSignSourceName(customerEntity);
                        marketCustomer.save(customerEntity);
                        //数据库负载较大，为避免报警，调大阀值
                        Thread.sleep(300);
                    }
                }
            }
        } catch (Exception e) {
            throw new Exception("拉取客户失败");
        }
    }

    private synchronized Long increaseProtectKey(Integer activeId) {
        return redisUtils.increaseByKey("active:protect:" + activeId);
    }

    private synchronized Long increaseDoneKey(Integer activeId) {
        return redisUtils.increaseByKey("active:done:" + activeId);
    }

    private void setApplySource(String quickSource, MarketingActivityEntity entity) {
        Set<String> crmSourceSet = new HashSet<>();
        //根据快捷来源选择所有下级CRM来源 v3.2.0
        for (String source : quickSource.split(",")) {
            List<CrmSourceEntity> sourceList = crmSourceService.getListByCategory(source);
            if (CollectionUtils.isNotEmpty(sourceList)) {
                sourceList.removeIf(m -> m.getSourceId() == 99 || m.getSourceId() == 562);
                sourceList.forEach(s -> crmSourceSet.add(String.valueOf(s.getSourceId())));
            }
        }
        if (!crmSourceSet.isEmpty()) {
            String source = Joiner.on(",").join(crmSourceSet);
            entity.setApplySource(source);
            entity.setApplySourceName("电商、房博士、400电话、楼盘订阅、看房团");
        }
    }

    private synchronized static MarketCustomerEntity getCustomer(Map<String, Object> map) {
        String name = getMapValueByKey(Constant.CUSTOMER_NAME, map, "", 150);
        String phone = getMapValueByKey(Constant.CUSTOMER_PHONE, map, "", 90);
        String cityCode = getMapValueByKey(Constant.CITY_CODE, map, "", 15);
        String cityName = getMapValueByKey(Constant.CITY_NAME, map, "", 15);
        String crmId = getMapValueByKey(Constant.CRMID, map, "", 20);
        String sex = getMapValueByKey(Constant.CUSTOMER_SEX, map, String.valueOf(Constant.CustomerSexEnum.NOTSURE.getMsg()), 5);
        String actSource = getMapValueByKey(Constant.CUSTOMER_ACTSOURCE, map, "", 300);
        String firstSource = getMapValueByKey(Constant.CUSTOMER_FIRSTSOURCE, map, "", 100);
        String latestSource = getMapValueByKey(Constant.CUSTOMER_LATESTSOURCE, map, "", 100);
        String latestCall = getMapValueByKey(Constant.CUSTOMER_CRM_LATESTSCALL, map, "", 100);
        String latestCallResult = getMapValueByKey(Constant.CUSTOMER_CRM_LATESTSCALL_RESULT, map, "", 100);
        String bizPort = getMapValueByKey("bizPort", map, "", 30);
        String buyIntention = getMapValueByKey("latestCallResult", map, "", 30);
        String projectIds = getMapValueByKey("projectIds", map, "", 200);
        String projectSourceId = getMapValueByKey("projectSourceId", map, "", 10);
        String projectSourceTime = getMapValueByKey("projectSourceTime", map, "", 30);

        List<String> contact = new ArrayList<>();
        if (!Strings.isNullOrEmpty(projectIds)) {
            JSONArray pids = JSONArray.fromObject(projectIds);
            for (Object object : pids) {
                contact.add(String.valueOf(object));
            }
        }
        Date date = new Date();

        actSource = com.house365.web.util.StringUtils.StringFilter(actSource);
        MarketCustomerEntity customerEntity = new MarketCustomerEntity();
        customerEntity.setName(name);
        customerEntity.setPhone(phone);
        customerEntity.setCityCode(cityCode);
        customerEntity.setCityName(cityName);
        customerEntity.setCrmId(crmId);
        customerEntity.setSex(Integer.valueOf(sex));
        customerEntity.setBizPort(bizPort);
        customerEntity.setActSource(actSource);
        customerEntity.setFirstSource(firstSource);
        customerEntity.setCreateSource("CRM拉取");
        customerEntity.setCustomerType(Constant.CustomerTypeEnum.ONLINE.getMsg());
        customerEntity.setLatestSource(latestSource);
        customerEntity.setCrmLatestCall(latestCall);
        customerEntity.setCrmLatestCallResult(latestCallResult);
        customerEntity.setCreateTime(date);
        customerEntity.setCreater(Constant.CustomerSourceEnum.CRM.getMsg());
        customerEntity.setUpdater(Constant.CustomerSourceEnum.CRM.getMsg());
        customerEntity.setUpdateTime(date);
        customerEntity.setStatus(Constant.CustomerStatusEnum.NORECORD.getStatus());
        customerEntity.setBuyIntention(buyIntention);
        customerEntity.setTraceStatus(1);
        customerEntity.setCrmSync("1");
        customerEntity.setIsDelete(0);
        customerEntity.setIsOvertime(0);
        customerEntity.setSignupSourceId(projectSourceId);
        customerEntity.setSignupSourceName("");
        customerEntity.setSignupTime(projectSourceTime);
        customerEntity.setSignupHouseId(Joiner.on(",").join(contact));
        customerEntity.setSignupHouseName("");

        return customerEntity;
    }

    private static String getMapValueByKey(String key, Map<String, Object> map, String defaultValue, Integer length) {
        String value = "";
        if (map.containsKey(key) && map.get(key) != null && !Strings.isNullOrEmpty(String.valueOf((map.get(key))))) {
            value = String.valueOf(map.get(key));
        }

        if (Strings.isNullOrEmpty(value) || "null".equalsIgnoreCase(value)) {
            value = defaultValue;
        }

        if (null != length) {
            value = value.length() > length ? value.substring(0, length) : value;
        }
        return value;
    }


    private void wrapNameValuePairList(List<NameValuePair> nameValuePairList, MarketingActivityEntity entity) {
        //报名来源
        if (StringUtils.isNotBlank(entity.getApplySource())) {
            String[] sources = entity.getApplySource().split(",");
            int i = 0;
            for (String source : sources) {
                if (!Strings.isNullOrEmpty(source)) {
                    nameValuePairList.add(new BasicNameValuePair("target_source[" + i + "]", source));
                    i++;
                }
            }
        }

        //报名时间
        if (entity.getApplyStartTime() != null && entity.getApplyEndTime() != null) {
            nameValuePairList.add(new BasicNameValuePair("join_time[0]",
                    DateTimeUtils.parseDate(entity.getApplyStartTime(), DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_SHORT)));
            nameValuePairList.add(new BasicNameValuePair("join_time[1]",
                    DateTimeUtils.parseDate(entity.getApplyEndTime(), DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_SHORT)));
        }
    }

    /**
     * 设置crm来源名称
     *
     * @param entity
     */
    private void setSignSourceName(MarketCustomerEntity entity) {
        if (StringUtils.isNotBlank(entity.getSignupSourceId())) {
            int sourceId = Integer.parseInt(entity.getSignupSourceId());
            Map<String, Object> map = new HashMap<>(3);
            map.put("sourceId", sourceId);
            List<CrmSourceEntity> list = crmSourceMapper.queryByConditions(map);
            if (CollectionUtils.isNotEmpty(list)) {
                entity.setSignupSourceName(list.get(0).getSourceName());
            }
        } else {
            entity.setSignupSourceName("");
        }
    }

}
