/**
 * Description: 客户信息业务实现类
 * Copyright:   Copyright (c)2016
 * Company:     江苏三六五网络股份有限公司
 *
 * @author: 江苏三六五网络股份有限公司
 * @version: 1.0
 * Create at:   2016-09-15 下午 15:36:13
 * <p>
 * Modification History:
 * Date         Author      Version     Description
 * ------------------------------------------------------------------
 * 2016-09-15   江苏三六五网络股份有限公司   1.0         Initial
 */
package com.house365.ws.service.impl;

import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.house365.beans.common.HGSConstant;
import com.house365.beans.common.MessageTypeEnum;
import com.house365.beans.entity.*;
import com.house365.beans.system.QueryParams;
import com.house365.beans.vo.CrmVisitAndSignCustomer;
import com.house365.commons.system.HttpClientUtil;
import com.house365.dao.system.interfaces.Dao;
import com.house365.service.system.impl.DefaultServiceImpl;
import com.house365.web.util.DateTimeUtils;
import com.house365.web.util.MemoryPropertyPlaceholderConfigurer;
import com.house365.web.util.StringUtils;
import com.house365.ws.dao.interfaces.ICustomerDao;
import com.house365.ws.dao.mapper.*;
import com.house365.ws.service.interfaces.*;
import com.house365.ws.util.Constant;
import com.house365.ws.util.OperateLogUtils;
import org.apache.commons.collections4.CollectionUtils;
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.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.house365.beans.common.MessageTypeEnum.*;
import static com.house365.web.util.DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_FULL;
import static com.house365.web.util.DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_SHORT;

/**
 * 客户信息业务实现类<br>
 *
 * @author 江苏三六五网络股份有限公司
 * @version 1.0, 2016-09-15
 * @see
 * @since 1.0
 */
@Service("customerService")
public class CustomerServiceImpl<T extends CustomerEntity> extends DefaultServiceImpl<T> implements ICustomerService<T> {

    //获取城市保护期设置数据
    private static final String DICKEY = "customer.protect.days";
    private final List<Integer> statusList = Lists.newArrayList(1, 2, 3, 4, 5, 6);
    private Logger logger = LoggerFactory.getLogger(getClass());
    /**
     * 自动注入的数据访问对象
     */
    @Autowired
    private ICustomerDao<T> customerDao;
    @Autowired
    private ICustomerSourceService customerSourceService;
    @Autowired
    private ICustomerStatusLogService customerStatusLogService;
    @Autowired
    private IProjectService projectService;
    @Autowired
    private IProjectSourceStatisticsService projectSourceStatisticsService;
    @Autowired
    private IUserSourceStatisticsService userSourceStatisticsService;
    @Autowired
    private IStatusSourceStatisticsService statusSourceStatisticsService;
    @Autowired
    private IDeptSourceStatisticsService deptSourceStatisticsService;
    @Autowired
    private IDepartmentService departmentService;
    @Autowired
    private IUserService userService;
    @Autowired
    private IDictionaryService dictionaryService;
    @Autowired
    private IWechatService wechatService;
    @Autowired
    private ICustomerUserService customerUserService;
    @Autowired
    private INoticeService noticeService;
    @Autowired
    private IRushCustomerService rushCustomerService;
    @Autowired
    private IHgsCacheUtil hgsCacheUtil;
    @Autowired
    private IMarketCustomerService marketCustomerService;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private DictionaryMapper dictionaryMapper;
    @Autowired
    private CustomerMergeMapper customermergemapper;
    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
    private OperateLogUtils logUtils;
    @Autowired
    private CloudCustomerMapper cloudCustomerMapper;

    private Map<Integer, DepartmentEntity> cityMap = new HashMap<>();
    private List<CustomerSourceEntity> customerSourceEntities = new ArrayList<>();

    @Override
    protected Dao<T> getDao() {
        return customerDao;
    }

    @Override
    public void updateManager(Integer managerId, String managerName) {
        customerDao.updateManager(managerId, managerName);
    }

    @Override
    public void updateOldCustomers(CustomerEntity customer) {
        customerDao.updateOldCustomers(customer);
    }

    @Override
    public void sendCustomerToCRMJOB() {
        logger.info("run task [sendCustomerToCRMJOB] at [{}]",
                DateTimeUtils.getDateString(new Date(), DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_FULL));

        String env = MemoryPropertyPlaceholderConfigurer.getContextProperty("system.env");

        if ("test".equalsIgnoreCase(env)) {
            return;
        }

        //get all cities record
        List<DictionaryEntity> dics = dictionaryService.getListByKey(DICKEY);
        if (CollectionUtils.isNotEmpty(dics)) {

            StringBuilder customerIds = new StringBuilder("");
            Date now = new Date();
            Set<String> cities = new HashSet<>();
            for (DictionaryEntity dict : dics) {
                String city = dict.getCity();
                cities.add(city);
                Integer period = Integer.valueOf(dict.getDicValue());
                if (period >= 0) {
                    //为0不保护
                    Date checkDate = now;
                    if (period > 0) {
                        checkDate = DateTimeUtils.getDaysAgo(now, period);
                    }

                    if (!Strings.isNullOrEmpty(city)) {
                        Map<String, Object> customerQueryMap = new HashMap<>(10);
                        customerQueryMap.put("EQ_cityCode", city);
                        customerQueryMap.put("EQ_crmSync", "0");
                        customerQueryMap.put("NOTEQ_creater", "CRM");
                        customerQueryMap.put("LTE_createTime", checkDate);
                        QueryParams customerQueryParams = new QueryParams();
                        customerQueryParams.setSearchParams(customerQueryMap);
                        List<CustomerEntity> customerEntities = (List<CustomerEntity>) customerDao.queryAll(customerQueryParams);
                        for (CustomerEntity ce : customerEntities) {
                            try {
                                customerIds.append(ce.getId()).append(",");
                                postToCRM(ce);
                                ce.setCrmSync("1");
                                update((T) ce);
                            } catch (Exception e) {
                                logger.error(e.getMessage(), e);
                            }
                        }

                    }
                } else {
                    logger.info("not run! city {} , period {}", city, period);
                }
            }

            if (!cities.isEmpty()) {
                for (String city : cities) {
                    if (!Strings.isNullOrEmpty(city)) {
                        Map<String, Object> customerQueryMap = new HashMap<>(10);
                        customerQueryMap.put("EQ_excludeCity", cities.toArray());
                        customerQueryMap.put("EQ_crmSync", "0");
                        customerQueryMap.put("NOTEQ_creater", "CRM");
                        QueryParams customerQueryParams = new QueryParams();
                        customerQueryParams.setSearchParams(customerQueryMap);
                        List<CustomerEntity> customerEntities = (List<CustomerEntity>) customerDao.queryAll(customerQueryParams);
                        for (CustomerEntity ce : customerEntities) {
                            try {
                                customerIds.append(ce.getId()).append(",");
                                postToCRM(ce);
                                ce.setCrmSync("1");
                                update((T) ce);
                                Thread.sleep(200);
                            } catch (Exception e) {
                                logger.error(e.getMessage(), e);
                            }
                        }
                    }
                }
            }

            logger.info("sync customer to crm [{}]", customerIds);
        }

    }

    @Override
    public void bindCustomer(CustomerEntity customerEntity, UserEntity user) throws Exception {
        if (customerEntity != null && user != null) {
            customerEntity.setManagerId(user.getId());
            customerEntity.setIsRecycled(0);
            customerEntity.setManagerName(user.getRealName());
            customerEntity.setUpdateTime(new Date());
            if (Strings.isNullOrEmpty(customerEntity.getCrmId())) {
                customerEntity.setUpdater(Constant.CustomerSourceEnum.SYSTEM.getMsg());
            } else {
                customerEntity.setUpdater(Constant.CustomerSourceEnum.CRM.getMsg());
            }
            update((T) customerEntity);
            Integer fromStatus = customerEntity.getStatus();
            if (customerEntity.getStatus() == Constant.CustomerStatusEnum.NORECORD.getStatus()) {
                fromStatus = null;
            }
            if (customerEntity.getStatus().equals(Constant.HotLineStatusEnum.INIT.getMsg())) {
                fromStatus = null;
            }
            if (customerEntity.getStatus().equals(Constant.HotLineStatusEnum.DELETE.getMsg())) {
                fromStatus = null;
            }

            hgsCacheUtil.delUserSummary(customerEntity.getManagerId());

            if (!Constant.CustomerSourceEnum.HOTLINE.getMsg().equals(customerEntity.getCreateSource())) {
                customerStatusLogService.addStatusLog(customerEntity.getId(), fromStatus, customerEntity.getStatus(),
                        "CRM绑定用户", Constant.CustomerSourceEnum.CRM.getMsg());
            }
        }
    }

    @Override
    public String postToCRM(CustomerEntity customer) throws Exception {

        if (Strings.isNullOrEmpty(customer.getPhone()) || Strings.isNullOrEmpty(
                customer.getCityCode()) || Strings.isNullOrEmpty(customer.getActSource())) {
            throw new Exception("参数不完整");
        }

        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 = "335";
        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 "";
    }

    /**
     * 接口调用的新增客户方法
     *
     * @param customerEntity 客户实体类
     * @param creator        创建人
     * @param userName       客户日志的创建人
     * @return
     * @throws Exception
     */
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    @Override
    public CustomerEntity createCustomer(CustomerEntity customerEntity, String creator, String userName) throws Exception {

        //更新来源
        Integer sourceId = customerSourceService.updateSource(customerEntity.getCityCode(),
                customerEntity.getActSource(),
                customerEntity.getCreateSource(), creator);
        customerEntity.setActSourceId(sourceId);
        //保存客户
        Integer customerId = save((T) customerEntity);
        // //新增客户新增日志
        customerEntity.setId(customerId);
        logUtils.saveCustomerLog(customerEntity, 1, 0, userName);

        hgsCacheUtil.delUserSummary(customerEntity.getManagerId());

        //推送微信消息
        Map<String, String> param = new HashMap<>();
        param.put("customerId", customerId.toString());
        sendMessageToWechat(NEWCUSTOMER, String.valueOf(customerEntity.getManagerId()), param);


        //纪录状态日志
        //        customerStatusLogService.addStatusLog(customerId, null, Constant.CustomerStatusEnum.NORECORD.getStatus(),
        //                                              "创建用户", creator);
        return customerEntity;
    }

    /**
     * 根据统计条件过滤客户ID
     *
     * @param summaryType 1 今日新增 2 今日驻场信息有更新的客户 3 超过7天未回访的新增客户 4 超过3天未回访的客户 5 已到访后超过7天状态未更新的客户
     * @return
     */
    @Override
    public List<Integer> getSummaryIds(String summaryType, String managerId) {
        List<Map<String, Object>> list = null;
        switch (summaryType) {
            case "1":
                list = getNewCustomerIds(managerId);
                break;
            case "2":
                list = getTodayUpdateIds(managerId);
                break;
            case "3":
                list = getNocallSevenDayIds(managerId);
                break;
            case "4":
                list = getNocallThreeDayIds(managerId);
                break;
            case "5":
                list = getNoStatusUpdateIds(managerId);
                break;
            default:
                list = new ArrayList<>();
                break;
        }

        List<Integer> idList = new ArrayList<>();
        for (Map<String, Object> map : list) {
            idList.add(Integer.valueOf(String.valueOf(map.get("id"))));
        }

        return idList;
    }

    /**
     * 今日新增客户
     *
     * @param managerId
     * @return
     */
    @Override
    public List<Map<String, Object>> getNewCustomerIds(String managerId) {
        List<Integer> userIds = userService.getUserIdOnPath(Integer.valueOf(managerId));
        return customerDao.getNewCustomerIds(Joiner.on(",").join(userIds));
    }

    /**
     * 今日驻场信息有更新
     *
     * @param managerId
     * @return
     */
    @Override
    public List<Map<String, Object>> getTodayUpdateIds(String managerId) {
        List<Integer> userIds = userService.getUserIdOnPath(Integer.valueOf(managerId));
        return customerDao.getTodayUpdateIds(Joiner.on(",").join(userIds));
    }

    /**
     * 超过7天未回访的新增客户
     *
     * @param managerId
     * @return
     */
    @Override
    public List<Map<String, Object>> getNocallSevenDayIds(String managerId) {
        List<Integer> userIds = userService.getUserIdOnPath(Integer.valueOf(managerId));
        return customerDao.getNocallSevenDayIds(Joiner.on(",").join(userIds));
    }

    /**
     * 超过3天未回访的客户
     *
     * @param managerId
     * @return
     */
    @Override
    public List<Map<String, Object>> getNocallThreeDayIds(String managerId) {
        List<Integer> userIds = userService.getUserIdOnPath(Integer.valueOf(managerId));
        return customerDao.getNocallThreeDayIds(Joiner.on(",").join(userIds));
    }

    /**
     * 已到访后超过7天状态未更新的客户
     *
     * @param managerId
     * @return
     */
    @Override
    public List<Map<String, Object>> getNoStatusUpdateIds(String managerId) {
        List<Integer> userIds = userService.getUserIdOnPath(Integer.valueOf(managerId));
        return customerDao.getNoStatusUpdateIds(Joiner.on(",").join(userIds));
    }

    /**
     * 已约见后超过N天状态未到访的客户
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> getNoVisitIdsByDays(Integer days, String city) {
        Map<String, Object> parameter = new HashMap<>(10);
        parameter.put("days", days);
        parameter.put("city", city);
        parameter.put("status", Constant.CustomerStatusEnum.RECORDED.getStatus());
        return customerDao.getNoVisitIdsByDays(parameter);
    }

    /**
     * 已到访后超过N天状态未认筹的客户
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> getNoPledgedIdsByDays(Integer days, String city) {
        Map<String, Object> parameter = new HashMap<>(10);
        parameter.put("days", days);
        parameter.put("city", city);
        parameter.put("status", Constant.CustomerStatusEnum.VISITED.getStatus());
        return customerDao.getNoPledgedIdsByDays(parameter);
    }

    /**
     * 获取概要统计信息
     *
     * @param managerId 客户经理ID
     * @return map newadd 今日新增 newupdate 今日驻场数据有更新的客户 nocall7 超过7天未回访的新增客户
     * nocall3 超过3天未回访的客户 noupdate 到访后超过7天状态未更新的客户
     */
    @Override
    public Map<String, Object> getSummary(String managerId) {
        List<Integer> userIds = userService.getUserIdOnPath(Integer.valueOf(managerId));
        return customerDao.getSummary(Joiner.on(",").join(userIds));
    }

    @Override
    public Map<String, Object> getNewSummary(Map<String, String> summaryParams) {
        return customerDao.getNewSummary(summaryParams);
    }

    @Override
    public Map<String, Object> getSummarySimple(String managerId) {
        List<Integer> userIds = userService.getUserIdOnPath(Integer.valueOf(managerId));
        return customerDao.getSummarySimple(Joiner.on(",").join(userIds));
    }

    /**
     * 获取公海统计信息 totalCount 总数 todayCount 今日新增
     *
     * @param cityCode
     * @return
     */
    @Override
    public Map<String, Object> getSeaSummary(String cityCode) {
        return customerDao.getSeaSummary(cityCode);
    }

    //微信我的客户首页统计信息
    @Override
    public Map<String, Object> getWechatMyCucstomerSummary(String managerId) {
        List<Integer> userIds = userService.getUserIdOnPath(Integer.valueOf(managerId));
        return customerDao.getWechatMyCucstomerSummary(Joiner.on(",").join(userIds));
    }

    //微信我的客户首页统计信息-置业顾问
    @Override
    public List<Map<String, Object>> getWechatMyCucstomerUserView(String managerId, String pageNo, String pageSize) {
        //        List<Integer> userIds = userService.getUserIdOnPath(Integer.valueOf(managerId));
        return customerDao.getWechatMyCucstomerUserView(managerId, pageNo, pageSize);
    }

    //获取最后评论记录，customerIds为逗号隔开，返回customerId和content
    @Override
    public List<Map<String, Object>> getLastestCallback(String customerIds) {
        return customerDao.getLastestCallback(customerIds);
    }

    /**
     * CRM 接口 三个月内 callCount 回访数 visitCount 到访数 signCount 签约数
     *
     * @param phone
     * @return
     */
    @Override
    public Map<String, Object> getSummaryForCRM(String phone) {
        return customerDao.getSummaryForCRM(phone);
    }

    @Override
    public Map<String, Object> getSummary7ForCRM(String phone) {
        return customerDao.getSummary7ForCRM(phone);
    }

    /**
     * 同步统计指标名称
     */
    @Override
    public void updateName() {
        logger.info("run task [updateName] at [{}]",
                DateTimeUtils.getDateString(new Date(), DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_FULL));
        projectSourceStatisticsService.updateNames();
        userSourceStatisticsService.updateNames();
        deptSourceStatisticsService.updateNames();
        statusSourceStatisticsService.updateNames();
    }

    @Override
    public void statisticTask() {
        logger.info("run task [statisticTask] at [{}]",
                DateTimeUtils.getDateString(new Date(), DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_FULL));
        statisticByDay(1);
    }

    /**
     * 统计指定天数前数据
     *
     * @param day 统计前多少天的数据
     */
    @Override
    public void statisticByDay(int day) {
        Map<String, String> parameter = new HashMap<>(10);
        Date startDate = DateTimeUtils.getDaysAgo(new Date(), day);
        Date now = DateTimeUtils.getToday(new Date());

        while (startDate.compareTo(now) < 0) {
            Date endDate = DateTimeUtils.getDaysAfter(startDate, 1);

            String startDateStr = DateTimeUtils.parseDate(startDate, DEFAULT_DATE_FORMAT_PATTERN_FULL);
            String endDateStr = DateTimeUtils.parseDate(endDate, DEFAULT_DATE_FORMAT_PATTERN_FULL);

            parameter.put("startDate", startDateStr);
            parameter.put("endDate", endDateStr);

            QueryParams queryParams = new QueryParams();
            Map<String, Object> psm = new HashMap<>();
            psm.put("EQ_createTime", startDateStr);
            queryParams.setSearchParams(psm);
            int count = projectSourceStatisticsService.getTotalCount(queryParams);
            int count1 = userSourceStatisticsService.getTotalCount(queryParams);
            int count2 = deptSourceStatisticsService.getTotalCount(queryParams);
            int count3 = statusSourceStatisticsService.getTotalCount(queryParams);

            //没有当前日期data，新增
            if (count > 0) {
                projectSourceStatisticsService.deleteByDate(startDateStr);
            }

            if (count1 > 0) {
                userSourceStatisticsService.deleteByDate(startDateStr);
            }

            if (count2 > 0) {
                deptSourceStatisticsService.deleteByDate(startDateStr);
            }

            if (count3 > 0) {
                statusSourceStatisticsService.deleteByDate(startDateStr);
            }

            statisticNoRecordByUser(cityMap, parameter, startDate);
            statisticNoRecordByDept(cityMap, parameter, startDate);
            statisticNoRecordByStatus(cityMap, parameter, startDate);

            startDate = DateTimeUtils.getDaysAfter(startDate, 1);
        }

        updateName();
    }

    @Override
    public void updateSourceName(String oldName, String name) {
        customerDao.updateName(oldName, name);
    }

    @Override
    public void removeFromOcean() {
        try {
            //添加客户删除日志
            Map<String, Object> map = new HashMap<>(5);
            List<CustomerEntity> list = customerMapper.queryOceanCustomer(map);
            customerDao.removeFromOcean();
            if (CollectionUtils.isNotEmpty(list)) {
                for (CustomerEntity c : list) {
                    logUtils.saveCustomerLog(c, 3, 0, "removeFromOcean定时任务");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("removeFromOcean定时任务失败", e);
        }
    }

    private void addUserBlank(List<UserSourceStatisticsEntity> list, Date date) {
        List<UserEntity> userEntities = userService.queryAll();
        customerSourceEntities = getCustomerSources();

        for (UserEntity user : userEntities) {
            for (Integer status : statusList) {
                for (CustomerSourceEntity cs : customerSourceEntities) {
                    boolean flag = false;

                    for (UserSourceStatisticsEntity ps : list) {
                        if ("2".equalsIgnoreCase(ps.getObjectType()) && ps.getProjectId().equals(
                                user.getId()) && ps.getCustomerStatus().equals(status) && ps.getSourceId().equals(
                                cs.getId()) && DateTimeUtils.getDateString(ps.getCreateTime(),
                                DEFAULT_DATE_FORMAT_PATTERN_SHORT).equals(
                                DateTimeUtils.getDateString(date, DEFAULT_DATE_FORMAT_PATTERN_SHORT))) {
                            flag = true;
                            break;
                        }
                    }

                    if (!flag) {
                        Integer deptId = user.getDeptId();
                        DepartmentEntity city = null;
                        if (cityMap.containsKey(deptId)) {
                            city = cityMap.get(deptId);
                        } else {
                            DepartmentEntity departmentEntity = (DepartmentEntity) departmentService.getById(deptId);
                            city = (DepartmentEntity) departmentService.getById(
                                    Integer.valueOf(departmentEntity.getCityID()));
                            cityMap.put(deptId, city);
                        }

                        UserSourceStatisticsEntity pss = new UserSourceStatisticsEntity();
                        pss.setCreateTime(date);
                        pss.setProjectId(user.getId());
                        pss.setProjectName(user.getRealName());
                        pss.setCity(city.getDescripition());
                        pss.setCityName(city.getName());
                        pss.setCustomerNum(0);
                        pss.setCustomerStatus(status);
                        pss.setDayBaseRatio(BigDecimal.ZERO);
                        pss.setObjectType("2");
                        pss.setSourceId(cs.getId());
                        pss.setSourceName(cs.getSourceName());
                        userSourceStatisticsService.save(pss);
                    }
                }
            }
        }
    }

    private void addDeptBlank(List<DeptSourceStatisticsEntity> list, Date date) {
        List<DepartmentEntity> deptEntities = departmentService.queryAll();
        customerSourceEntities = getCustomerSources();

        for (DepartmentEntity dept : deptEntities) {
            for (Integer status : statusList) {
                for (CustomerSourceEntity cs : customerSourceEntities) {
                    boolean flag = false;

                    for (DeptSourceStatisticsEntity ps : list) {
                        if ("1".equalsIgnoreCase(ps.getObjectType()) && ps.getProjectId().equals(
                                dept.getId()) && ps.getCustomerStatus().equals(status) && ps.getSourceId().equals(
                                cs.getId()) && DateTimeUtils.getDateString(ps.getCreateTime(),
                                DEFAULT_DATE_FORMAT_PATTERN_SHORT).equals(
                                DateTimeUtils.getDateString(date, DEFAULT_DATE_FORMAT_PATTERN_SHORT))) {
                            flag = true;
                            break;
                        }
                    }

                    if (!flag) {
                        Integer deptId = dept.getId();
                        DepartmentEntity city = null;
                        if (cityMap.containsKey(deptId)) {
                            city = cityMap.get(deptId);
                        } else {
                            DepartmentEntity departmentEntity = (DepartmentEntity) departmentService.getById(deptId);
                            city = (DepartmentEntity) departmentService.getById(
                                    Integer.valueOf(departmentEntity.getCityID()));
                            cityMap.put(deptId, city);
                        }

                        DeptSourceStatisticsEntity pss = new DeptSourceStatisticsEntity();
                        pss.setCreateTime(date);
                        pss.setProjectId(dept.getId());
                        pss.setProjectName(dept.getName());
                        pss.setCity(city.getDescripition());
                        pss.setCityName(city.getName());
                        pss.setCustomerNum(0);
                        pss.setCustomerStatus(status);
                        pss.setDayBaseRatio(BigDecimal.ZERO);
                        pss.setObjectType("1");
                        pss.setSourceId(cs.getId());
                        pss.setSourceName(cs.getSourceName());
                        deptSourceStatisticsService.save(pss);
                    }
                }
            }
        }
    }

    private void addProjectBlank(List<ProjectSourceStatisticsEntity> list, Date date) {
        List<ProjectEntity> projectEntities = projectService.queryAll();
        customerSourceEntities = getCustomerSources();

        for (ProjectEntity project : projectEntities) {
            for (Integer status : statusList) {
                for (CustomerSourceEntity cs : customerSourceEntities) {
                    boolean flag = false;

                    for (ProjectSourceStatisticsEntity ps : list) {
                        if ("3".equalsIgnoreCase(ps.getObjectType()) && ps.getProjectId().equals(
                                project.getId()) && ps.getCustomerStatus().equals(status) && ps.getSourceId().equals(
                                cs.getId()) && DateTimeUtils.getDateString(ps.getCreateTime(),
                                DEFAULT_DATE_FORMAT_PATTERN_SHORT).equals(
                                DateTimeUtils.getDateString(date, DEFAULT_DATE_FORMAT_PATTERN_SHORT))) {
                            flag = true;
                            break;
                        }
                    }

                    if (!flag) {

                        ProjectSourceStatisticsEntity pss = new ProjectSourceStatisticsEntity();
                        pss.setCreateTime(date);
                        pss.setProjectId(project.getId());
                        pss.setProjectName(project.getProjectName());
                        pss.setCity(project.getCity());
                        pss.setCityName(project.getCityName());
                        pss.setCustomerNum(0);
                        pss.setCustomerStatus(status);
                        pss.setDayBaseRatio(0d);
                        pss.setObjectType("3");
                        pss.setSourceId(cs.getId());
                        pss.setSourceName(cs.getSourceName());
                        projectSourceStatisticsService.save(pss);
                    }
                }
            }
        }
    }

    private List<CustomerSourceEntity> getCustomerSources() {
        if (customerSourceEntities.isEmpty()) {
            customerSourceEntities = customerSourceService.queryAll();
        }
        return customerSourceEntities;
    }

    /**
     * 按状态统计未约看客户信息入统计表
     *
     * @param cityMap
     * @param parameter
     * @param startDate
     * @return
     */
    private List<StatusSourceStatisticsEntity> statisticNoRecordByStatus(
            Map<Integer, DepartmentEntity> cityMap, Map<String, String> parameter, Date startDate
    ) {
        List<StatusSourceStatisticsEntity> pssList = new ArrayList<>();

        List<Map<String, Object>> statisticByUser = customerDao.statisticNoRecordByStatus(parameter);
        for (Map<String, Object> statistic : statisticByUser) {
            //cache city 部门对应的城市

            StatusSourceStatisticsEntity pss = new StatusSourceStatisticsEntity();
            pss.setCreateTime(startDate);
            pss.setProjectId(0);
            pss.setProjectName("未约看");

            pss.setCity(String.valueOf(statistic.get("citycode")));
            pss.setCityName(String.valueOf(statistic.get("cityName")));
            pss.setCustomerNum(new BigDecimal(String.valueOf(statistic.get("num"))).intValue());
            pss.setCustomerStatus(0);

            pss.setDayBaseRatio(BigDecimal.ZERO);
            pss.setObjectType("4");
            pss.setSourceId((Integer) statistic.get("act_source_id"));

            String actSource = statistic.get("act_source") == null ? "" : String.valueOf(statistic.get("act_source"));
            actSource = Strings.isNullOrEmpty(actSource) ? "" : StringUtils.StringFilter(actSource);
            pss.setSourceName(actSource);

            statusSourceStatisticsService.save(pss);
            pssList.add(pss);
        }

        return pssList;
    }

    /**
     * 按用户统计未约看客户信息入统计表
     *
     * @param cityMap
     * @param parameter
     * @param startDate
     * @return
     */
    private List<UserSourceStatisticsEntity> statisticNoRecordByUser(
            Map<Integer, DepartmentEntity> cityMap, Map<String, String> parameter, Date startDate
    ) {
        List<UserSourceStatisticsEntity> pssList = new ArrayList<>();

        List<Map<String, Object>> statisticByUser = customerDao.statisticNoRecordByUser(parameter);
        for (Map<String, Object> statistic : statisticByUser) {

            UserSourceStatisticsEntity pss = new UserSourceStatisticsEntity();
            pss.setCreateTime(startDate);
            pss.setProjectId((Integer) statistic.get("manager_id"));
            pss.setProjectName(String.valueOf(statistic.get("manager_name")));

            pss.setCity(String.valueOf(statistic.get("cityCode")));
            pss.setCityName(String.valueOf(statistic.get("cityName")));
            pss.setCustomerNum(new BigDecimal(String.valueOf(statistic.get("num"))).intValue());
            pss.setCustomerStatus(0);

            pss.setDayBaseRatio(BigDecimal.ZERO);
            pss.setObjectType("2");
            pss.setSourceId((Integer) statistic.get("act_source_id"));

            String actSource = statistic.get("act_source") == null ? "" : String.valueOf(statistic.get("act_source"));
            actSource = Strings.isNullOrEmpty(actSource) ? "" : StringUtils.StringFilter(actSource);
            pss.setSourceName(actSource);

            userSourceStatisticsService.save(pss);
            pssList.add(pss);
        }

        return pssList;
    }

    /**
     * 按用户统计非未约看客户信息入统计表
     *
     * @param cityMap
     * @param parameter
     * @param startDate
     * @return
     */
    private List<UserSourceStatisticsEntity> statisticByUser(
            Map<Integer, DepartmentEntity> cityMap, Map<String, String> parameter, Date startDate
    ) {
        List<UserSourceStatisticsEntity> pssList = new ArrayList<>();

        List<Map<String, Object>> statisticByUser = customerDao.statisticByUser(parameter);
        for (Map<String, Object> statistic : statisticByUser) {
            //cache city 部门对应的城市
            Integer deptId = (Integer) statistic.get("dept_id");
            DepartmentEntity city = null;
            if (cityMap.containsKey(deptId)) {
                city = cityMap.get(deptId);
            } else {
                DepartmentEntity departmentEntity = (DepartmentEntity) departmentService.getById(
                        (Integer) statistic.get("dept_id"));
                city = (DepartmentEntity) departmentService.getById(Integer.valueOf(departmentEntity.getCityID()));
                cityMap.put(deptId, city);
            }

            UserSourceStatisticsEntity pss = new UserSourceStatisticsEntity();
            pss.setCreateTime(startDate);
            pss.setProjectId((Integer) statistic.get("manager_id"));
            pss.setProjectName(String.valueOf(statistic.get("manager_name")));

            pss.setCity(city.getDescripition());
            pss.setCityName(city.getName());
            pss.setCustomerNum(new BigDecimal(String.valueOf(statistic.get("num"))).intValue());
            pss.setCustomerStatus((Integer) statistic.get("status_id"));

            pss.setDayBaseRatio(BigDecimal.ZERO);
            pss.setObjectType("2");
            pss.setSourceId((Integer) statistic.get("source_id"));
            String actSource = statistic.get("act_source") == null ? "" : String.valueOf(statistic.get("act_source"));
            actSource = Strings.isNullOrEmpty(actSource) ? "" : StringUtils.StringFilter(actSource);
            pss.setSourceName(actSource);

            userSourceStatisticsService.save(pss);
            pssList.add(pss);
        }

        return pssList;
    }

    /**
     * 根据状态统计信息
     *
     * @param cityMap
     * @param parameter
     * @param startDate
     * @return
     */
    private List<StatusSourceStatisticsEntity> statisticByStatus(
            Map<Integer, DepartmentEntity> cityMap, Map<String, String> parameter, Date startDate
    ) {
        List<StatusSourceStatisticsEntity> pssList = new ArrayList<>();

        List<Map<String, Object>> statisticByUser = customerDao.statisticByStatus(parameter);
        for (Map<String, Object> statistic : statisticByUser) {

            StatusSourceStatisticsEntity pss = new StatusSourceStatisticsEntity();
            pss.setCreateTime(startDate);
            pss.setProjectId((Integer) statistic.get("status_id"));
            pss.setProjectName(String.valueOf(statistic.get("status_name")));

            pss.setCity(String.valueOf(statistic.get("cityCode")));
            pss.setCityName(String.valueOf(statistic.get("cityname")));
            pss.setCustomerNum(new BigDecimal(String.valueOf(statistic.get("num"))).intValue());
            pss.setCustomerStatus((Integer) statistic.get("status_id"));

            pss.setDayBaseRatio(BigDecimal.ZERO);
            pss.setObjectType("4");
            pss.setSourceId((Integer) statistic.get("source_id"));
            String actSource = statistic.get("act_source") == null ? "" : String.valueOf(statistic.get("act_source"));
            actSource = Strings.isNullOrEmpty(actSource) ? "" : StringUtils.StringFilter(actSource);
            pss.setSourceName(actSource);

            statusSourceStatisticsService.save(pss);
            pssList.add(pss);
        }

        return pssList;
    }

    /**
     * 按部门统计非未约看客户信息入统计表
     *
     * @param cityMap
     * @param parameter
     * @param startDate
     * @return
     */
    private List<DeptSourceStatisticsEntity> statisticByDept(
            Map<Integer, DepartmentEntity> cityMap, Map<String, String> parameter, Date startDate
    ) {
        List<DeptSourceStatisticsEntity> pssList = new ArrayList<>();
        List<Map<String, Object>> statisticByDept = customerDao.statisticByDept(parameter);

        saveStatisticDeptInfo(startDate, pssList, statisticByDept);

        return pssList;
    }

    private void saveStatisticDeptInfo(
            Date startDate, List<DeptSourceStatisticsEntity> pssList, List<Map<String, Object>> statisticByDept
    ) {
        if (statisticByDept != null && !statisticByDept.isEmpty()) {
            List<StatisticCheckPo> poList = new ArrayList<>();

            for (Map<String, Object> statistic : statisticByDept) {

                Long sourceId = Long.valueOf(
                        String.valueOf(statistic.get("source_id") == null ? "0" : statistic.get("source_id")));
                Long statusId = Long.valueOf(
                        String.valueOf(statistic.get("status_id") == null ? "0" : statistic.get("status_id")));
                Long deptId = Long.valueOf(
                        String.valueOf(statistic.get("dept_id") == null ? "0" : statistic.get("dept_id")));
                Long num = Long.valueOf(String.valueOf(statistic.get("num") == null ? "0" : statistic.get("num")));
                String deptName = (String) statistic.get("dept_name");
                String cityCode = String.valueOf(statistic.get("cityCode"));
                String cityName = String.valueOf(statistic.get("cityName"));
                String actSource = statistic.get("act_source") == null ? "" : String.valueOf(
                        statistic.get("act_source"));
                actSource = Strings.isNullOrEmpty(actSource) ? "" : StringUtils.StringFilter(actSource);

                StatisticCheckPo po = new StatisticCheckPo(sourceId, num, statusId, deptId, deptName, cityCode,
                        cityName, actSource);
                if (!poList.contains(po)) {
                    poList.add(po);
                }

                String urlPath = String.valueOf(statistic.get("urlpath"));
                if (!Strings.isNullOrEmpty(urlPath)) {
                    String[] parents = urlPath.split("/");
                    for (String pid : parents) {
                        if (!Strings.isNullOrEmpty(pid)) {
                            StatisticCheckPo poChild = new StatisticCheckPo(sourceId, 0L, statusId, Long.parseLong(pid),
                                    "", cityCode, cityName, actSource);
                            if (!poList.contains(poChild)) {
                                poList.add(poChild);
                            }

                        }
                    }
                }

            }

            for (StatisticCheckPo po : poList) {

                DeptSourceStatisticsEntity pss = new DeptSourceStatisticsEntity();
                pss.setCreateTime(startDate);
                pss.setProjectId(po.projectId.intValue());
                pss.setProjectName(po.projectName);
                pss.setCity(po.city);
                pss.setCityName(po.cityName);
                pss.setCustomerNum(po.num.intValue());
                pss.setCustomerStatus(po.statusId.intValue());
                pss.setDayBaseRatio(BigDecimal.ZERO);
                pss.setObjectType("1");
                pss.setSourceId(po.sourceId.intValue());
                pss.setSourceName(po.actSource);
                deptSourceStatisticsService.save(pss);
                pssList.add(pss);

            }
        }
    }

    /**
     * 按部门统计未约看客户信息入统计表
     *
     * @param cityMap
     * @param parameter
     * @param startDate
     * @return
     */
    private List<DeptSourceStatisticsEntity> statisticNoRecordByDept(
            Map<Integer, DepartmentEntity> cityMap, Map<String, String> parameter, Date startDate
    ) {
        List<DeptSourceStatisticsEntity> pssList = new ArrayList<>();
        List<Map<String, Object>> statisticByDept = customerDao.statisticNoRecordByDept(parameter);
        saveStatisticDeptInfo(startDate, pssList, statisticByDept);
        return pssList;
    }

    private List<ProjectSourceStatisticsEntity> statisticByProject(
            Map<Integer, DepartmentEntity> cityMap, Map<String, String> parameter, Date startDate
    ) {
        List<ProjectSourceStatisticsEntity> pssList = new ArrayList<>();
        List<Map<String, Object>> statisticByProject = customerDao.statisticByProject(parameter);
        for (Map<String, Object> statistic : statisticByProject) {

            ProjectSourceStatisticsEntity pss = new ProjectSourceStatisticsEntity();
            pss.setCreateTime(startDate);
            pss.setProjectId((Integer) statistic.get("project_id"));
            pss.setProjectName(String.valueOf(statistic.get("projectName")));

            pss.setCity(String.valueOf(statistic.get("cityCode")));
            pss.setCityName(String.valueOf(statistic.get("cityName")));
            pss.setCustomerNum(new BigDecimal(String.valueOf(statistic.get("num"))).intValue());
            pss.setCustomerStatus((Integer) statistic.get("status_id"));

            pss.setDayBaseRatio(0d);
            pss.setObjectType("3");
            pss.setSourceId((Integer) statistic.get("source_id"));
            String actSource = statistic.get("act_source") == null ? "" : String.valueOf(statistic.get("act_source"));
            actSource = Strings.isNullOrEmpty(actSource) ? "" : StringUtils.StringFilter(actSource);
            pss.setSourceName(actSource);
            projectSourceStatisticsService.save(pss);
            pssList.add(pss);
        }
        return pssList;
    }

    //今日新增客户
    @Override
    public List<Integer> getNewAddCustomerIds(String managerId) {
        List<Integer> userIds = userService.getUserIdOnPath(Integer.valueOf(managerId));
        return customerDao.getNewAddCustomerIds(Joiner.on(",").join(userIds));
    }

    //3天内回访的客户
    @Override
    public List<Integer> getCallInThreeDayIds(String managerId) {
        List<Integer> userIds = userService.getUserIdOnPath(Integer.valueOf(managerId));
        return customerDao.getCallInThreeDayIds(Joiner.on(",").join(userIds));
    }

    //星标客户
    @Override
    public List<Integer> getStarCustomerIds(String managerId) {
        List<Integer> userIds = userService.getUserIdOnPath(Integer.valueOf(managerId));
        return customerDao.getStarCustomerIds(Joiner.on(",").join(userIds));
    }

    //7日新增客户
    @Override
    public List<Integer> getSevenDayNewCustomerIds(String managerId) {
        List<Integer> userIds = userService.getUserIdOnPath(Integer.valueOf(managerId));
        return customerDao.getSevenDayNewCustomerIds(Joiner.on(",").join(userIds));
    }

    @Override
    public void sendMessageToWechat(final MessageTypeEnum type, final String toUser, final Map<String, String> params) {

        final String toUserTest = toUser;
        final String customerId = params.get("customerId");
        final String customerName = params.get("customerName");
        final String customerProjectId = params.get("customerProjectId");

        ExecutorService executor = Executors.newCachedThreadPool();

        logger.info("sendMessageToWechat [{}]", type);

        switch (type) {
            case NEWHOTLINE:
                final String newHotLineUrl = MemoryPropertyPlaceholderConfigurer.getContextProperty(
                        "WECHAT.SERVICE.URL") + "/customer/hotline?timeFilter=1";
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        wechatService.sendCardTextMessage(toUserTest, NEWHOTLINE.getDes(), NEWHOTLINE.getMessage(),
                                newHotLineUrl, "查看详情");
                    }
                });
                break;
            case NEWCUSTOMER:
                final String mes = NEWCUSTOMER.getMessage().replaceAll("@replace1@", customerId);
                final String newCustomerUrl = NEWCUSTOMER.getUrl().replaceAll("@replace1@", customerId);
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        wechatService.sendCardTextMessage(toUserTest, NEWCUSTOMER.getDes(), mes, newCustomerUrl,
                                "查看详情");
                    }
                });
                break;
            case UPDATECUSTOMERSTATUS:
                final String toStatus = params.get("toStatus");
                final String mes2 = UPDATECUSTOMERSTATUS.getMessage().replaceAll("@replace1@", customerName).replaceAll(
                        "@replace2@", toStatus);
                final String updateCustomerStatusTitle = UPDATECUSTOMERSTATUS.getDes().replaceAll("@replace2@",
                        toStatus);
                final String updateCustomerStatusUrl = UPDATECUSTOMERSTATUS.getUrl().replaceAll("@replace1@",
                        customerProjectId);
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        wechatService.sendCardTextMessage(toUserTest, updateCustomerStatusTitle, mes2,
                                updateCustomerStatusUrl, "查看详情");
                    }
                });
                break;
            case NEWRECORDCUSTOMER:
                String projectName = params.get("projectName");
                String customerPhone = params.get("customerPhone");
                String managerName = params.get("managerName");
                final String newRecordCustomerUrl = NEWRECORDCUSTOMER.getUrl().replaceAll("@replace1@",
                        customerProjectId);
                final String mes3 = NEWRECORDCUSTOMER.getMessage().replaceAll("@replace1@", projectName).replaceAll(
                        "@replace2@", customerName).replaceAll("@replace3@", customerPhone).replaceAll("@replace4@",
                        managerName).replaceAll(
                        "@replace5@", customerProjectId);
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        wechatService.sendCardTextMessage(toUserTest, NEWRECORDCUSTOMER.getDes(), mes3,
                                newRecordCustomerUrl, "查看详情");
                    }
                });
                break;
            case NEWNOTICE:
                final String noticeId = params.get("noticeId");
                final String newNoticeUrl = NEWNOTICE.getUrl().replaceAll("@replace1@", noticeId);
                NoticeEntity notice = (NoticeEntity) noticeService.getById(Integer.valueOf(noticeId));

                String regEx_html = "<[^>]+>"; //定义HTML标签的正则表达式
                Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
                Matcher m_html = p_html.matcher(notice.getContent());
                String content = m_html.replaceAll(""); //过滤html标签

                final String mes4 = NEWNOTICE.getMessage().replaceAll("@replace1@", content);

                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        wechatService.sendCardTextMessage(toUserTest, NEWNOTICE.getDes(), mes4, newNoticeUrl, "查看详情");
                    }
                });
                break;
            case RUSHCUSTOMER:
                final String rushCustomerCount = params.get("rushCustomerCount");
                final String mes6 = RUSHCUSTOMER.getMessage().replaceAll("@replace1@", rushCustomerCount);
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        wechatService.sendCardTextMessage(toUserTest, RUSHCUSTOMER.getDes(), mes6,
                                RUSHCUSTOMER.getUrl(), "查看详情");
                    }
                });
                break;
            default:
                break;
        }

    }

    @Override
    public void sendMsgToWechat(String msg, int userId, Map<String, String> params) {

    }

    @Override
    public List<CustomerEntity> getCustomerManagementList(QueryParams<CustomerEntity> queryParams) {
        return customerDao.getCustomerManagementList(queryParams);
    }

    @Override
    public List<CustomerEntity> getPlatformCustomerList(QueryParams<CustomerEntity> queryParams) {
        return customerDao.getPlatformCustomerList(queryParams);
    }

    @Override
    public List<CustomerEntity> getCustomerManagementList4Label(QueryParams<CustomerEntity> queryParams) {
        return customerDao.getCustomerManagementList4Label(queryParams);
    }

    @Override
    public List<CustomerEntity> getCustomerListFromOld(QueryParams<CustomerEntity> queryParams) {
        return customerDao.getCustomerListFromOld(queryParams);
    }

    @Override
    public List<DictionaryEntity> getNoApproximateConfig(Map<String, Object> map) {
        return dictionaryMapper.getNoApproximateConfig(map);
    }

    @Override
    public void backToSeaByStatusOverDaysTask() {
        logger.error("****************到访未认筹和约看未到访******************" +
                DateTimeUtils.getDateString(new Date(), DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_FULL));

        List<DictionaryEntity> orderDictionaries = dictionaryService.getListByKey("customer.remove.days.order");
        for (DictionaryEntity dictionary : orderDictionaries) {
            if ("0".equals(dictionary.getDicValue())) {
                continue;
            }
            //根据查询新表的客户id，手机号和安家顾问id
            List<Map<String, Object>> noVisitResult = this.getNoVisitIdsByDays(
                    Integer.valueOf(dictionary.getDicValue()), dictionary.getCity());
            Map<String, Object> idMap = new HashMap<>(10);
            List<Integer> idList = new ArrayList<>();
            for (Map map : noVisitResult) {
                Integer customerId = (Integer) map.get("id");
                String phone = (String) map.get("phone");
                Integer managerId = (Integer) map.get("managerId");
                idList.add(customerId);
                try {
                    newRemoveCustomer(managerId, phone, -1, true);
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
            }
            idMap.put("ids", idList);
            if (idList.size() > 0) {
                customermergemapper.deleteCustomerMergeById(idMap);
            }
        }

        List<DictionaryEntity> visitDictionaries = dictionaryService.getListByKey("customer.remove.days.visit");
        for (DictionaryEntity dictionary : visitDictionaries) {
            if ("0".equals(dictionary.getDicValue())) {
                continue;
            }
            List<Map<String, Object>> noPledgedResult = this.getNoPledgedIdsByDays(
                    Integer.valueOf(dictionary.getDicValue()), dictionary.getCity());
            Map<String, Object> idMap = new HashMap<>(10);
            List<Integer> idList = new ArrayList<>();
            for (Map map : noPledgedResult) {
                Integer customerId = (Integer) map.get("id");
                String phone = (String) map.get("phone");
                Integer managerId = (Integer) map.get("manager_id");
                idList.add(customerId);
                try {
                    newRemoveCustomer(managerId, phone, -1, true);
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }

            }
            idMap.put("ids", idList);
            if (idList.size() > 0) {
                customermergemapper.deleteCustomerMergeById(idMap);
            }
        }

        //48小时无回访的待回访记录回公海
        List<DictionaryEntity> noCallDictionaries = dictionaryService.getListByKey("customer.remove.days.nocall");
        for (DictionaryEntity dictionary : noCallDictionaries) {
            if ("0".equals(dictionary.getDicValue())) {
                continue;
            }

            List<Map<String, Object>> noPledgedResult = getNoCallByHours(Integer.valueOf(dictionary.getDicValue()),
                    dictionary.getCity());
            if (noPledgedResult != null) {
                for (Map map : noPledgedResult) {
                    Integer customerId = (Integer) map.get("id");
                    String phone = (String) map.get("phone");
                    String managerId = (String) map.get("managerId");
                    try {
                        removeCustomer(customerId, -1, true);
                    } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                    }
                }
            }
        }

    }

    @Override
    public List<Map<String, Object>> getNoCallByHours(Integer hours, String city) {
        Map<String, Object> parameter = new HashMap<>(10);
        parameter.put("hours", hours);
        parameter.put("city", city);
        parameter.put("status", Constant.CustomerStatusEnum.VISITED.getStatus());
        return customerDao.getNoCallByHours(parameter);
    }


    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    @Override
    public void newRemoveCustomer(Integer managerId, String phone, Integer userId, boolean isRecycled) throws Exception {
//        CustomerEntity customerEntity = getById(custmerId);
        Map<String, Object> paramMap = new HashMap<>(10);
        paramMap.put("managerId", managerId);
        paramMap.put("phone", phone);
        List<CustomerEntity> customerList = customermergemapper.getCustomerList(paramMap);
        if (CollectionUtils.isNotEmpty(customerList)) {
            for (CustomerEntity ce : customerList) {
                hgsCacheUtil.delUserSummary(ce.getManagerId());
                //save last manager name
                if (!Strings.isNullOrEmpty(ce.getManagerName())) {
                    ce.setLastManager(ce.getManagerName());
                }
                ce.setManagerName(null);
                ce.setManagerId(null);
                ce.setOceanDate(new Date());
                // 定时任务清理进公海的客户,isRecycled字段更新为1
                if (isRecycled) {
                    ce.setIsRecycled(1);
                }
                update((T) ce);
                //添加客户移入公海日志
                UserEntity userEntity = userMapper.getById(userId);
                String userName;
                if (userEntity != null) {
                    userName = userEntity.getRealName();
                } else {
                    userName = "定时任务";
                }

                if (userId != null) {
                    //remove wechat star record
                    customerUserService.removeStar(ce.getId(), userId == -1 ? 1 : userId);
                }

                if (HGSConstant.CustomerSourceType.MARKET.getType().intValue() == ce.getCustomerSourceType().intValue()) {
                    marketCustomerService.removeCustomer(ce, userId);
                    //update marketcustomerentity
                } else if (HGSConstant.CustomerSourceType.ROB.getType().intValue() == ce.getCustomerSourceType().intValue()) {
                    //抢客状态还原
                    RushCustomerEntity rushCustomerEntity = (RushCustomerEntity) rushCustomerService.getById(
                            ce.getCustomerRelId());
                    rushCustomerEntity.setRushStatus(1);
                    rushCustomerService.update(rushCustomerEntity);
                }
                ce.setManagerId(managerId);
                logUtils.saveCustomerLog(ce, 6, userId, userName);
                logger.info("user [{}] remove customer [{}]", userId == null ? "system" : userId, ce.getId());
            }

        }

    }

    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    @Override
    public void removeCustomer(Integer custmerId, Integer userId, boolean isRecycled) throws Exception {
        CustomerEntity customerEntity = getById(custmerId);
        System.out.println("****************即将回公海客户:***************" + customerEntity);
        if (customerEntity != null) {
            hgsCacheUtil.delUserSummary(customerEntity.getManagerId());
            Integer managerId = customerEntity.getManagerId();
            //save last manager name
            if (!Strings.isNullOrEmpty(customerEntity.getManagerName())) {
                customerEntity.setLastManager(customerEntity.getManagerName());
            }
            customerEntity.setManagerName(null);
            customerEntity.setManagerId(null);
            customerEntity.setOceanDate(new Date());
            // 定时任务清理进公海的客户,isRecycled字段更新为1
            if (isRecycled) {
                customerEntity.setIsRecycled(1);
            }
            if (HGSConstant.CustomerSourceType.MARKET.getType().intValue() != customerEntity.getCustomerSourceType().intValue()) {
                update((T) customerEntity);
            }


            //添加客户移入公海日志
            UserEntity userEntity = userMapper.getById(userId);
            String userName;
            if (userEntity != null) {
                userName = userEntity.getRealName();
            } else {
                userName = "定时任务";
            }
            if (userId != null) {
                //remove wechat star record
                customerUserService.removeStar(custmerId, userId == -1 ? 1 : userId);
            }
            //云迹客户进入公海逻辑,更新manageId,mangerName
            if (customerEntity.getCustomerSourceType() == 7) {
                updateCloud(custmerId);
            }

            if (HGSConstant.CustomerSourceType.MARKET.getType().intValue() == customerEntity.getCustomerSourceType().intValue()) {

                marketCustomerService.removeCustomer(customerEntity, userId);
            } else if (HGSConstant.CustomerSourceType.ROB.getType().intValue() == customerEntity.getCustomerSourceType().intValue()) {
                //抢客状态还原
                RushCustomerEntity rushCustomerEntity = (RushCustomerEntity) rushCustomerService.getById(
                        customerEntity.getCustomerRelId());
                rushCustomerEntity.setRushStatus(1);
                rushCustomerService.update(rushCustomerEntity);
            }
            customerEntity.setManagerId(managerId);
            logUtils.saveCustomerLog(customerEntity, 6, userId, userName);

            logger.info("user [{}] remove customer [{}]", userId == null ? "system" : userId, customerEntity.getId());
        }

    }

    /**
     * 云迹客户移入公海操作
     *
     * @param customerId 客户id
     */
    private void updateCloud(int customerId) {
        Map<String, Object> queryMap = new HashMap<>(5);
        queryMap.put("customerId", customerId);
        List<CloudCustomerEntity> list = cloudCustomerMapper.queryByConditions(queryMap);
        if (CollectionUtils.isNotEmpty(list)) {
            CloudCustomerEntity cloudCustomer = list.get(0);
            cloudCustomer.setManagerId(0);
            cloudCustomer.setManagerName("");
            cloudCustomer.setBindTime(null);
            cloudCustomer.setUpdateTime(new Date());
            cloudCustomerMapper.update(cloudCustomer);
        }
    }

    /**
     * 批量转移客户到公海
     *
     * @param customerIds
     * @param userId
     */
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    @Override
    public void batchRemoveCustomer(String customerIds, Integer userId, String userName) throws Exception {

        String[] arrCustomerId = org.apache.commons.lang3.StringUtils.split(customerIds, ",");
        for (String strCustomerId : arrCustomerId) {
            Integer customerId = Integer.valueOf(strCustomerId);
            CustomerEntity mergeCustomerEntity = customermergemapper.queryById(customerId);
            Map<String, Object> map = new HashMap<>(10);
            map.put("managerId", mergeCustomerEntity.getManagerId());
            map.put("phone", mergeCustomerEntity.getPhone());
            List<CustomerEntity> oldCustomerList = customerMapper.getDetailCustomers(map);
            //将新表合并后的客户数据删除
            Map<String, Object> idMap = new HashMap<>(10);
            List<Integer> idList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(oldCustomerList)) {
                for (CustomerEntity ce : oldCustomerList) {
                    idList.add(ce.getId());
                    //云迹客户进入公海逻辑,更新manageId,mangerName
                    if (ce.getCustomerSourceType() == 7) {
                        updateCloud(ce.getId());
                    }
                }
            }
            idMap.put("ids", idList);
            if (CollectionUtils.isNotEmpty(idList)) {
                customermergemapper.deleteCustomerMergeById(idMap);
            }
            if (CollectionUtils.isNotEmpty(oldCustomerList)) {
                //更新老客户表合并前的数据
                for (CustomerEntity customerEntity : oldCustomerList) {
                    if (customerEntity != null) {
                        int managerId = customerEntity.getManagerId();
                        hgsCacheUtil.delUserSummary(customerEntity.getManagerId());
                        //save last manager name
                        if (!Strings.isNullOrEmpty(customerEntity.getManagerName())) {
                            customerEntity.setLastManager(customerEntity.getManagerName());
                        }
                        Date date = new Date();
                        customerEntity.setOceanDate(date);
                        customerEntity.setUpdater(String.valueOf(userId));
                        customerEntity.setUpdateTime(date);
                        customerEntity.setLastManager(customerEntity.getManagerName());
                        customerEntity.setManagerId(null);
                        customerEntity.setManagerName(null);
                        if (HGSConstant.CustomerSourceType.MARKET.getType().intValue() != customerEntity.getCustomerSourceType().intValue()) {
                            update((T) customerEntity);
                        }

                        //添加客户移入公海日志
                        if (userId == -1) {
                            userId = 1;
                        }

                        if (userId != null) {
                            //remove wechat star record
                            customerUserService.removeStar(customerId, userId);
                        }

                        if (HGSConstant.CustomerSourceType.MARKET.getType().intValue() == customerEntity.getCustomerSourceType().intValue()) {
                            marketCustomerService.removeCustomer(customerEntity, userId);
                            //update marketcustomerentity
                        } else if (HGSConstant.CustomerSourceType.ROB.getType().intValue() == customerEntity.getCustomerSourceType().intValue()) {
                            //抢客状态还原
                            RushCustomerEntity rushCustomerEntity = (RushCustomerEntity) rushCustomerService.getById(
                                    customerEntity.getCustomerRelId());
                            rushCustomerEntity.setRushStatus(1);
                            rushCustomerService.update(rushCustomerEntity);
                        }

                        if (userId != null) {
                            //remove wechat star record
                            customerUserService.removeStar(customerId, userId);
                        }
                        customerEntity.setManagerId(managerId);
                        logUtils.saveCustomerLog(customerEntity, 6, userId, userName);
                        logger.info("user [{}] remove customer [{}]", userId == null ? "system" : userId, customerEntity.getId());
                    }
                }

            }
        }
    }

    @Override
    public List<CustomerEntity> getWechatCustomers(QueryParams<CustomerEntity> queryParams) {
        return customerDao.getWechatCustomers(queryParams);
    }

    //待回访中总回访次数
    @Override
    public Integer getTotalCall(QueryParams<T> queryParams) {
        return customerDao.getTotalCall(queryParams);
    }

    @Override
    public Integer getTotalCallOptimize(QueryParams<T> queryParams) {
        return customerDao.getTotalCallOptimize(queryParams);
    }

    //待回访中总放弃次数
    @Override
    public Integer getTotalAbandon(QueryParams<T> queryParams) {
        return customerDao.getTotalAbandon(queryParams);
    }

    @Override
    public List<Map<String, Object>> getMarketInfo(QueryParams<T> queryParams) {
        return customerDao.getMarketInfo(queryParams);
    }

    @Override
    public List<CrmVisitAndSignCustomer> crmVisitAndSignCustomer(Map<String, Object> params) {
        return customerDao.crmVisitAndSignCustomer(params);
    }

    private class StatisticCheckPo {
        private Long sourceId;
        private Long statusId;
        private Long projectId;
        private Long num;
        private String projectName;
        private String city;
        private String cityName;
        private String actSource;

        public StatisticCheckPo(
                Long sourceId, Long num, Long statusId, Long projectId, String projectName, String city, String cityName,
                String actSource
        ) {
            this.sourceId = sourceId;
            this.statusId = statusId;
            this.projectId = projectId;
            this.city = city;
            this.projectName = projectName;
            this.cityName = cityName;
            this.actSource = actSource;
            this.num = num;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }

            StatisticCheckPo that = (StatisticCheckPo) o;

            if (sourceId != null ? !sourceId.equals(that.sourceId) : that.sourceId != null) {
                return false;
            }
            if (statusId != null ? !statusId.equals(that.statusId) : that.statusId != null) {
                return false;
            }
            if (projectId != null ? !projectId.equals(that.projectId) : that.projectId != null) {
                return false;
            }
            if (city != null ? !city.equals(that.city) : that.city != null) {
                return false;
            }
            if (cityName != null ? !cityName.equals(that.cityName) : that.cityName != null) {
                return false;
            }
            if (actSource != null ? !actSource.equals(that.actSource) : that.actSource != null) {
                return false;
            }

            return true;
        }

        @Override
        public int hashCode() {
            int result = sourceId != null ? sourceId.hashCode() : 0;
            result = 31 * result + (statusId != null ? statusId.hashCode() : 0);
            result = 31 * result + (projectId != null ? projectId.hashCode() : 0);
            result = 31 * result + (city != null ? city.hashCode() : 0);
            result = 31 * result + (cityName != null ? cityName.hashCode() : 0);
            result = 31 * result + (actSource != null ? actSource.hashCode() : 0);
            return result;
        }
    }

}
