/**
 * Description: 客户信息WS接口
 * 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.interfaces.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import com.house365.beans.common.HGSConstant;
import com.house365.beans.entity.*;
import com.house365.beans.system.Page;
import com.house365.beans.system.QueryParams;
import com.house365.commons.system.HttpClientUtil;
import com.house365.commons.system.SmsUtils;
import com.house365.rest.context.Parameter;
import com.house365.rest.exception.ServiceException;
import com.house365.rest.exception.ServiceRunException;
import com.house365.rest.parameter.House365RestObject;
import com.house365.rest.parameter.House365RestResponse;
import com.house365.web.util.DateTimeUtils;
import com.house365.web.util.MemoryPropertyPlaceholderConfigurer;
import com.house365.ws.beans.request.CustomerListRequest;
import com.house365.ws.beans.request.CustomerRequest;
import com.house365.ws.beans.request.MapListRequest;
import com.house365.ws.beans.response.CustomerListResponse;
import com.house365.ws.beans.response.CustomerResponse;
import com.house365.ws.beans.response.MapListResponse;
import com.house365.ws.beans.util.HResult;
import com.house365.ws.cached.RedisUtilsInterface;
import com.house365.ws.dao.mapper.*;
import com.house365.ws.interfaces.server.ICustomer;
import com.house365.ws.service.interfaces.*;
import com.house365.ws.system.ReturnAppResult;
import com.house365.ws.system.ReturnResult;
import com.house365.ws.util.Constant;
import com.house365.ws.util.MergeCustomerUtil;
import com.house365.ws.util.OperateLogUtils;
import net.sf.json.JSONObject;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.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 java.net.URLEncoder;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

import static com.house365.beans.common.MessageTypeEnum.NEWCUSTOMER;
import static com.house365.beans.common.MessageTypeEnum.NEWRECORDCUSTOMER;


/**
 * 客户信息WS接口<br>
 *
 * @author 江苏三六五网络股份有限公司
 * @version 1.0, 2016-09-15
 * @see
 * @since 1.0
 */
@Service("customer")
public class CustomerImpl implements ICustomer {
    /**
     * 日志记录器
     */
    private static final Logger LOGGER = LoggerFactory.getLogger( CustomerImpl.class );

    /**
     * 客户信息服务对象
     */
    @Autowired
    private ICustomerService<CustomerEntity> customerService;
    @Autowired
    private IUserService userService;
    @Autowired
    private IProjectService projectService;
    @Autowired
    private ICustomerProjectService customerProjectService;
    @Autowired
    private ICustomerStatusLogService customerStatusLogService;
    @Autowired
    private IDepartmentService departmentService;
    @Autowired
    private IHgsCacheUtil hgsCacheUtil;
    @Autowired
    private IMarketCustomerService marketCustomerService;
    @Autowired
    private ICustomerUserService customerUserService;
    @Autowired
    private ICustomerSourceService customerSourceService;
    @Autowired
    private IMarketingActivityService marketingActivityService;
    @Autowired
    private RedisUtilsInterface redisUtils;

    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
    private CustomerStatusLogMapper customerStatusLogMapper;
    @Autowired
    private CustomerProjectMapper customerProjectMapper;
    @Autowired
    private LabelMapper labelmapper;

    @Autowired
    private CustomerRemindMapper remindMapper;
    @Autowired
    private CustomerMergeMapper customermergemapper;
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private OperateLogUtils logUtils;
    @Autowired
    private CustomerCallbackMapper callbackMapper;
    @Autowired
    private CustomerLogMapper customerLogMapper;
    @Autowired
    private MergeCustomerUtil mergeCustomerUtil;
    @Autowired
    private CloudActivityMapper activityMapper;
    @Autowired
    private CloudCustomerMapper cloudCustomerMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private DepartMapper departMapper;


    @Value("${crm.sync.url}")
    private String crmSyncUrl;

    public static final String MD5(String s) {
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
        try {
            byte[] strTemp = s.getBytes();
            MessageDigest mdTemp = MessageDigest.getInstance( "MD5" );
            mdTemp.update( strTemp );
            byte[] md = mdTemp.digest();
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String( str );
        } catch (Exception e) {
            return null;
        }
    }

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

    @Override
    public House365RestResponse checkCustomerPhone(Integer userId, String customerPhone, String sourceType, Integer platMangerId) {
        House365RestResponse<CustomerEntity> response = new House365RestResponse<>();

        // 业务层统一处理
        House365RestObject<CustomerEntity> data;
        try {
            if (StringUtils.isEmpty( sourceType )) {
                data = doCheckCustomerPhone( userId, customerPhone );
                response.setData( data );
            }
            if ("1".equals( sourceType )) {
                data = doCheckCustomerPhone( userId, customerPhone, sourceType );
                response.setData( data );
            }
            if ("2".equals( sourceType )) {
                data = doCheckCustomerPhone( platMangerId, customerPhone, sourceType );
                response.setData( data );
            }
            response.setResult( ReturnAppResult.APP_SUCCESS.getResultCode() );
            response.setMsg( ReturnAppResult.APP_SUCCESS.getResultMessage() );
        } catch (Exception e) {
            LOGGER.error( e.getMessage(), e );
            response.setResult( ReturnAppResult.APP_FAIL.getResultCode() );
            response.setMsg( (ReturnAppResult.APP_FAIL.getResultMessage() + ":" + e.getMessage()) );
        }
        return response;
    }

    @Override
    public House365RestResponse checkCustomerPhoneByCustomerIds(String userIds, String customerIds) {
        House365RestResponse<CustomerEntity> response = new House365RestResponse<>();

        // 业务层统一处理
        try {
            House365RestObject<CustomerEntity> data = doCheckCustomerPhoneByCustomerIds( userIds, customerIds );
            response.setResult( ReturnAppResult.APP_SUCCESS.getResultCode() );
            response.setMsg( ReturnAppResult.APP_SUCCESS.getResultMessage() );
            response.setData( data );
        } catch (Exception e) {
            LOGGER.error( e.getMessage(), e );
            response.setResult( ReturnAppResult.APP_FAIL.getResultCode() );
            response.setMsg( (ReturnAppResult.APP_FAIL.getResultMessage() + ":" + e.getMessage()) );
        }
        return response;
    }

    private House365RestObject<CustomerEntity> doCheckCustomerPhone(Integer userId, String customerPhone, String sourceType) throws Exception {
        // 返回Json对象
        House365RestObject<CustomerEntity> restObject = new House365RestObject<>();

        Map<String, Object> result = new HashMap<>( 10 );

        if (!Strings.isNullOrEmpty( customerPhone )) {
            Map<String, Object> queryManagerMap = new HashMap<>( 10 );
            queryManagerMap.put( "EQ_phone", customerPhone );
            queryManagerMap.put( "EQ_creater", userId );
            queryManagerMap.put( "EQ_hotline", "0" );
            queryManagerMap.put( "EQ_createSource", "PT" );
            queryManagerMap.put( "EQ_customerSourceType", "8" );
            QueryParams<Map<String, String>> queryManagerParams = new QueryParams<>( queryManagerMap );

            List<CustomerEntity> managerCustomers = customerService.queryAll( queryManagerParams );
            if (CollectionUtils.isNotEmpty( managerCustomers )) {
                result.put( "result", "0" );
                result.put( "msg", "该号码已添加,请勿重复操作" );
                restObject.setParaMap( result );
                return restObject;
            }

            UserEntity userEntity = userMapper.getById( userId );
            Map<String, Object> queryMap = new HashMap<>( 10 );
            queryMap.put( "deptId", userEntity.getDeptId() );
            List<UserEntity> userList = userMapper.queryByConditions( queryMap );
            if (CollectionUtils.isNotEmpty( userList )) {
                List<String> createList = new ArrayList<>();
                userList.forEach( u -> createList.add( String.valueOf( u.getId() ) ) );
                //3天内添加人当前所在分组所有添加过的客户手机号(15天内)；
                Date date = new Date();
                date = DateTimeUtils.getDaysAgo( date, 15 );
                Map<String, Object> map = new HashMap<>( 10 );
                map.put( "isPrivate", 1 );
                map.put( "createTime", date );
                map.put( "phone", customerPhone );
                map.put( "createIdList", createList );
                queryManagerMap.put( "customerSourceType", 8 );
                List<CustomerEntity> mergeList = customerMapper.queryByConditions( map );
                if (CollectionUtils.isNotEmpty( mergeList )) {
                    result.put( "result", "0" );
                    result.put( "msg", "该号码已由其他人上报，请勿重复操作" );
                    restObject.setParaMap( result );
                    return restObject;
                }
            }

            result.put( "result", "1" );
            restObject.setParaMap( result );
        }
        return restObject;
    }

    /**
     * 检查用户手机号
     */
    private House365RestObject<CustomerEntity> doCheckCustomerPhone(Integer userId, String customerPhone) throws Exception {
        // 返回Json对象
        House365RestObject<CustomerEntity> restObject = new House365RestObject<>();

        Map<String, Object> result = new HashMap<>( 10 );

        if (!Strings.isNullOrEmpty( customerPhone )) {
            UserEntity user = (UserEntity) userService.getById( userId );

            Map<String, Object> queryManagerMap = new HashMap<>( 10 );
            queryManagerMap.put( "EQ_phone", customerPhone );
            queryManagerMap.put( "EQ_managerId", user.getId() );
            queryManagerMap.put( "EQ_hotline", "0" );
            QueryParams<Map<String, String>> queryManagerParams = new QueryParams<>( queryManagerMap );

            List<CustomerEntity> managerCustomers = customerService.queryAll( queryManagerParams );
            if (CollectionUtils.isNotEmpty( managerCustomers )) {
                result.put( "result", "0" );
                result.put( "msg", "该号码已存在与当前帐号下" );
                restObject.setParaMap( result );
                return restObject;
            }

            String city = departmentService.getCityByDepartmentId( user.getDeptId() );
            //南京站添加用户，重复用户的提示，仅提示自己名下的重复手机号码，其他站保持线上不变。
            if (!"nj".equals( city )) {
                //4.1.0版本其他城市判断重复用户添加私客条件
                Map<String, Object> searchMap = new HashMap<>( 10 );
                searchMap.put( "phone", customerPhone );
                searchMap.put( "isPrivate", 1 );
                if (StringUtils.isNotBlank( city )) {
                    searchMap.put( "city", city );
                }
                List<CustomerEntity> list = customerMapper.queryByConditions( searchMap );
                if (CollectionUtils.isNotEmpty( list )) {
                    result.put( "result", "0" );
                    result.put( "msg", "该号码已存在于他人帐号下" );
                    restObject.setParaMap( result );
                    return restObject;
                }
            }
            result.put( "result", "1" );
            restObject.setParaMap( result );
        }
        return restObject;
    }

    /**
     * 检查用户手机号
     */
    private House365RestObject<CustomerEntity> doCheckCustomerPhoneByCustomerIds(String userIds, String customerIds) throws Exception {
        // 返回Json对象
        House365RestObject<CustomerEntity> restObject = new House365RestObject<>();

        Map<String, Object> result = new HashMap<>( 10 );

        if (!Strings.isNullOrEmpty( customerIds ) && !Strings.isNullOrEmpty( userIds )) {
            String[] userIdArray = userIds.split( "," );
            for (String userId : userIdArray) {
                Integer uId = Integer.valueOf( userId );
                UserEntity user = (UserEntity) userService.getById( uId );
                String[] customerIdArray = customerIds.split( "," );
                String flag = "1";

                StringBuilder inCurrentUser = new StringBuilder();
                StringBuilder inOtherUser = new StringBuilder();
                for (String customerId : customerIdArray) {
                    CustomerEntity customer = customerService.getById( Integer.valueOf( customerId ) );
                    Map<String, Object> queryManagerMap = new HashMap<>( 10 );
                    queryManagerMap.put( "EQ_phone", customer.getPhone() );
                    queryManagerMap.put( "EQ_managerId", user.getId() );
                    queryManagerMap.put( "EQ_hotline", "0" );
                    QueryParams<Map<String, String>> queryManagerParams = new QueryParams<>( queryManagerMap );

                    List<CustomerEntity> managerCustomers = customerService.queryAll( queryManagerParams );
                    if (CollectionUtils.isNotEmpty( managerCustomers )) {
                        flag = "0";
                        inCurrentUser.append( customer.getPhone().substring( 0, 3 ) + "****" + customer.getPhone().substring( 7,
                                customer.getPhone().length() ) ).append(
                                " " );
                        result.put( "msg", "该号码已存在与当前帐号下" );
                        continue;
                    }

                    String city = departmentService.getCityByDepartmentId( user.getDeptId() );
                    //南京站添加用户，重复用户的提示，仅提示自己名下的重复手机号码，其他站保持线上不变。
                    if (!"nj".equals( city )) {
                        Map<String, Object> queryCityMap = new HashMap<>();
                        queryCityMap.put( "EQ_phone", customer.getPhone() );
                        if (StringUtils.isNotBlank( city )) {
                            queryCityMap.put( "EQ_cityCode", city );
                        }
                        queryCityMap.put( "EQ_hotline", "0" );
                        queryCityMap.put( "ISNOTNULL_managerId", "1" );
                        QueryParams<Map<String, String>> queryCityParams = new QueryParams<>( queryCityMap );
                        List<CustomerEntity> cityCustomers = customerService.queryAll( queryCityParams );
                        if (cityCustomers != null && cityCustomers.size() != 0) {
                            flag = "0";
                            inOtherUser.append(
                                    customer.getPhone().substring( 0, 3 ) + "****" + customer.getPhone().substring( 7,
                                            customer.getPhone().length() ) ).append(
                                    " " );
                            result.put( "msg", "该号码已存在于他人帐号下" );
                        }
                    }
                }
                String msg = "";
                if ("0".equals( flag )) {
                    if (inCurrentUser.length() > 0) {
                        msg += "客户" + inCurrentUser.toString() + "已存在与当前帐号下";
                    }

                    if (inOtherUser.length() > 0) {
                        msg += "客户" + inCurrentUser.toString() + "已存在于当前帐号下";
                    }
                }

                result.put( "result", flag );
                result.put( "msg", msg );
            }
            restObject.setParaMap( result );
        }
        return restObject;
    }

    /**
     * 客户信息列表查询
     *
     * @param request 客户信息列表查询请求
     * @return 客户信息列表查询响应
     */
    @Override
    public CustomerListResponse getCustomerList(CustomerListRequest request) {
        CustomerListResponse response = new CustomerListResponse();
        try {
            QueryParams<CustomerEntity> queryParams = new QueryParams<>( request.getSearchParams() );
            queryParams.setPaging( request.getPaging() );
            queryParams.setOrderColumn( request.getOrderColumn() );
            queryParams.setOrderMode( request.getOrderMode() );
            List<CustomerEntity> customers = customerService.queryByPage( queryParams );
            response.setPaging( queryParams.getPaging() );
            response.setObjectList( customers );
            response.setResultCode( ReturnResult.SUCCESS.getResultCode() );
            response.setResultMessage( ReturnResult.SUCCESS.getResultMessage() );
        } catch (Exception ex) {
            LOGGER.error( ex.getMessage(), ex );
            response.setResultCode( ReturnResult.FAIL.getResultCode() );
            response.setResultMessage( ex.getMessage() );
        }
        return response;
    }

    @Override
    public Integer getTotalAbandon(CustomerListRequest request) {
        Integer count = 0;
        try {
            QueryParams<CustomerEntity> queryParams = new QueryParams<>( request.getSearchParams() );
            queryParams.setPaging( request.getPaging() );
            queryParams.setOrderColumn( request.getOrderColumn() );
            queryParams.setOrderMode( request.getOrderMode() );
            count = customerService.getTotalAbandon( queryParams );
        } catch (Exception ex) {
            LOGGER.error( ex.getMessage(), ex );
        }
        return count;
    }

    @Override
    public Integer getTotalCall(CustomerListRequest request) {
        Integer count = 0;
        try {
            QueryParams<CustomerEntity> queryParams = new QueryParams<>( request.getSearchParams() );
            queryParams.setPaging( request.getPaging() );
            queryParams.setOrderColumn( request.getOrderColumn() );
            queryParams.setOrderMode( request.getOrderMode() );
            count = customerService.getTotalCall( queryParams );
        } catch (Exception ex) {
            LOGGER.error( ex.getMessage(), ex );
        }
        return count;
    }

    @Override
    public Integer getTotalCallOptimize(CustomerListRequest request) {
        Integer count = 0;
        try {
            QueryParams<CustomerEntity> queryParams = new QueryParams<>( request.getSearchParams() );
            queryParams.setPaging( request.getPaging() );
            queryParams.setOrderColumn( request.getOrderColumn() );
            queryParams.setOrderMode( request.getOrderMode() );
            count = customerService.getTotalCallOptimize( queryParams );
        } catch (Exception ex) {
            LOGGER.error( ex.getMessage(), ex );
        }
        return count;
    }

    @Override
    public List<Map<String, Object>> getMarketInfo(CustomerListRequest request) {
        QueryParams<CustomerEntity> queryParams = new QueryParams<>( request.getSearchParams() );
        return customerService.getMarketInfo( queryParams );
    }


    /**
     * 客户信息列表查询
     *
     * @param request 客户信息列表查询请求
     * @return 客户信息列表查询响应
     */
    @Override
    public CustomerListResponse getCustomerManagementList(CustomerListRequest request) {
        CustomerListResponse response = new CustomerListResponse();
        try {
            QueryParams<CustomerEntity> queryParams = new QueryParams<>( request.getSearchParams() );
            queryParams.setPaging( request.getPaging() );
            queryParams.setOrderColumn( request.getOrderColumn() );
            queryParams.setOrderMode( request.getOrderMode() );
            List<CustomerEntity> customers = customerService.getCustomerManagementList( queryParams );
            response.setPaging( queryParams.getPaging() );
            response.setObjectList( customers );
            response.setResultCode( ReturnResult.SUCCESS.getResultCode() );
            response.setResultMessage( ReturnResult.SUCCESS.getResultMessage() );
        } catch (Exception ex) {
            LOGGER.error( ex.getMessage(), ex );
            response.setResultCode( ReturnResult.FAIL.getResultCode() );
            response.setResultMessage( ex.getMessage() );
        }
        return response;
    }

    @Override
    public CustomerListResponse getPlatformCustomerList(CustomerListRequest request) {
        CustomerListResponse response = new CustomerListResponse();
        try {
            QueryParams<CustomerEntity> queryParams = new QueryParams<>( request.getSearchParams() );
            queryParams.setPaging( request.getPaging() );
            queryParams.setOrderColumn( request.getOrderColumn() );
            queryParams.setOrderMode( request.getOrderMode() );
            List<CustomerEntity> customers = customerService.getPlatformCustomerList( queryParams );
            response.setPaging( queryParams.getPaging() );
            response.setObjectList( customers );
            response.setResultCode( ReturnResult.SUCCESS.getResultCode() );
            response.setResultMessage( ReturnResult.SUCCESS.getResultMessage() );
        } catch (Exception ex) {
            LOGGER.error( ex.getMessage(), ex );
            response.setResultCode( ReturnResult.FAIL.getResultCode() );
            response.setResultMessage( ex.getMessage() );
        }
        return response;
    }

    /**
     * 客户信息列表查询:查询客户标签
     *
     * @param request 客户信息列表查询请求
     * @return 客户信息列表查询响应
     */
    @Override
    public CustomerListResponse getCustomerManagementList4Label(CustomerListRequest request) {
        CustomerListResponse response = new CustomerListResponse();
        try {
            QueryParams<CustomerEntity> queryParams = new QueryParams<>( request.getSearchParams() );
            queryParams.setPaging( request.getPaging() );
            String labelId = (String) request.getSearchParams().get( "EQ_labelId" );
            List<String> labelIdList = new ArrayList<>();
            if (StringUtils.isNotEmpty( labelId )) {
                String[] lids;
                if (labelId.contains( "," )) {
                    lids = labelId.split( "," );
                } else {
                    lids = new String[1];
                    lids[0] = labelId;
                }
                for (String lid : lids) {
                    labelIdList.add( lid );
                }
            }
            Map<String, Object> map = new HashMap<>();
            Map<String, Object> paramMap = request.getSearchParams();
            map.put( "OrderColumn", request.getOrderColumn() );
            map.put( "OrderMode", request.getOrderMode() );
            map.put( "PageNumber", ((request.getPaging().getCurrentPage() - 1) * request.getPaging().getPageSize() < 0 ? 0 : (request.getPaging().getCurrentPage() - 1) * request.getPaging().getPageSize()) );
            map.put( "pageSize", request.getPaging().getPageSize() );
            map.put( "labelIdList", labelIdList );
            List<String> createSourceList = new ArrayList<>();
            Set<Map.Entry<String, Object>> entrySet = paramMap.entrySet();
            Iterator<Map.Entry<String, Object>> it2 = entrySet.iterator();
            while (it2.hasNext()) {
                // 获取Map.Entry关系对象me
                Map.Entry<String, Object> me = it2.next();
                // 通过关系对像获取key
                String key2 = me.getKey();
                // 通过关系对像获取value
                Object value2 = (Object) me.getValue();
                if (key2.contains( "_" )) {
                    key2 = key2.split( "_" )[1];
                }
                map.put( key2, value2 );
            }

            Object vvv = map.get( "createSourceList3" );
            if (map.containsKey( "createSource" ) && map.get( "createSource" ) != null && !"".equals( map.get( "createSource" ) )) {
                createSourceList = (ArrayList) map.get( "createSource" );
                if (createSourceList.size() == 1) {
                    map.put( "createSourceList3", createSourceList.get( 0 ) );
                } else {
                    map.put( "createSourceList1", createSourceList.get( 0 ) );
                    map.put( "createSourceList2", createSourceList.get( 1 ) );
                }
            }
            if (map.containsKey( "isBack" )) {
                map.put( "hasBack", "2" );
                map.remove( "isBack" );
            }
            List<CustomerEntity> customers = customermergemapper.getCustomerManagementList4Label( map );
            Integer customersCount = customermergemapper.getCustomerManagementList4LabelCount( map );
            if (CollectionUtils.isNotEmpty( customers )) {
                int finalPages = customersCount % 100 == 0 ? customersCount / 100 : customersCount / 100 + 1;
                queryParams.getPaging().setPages( finalPages );
                queryParams.getPaging().setRecords( customersCount );
            }

            response.setPaging( queryParams.getPaging() );
            response.setObjectList( customers );
            response.setResultCode( ReturnResult.SUCCESS.getResultCode() );
            response.setResultMessage( ReturnResult.SUCCESS.getResultMessage() );
        } catch (Exception ex) {
            LOGGER.error( ex.getMessage(), ex );
            response.setResultCode( ReturnResult.FAIL.getResultCode() );
            response.setResultMessage( ex.getMessage() );
        }
        return response;
    }

    /**
     * 待回访数据
     *
     * @param request
     * @return
     */
    @Override
    public CustomerListResponse getCustomerListFromOld(CustomerListRequest request) {
        CustomerListResponse response = new CustomerListResponse();
        try {
            QueryParams<CustomerEntity> queryParams = new QueryParams<>( request.getSearchParams() );
            queryParams.setPaging( request.getPaging() );
            queryParams.setOrderColumn( request.getOrderColumn() );
            queryParams.setOrderMode( request.getOrderMode() );
            List<CustomerEntity> customers = customerService.getCustomerListFromOld( queryParams );
            response.setPaging( queryParams.getPaging() );
            response.setObjectList( customers );
            response.setResultCode( ReturnResult.SUCCESS.getResultCode() );
            response.setResultMessage( ReturnResult.SUCCESS.getResultMessage() );
        } catch (Exception ex) {
            LOGGER.error( ex.getMessage(), ex );
            response.setResultCode( ReturnResult.FAIL.getResultCode() );
            response.setResultMessage( ex.getMessage() );
        }
        return response;
    }

    /**
     * 保存客户信息（已经遗弃不需要加日志）
     *
     * @param request 客户信息请求
     * @return 保存客户信息响应
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public CustomerResponse addCustomer(CustomerRequest request) {
        CustomerResponse response = new CustomerResponse();
        try {
            CustomerEntity entity = request.getEntity();
            hgsCacheUtil.delUserSummary( entity.getManagerId() );
            customerService.save( entity );
            Map<String, String> param = new HashMap<>( 10 );
            param.put( "customerId", String.valueOf( entity.getId() ) );
            customerService.sendMessageToWechat( NEWCUSTOMER, String.valueOf( entity.getManagerId() ), param );

            response.setEntity( entity );
            response.setResultCode( ReturnResult.SUCCESS.getResultCode() );
            response.setResultMessage( ReturnResult.SUCCESS.getResultMessage() );
        } catch (Exception ex) {
            LOGGER.error( ex.getMessage(), ex );
            response.setResultCode( ReturnResult.FAIL.getResultCode() );
            response.setResultMessage( ex.getMessage() );
        }
        return response;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public CustomerResponse addCustomerNew(CustomerRequest request, int userId, String userName) {
        CustomerResponse response = new CustomerResponse();
        try {
            CustomerEntity entity = request.getEntity();
            hgsCacheUtil.delUserSummary( entity.getManagerId() );
            int id = customerService.save( entity );
            //记录客户新增日志
            entity.setId( id );
            logUtils.saveCustomerLog( entity, 1, userId, userName );

            Map<String, String> param = new HashMap<>( 10 );
            param.put( "customerId", String.valueOf( entity.getId() ) );
            customerService.sendMessageToWechat( NEWCUSTOMER, String.valueOf( entity.getManagerId() ), param );

            response.setEntity( entity );
            response.setResultCode( ReturnResult.SUCCESS.getResultCode() );
            response.setResultMessage( ReturnResult.SUCCESS.getResultMessage() );
        } catch (Exception ex) {
            LOGGER.error( ex.getMessage(), ex );
            response.setResultCode( ReturnResult.FAIL.getResultCode() );
            response.setResultMessage( ex.getMessage() );
        }
        return response;
    }

    @Override
    public CustomerResponse setDeleteFlag(Integer id, int userId, String userName) {
        CustomerResponse response = new CustomerResponse();
        try {
            CustomerEntity customerEntity = customerService.getById( id );
            if (customerEntity != null) {
                hgsCacheUtil.delUserSummary( customerEntity.getManagerId() );

                customerEntity.setIsDelete( 1 );
                customerService.update( customerEntity );
                //新增客户删除日志
                logUtils.saveCustomerLog( customerEntity, 3, userId, userName );
            }

            response.setResultCode( ReturnResult.SUCCESS.getResultCode() );
            response.setResultMessage( ReturnResult.SUCCESS.getResultMessage() );
        } catch (Exception ex) {
            LOGGER.error( ex.getMessage(), ex );
            response.setResultCode( ReturnResult.FAIL.getResultCode() );
            response.setResultMessage( ex.getMessage() );
        }
        return response;
    }


    /**
     * 修改客户信息(不需要添加客户编辑日志)
     *
     * @param request 修改客户信息请求
     * @return 修改客户信息响应
     */
    @Override
    public CustomerResponse updateCustomer(CustomerRequest request, int userId, String userName) {
        CustomerResponse response = new CustomerResponse();
        try {
            int id = request.getEntity().getId();
            CustomerEntity oldEntity = customerMapper.queryById( id );
            if (oldEntity.getIsDelete() == 0 && request.getEntity().getIsDelete() == 1) {
                //新增客户删除日志
                logUtils.saveCustomerLog( oldEntity, 3, userId, userName );
            }
            customerService.update( request.getEntity() );
            response.setResultCode( ReturnResult.SUCCESS.getResultCode() );
            response.setResultMessage( ReturnResult.SUCCESS.getResultMessage() );
        } catch (Exception ex) {
            LOGGER.error( ex.getMessage(), ex );
            response.setResultCode( ReturnResult.FAIL.getResultCode() );
            response.setResultMessage( ex.getMessage() );
        }
        return response;
    }

    /**
     * 重写客户编辑（需要添加客户编辑日志）
     *
     * @param request
     * @param userId
     * @param userName
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public CustomerResponse updateCustomerNew(CustomerRequest request, int userId, String userName) {
        CustomerResponse response = new CustomerResponse();
        try {
            int id = request.getEntity().getId();
            CustomerEntity oldEntity = customerMapper.queryById( id );
            customerService.update( request.getEntity() );
            CustomerEntity newEntity = customerService.getById( id );
            //调用工具类添加日志方法
            logUtils.newRecordOperateLog( oldEntity, newEntity, id, userId, userName );
            //更新customer_merge新表
            Map<String, Object> map = new HashMap<>( 10 );
            map.put( "name", request.getEntity().getName() );
            map.put( "bakPhone1", request.getEntity().getBakPhone1() );
            map.put( "sex", request.getEntity().getSex() );
            map.put( "buyIntention", request.getEntity().getBuyIntention() );
            map.put( "traceStatus", request.getEntity().getTraceStatus() );
            map.put( "updateTime", new Date() );
            map.put( "updater", userId );
            map.put( "id", id );
            customermergemapper.update( map );

            response.setResultCode( ReturnResult.SUCCESS.getResultCode() );
            response.setResultMessage( ReturnResult.SUCCESS.getResultMessage() );
        } catch (Exception ex) {
            LOGGER.error( ex.getMessage(), ex );
            response.setResultCode( ReturnResult.FAIL.getResultCode() );
            response.setResultMessage( ex.getMessage() );
        }
        return response;
    }

    /**
     * 通过ID获取客户信息
     *
     * @param id 唯一标识
     * @return 通过ID获取客户信息响应
     */
    @Override
    public CustomerResponse getCustomerById(Integer id) {
        CustomerResponse response = new CustomerResponse();
        try {
            CustomerEntity entity = customerService.getById( id );
            response.setEntity( entity );
            response.setResultCode( ReturnResult.SUCCESS.getResultCode() );
            response.setResultMessage( ReturnResult.SUCCESS.getResultMessage() );
        } catch (Exception ex) {
            LOGGER.error( ex.getMessage(), ex );
            response.setResultCode( ReturnResult.FAIL.getResultCode() );
            response.setResultMessage( ex.getMessage() );
        }
        return response;
    }

    /**
     * 获取客户经理概要统计信息
     *
     * @param managerId
     * @return
     */
    @Override
    public House365RestResponse getSummary(String managerId) {
        House365RestResponse restResponse = new House365RestResponse();
        House365RestObject<Map<String, Object>> restObject = new House365RestObject();
        Map<String, Object> summary = customerService.getSummary( managerId );
        restObject.setEntity( summary );
        restResponse.setData( restObject );
        return restResponse;
    }

    /**
     * 获取客户经理概要统计信息
     *
     * @param
     * @return
     */
    @Override
    public Map<String, Object> getNewSummary(Map<String, String> summaryParams) {
        return customerService.getNewSummary( summaryParams );
    }

    @Override
    public House365RestResponse getSummarySimple(String managerId) {
        House365RestResponse restResponse = new House365RestResponse();
        House365RestObject<Map<String, Object>> restObject = new House365RestObject();
        Map<String, Object> summary = customerService.getSummarySimple( managerId );
        restObject.setEntity( summary );
        restResponse.setData( restObject );
        return restResponse;
    }

    /**
     * 获取客户经理概要统计信息
     *
     * @param managerId
     * @return
     */
    @Override
    public House365RestResponse getHotLineSummary(Integer managerId, String cityCode) {
        House365RestResponse restResponse = new House365RestResponse();
        House365RestObject<Map<String, Object>> restObject = new House365RestObject();
        Map<String, Object> summary = new HashMap<>( 10 );

        Map<String, Object> searchParams = new HashMap<>( 10 );
        List<Integer> userIds = userService.getUserIdOnPath( managerId );

        Calendar calendar = Calendar.getInstance();
        calendar.setTime( DateTimeUtils.getDateByString( DateTimeUtils.parseDate( new Date(), "yyyy-MM-dd 23:59:59" ) ) );

        //来源为 400电话
        searchParams.put( "EQ_userIds", Joiner.on( "," ).join( userIds ) );
        searchParams.put( "EQ_createSource", Constant.CustomerSourceEnum.HOTLINE.getMsg() );
        searchParams.put( "EQ_cityCode", cityCode );
        searchParams.put( "NOTEQ_status", Constant.HotLineStatusEnum.DELETE.getMsg().intValue() );
        searchParams.put( "LTE_createTimeEnd", calendar.getTime() );
        calendar.add( Calendar.DATE, -1 );
        searchParams.put( "GTE_createTimeStart", calendar.getTime() );
        QueryParams todayParams = new QueryParams( searchParams );
        int newadd = customerService.getTotalCount( todayParams );
        summary.put( "newadd", newadd );

        searchParams.clear();
        //来源为 400电话
        searchParams.put( "EQ_userIds", Joiner.on( "," ).join( userIds ) );
        searchParams.put( "EQ_createSource", Constant.CustomerSourceEnum.HOTLINE.getMsg() );
        searchParams.put( "EQ_cityCode", cityCode );
        searchParams.put( "NOTEQ_status", Constant.HotLineStatusEnum.DELETE.getMsg().intValue() );
        QueryParams historyParams = new QueryParams( searchParams );
        int allCount = customerService.getTotalCount( historyParams );
        summary.put( "allCount", allCount );

        restObject.setEntity( summary );
        restResponse.setData( restObject );
        return restResponse;
    }

    @Override
    public House365RestResponse getSummaryIds(String summaryType, String managerId) {
        House365RestResponse restResponse = new House365RestResponse();
        House365RestObject<List<Integer>> restObject = new House365RestObject();
        List<Integer> summary = customerService.getSummaryIds( summaryType, managerId );
        restObject.setEntity( summary );
        restResponse.setData( restObject );
        return restResponse;
    }

    /**
     * 公海页面展示共多少条数据，今日新增数据
     *
     * @param cityCode
     * @return
     */
    @Override
    public House365RestResponse getSeaSummary(String cityCode) {
        House365RestResponse restResponse = new House365RestResponse();
        House365RestObject<Map<String, Object>> restObject = new House365RestObject();
        Map<String, Object> summary = customerService.getSeaSummary( cityCode );
        restObject.setEntity( summary );
        restResponse.setData( restObject );
        return restResponse;
    }

    /**
     * 统计状态来源分布
     *
     * @param cityCode
     * @param status
     * @param period
     * @param startDate
     * @param endDate
     * @return
     */
    public House365RestResponse statisticStatusSource(String cityCode, String status, String period, String startDate, String endDate) {
        House365RestResponse restResponse = new House365RestResponse();
        House365RestObject<Map<String, Object>> restObject = new House365RestObject();
        Map<String, Object> summary = customerService.getSeaSummary( cityCode );
        restObject.setEntity( summary );
        restResponse.setData( restObject );
        return restResponse;
    }

    /**
     * 派工
     *
     * @param customerIds
     * @param userIds
     * @throws Exception
     */
    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void bindUser(String[] customerIds, String[] userIds, Integer operId, boolean isHandover, String type, String assignFrom) throws Exception {
        if (customerIds != null && userIds != null) {
            for (String userId : userIds) {
                Integer uId = Integer.valueOf( userId );
                hgsCacheUtil.delUserSummary( uId );
            }
            List<String> useridSplit = Arrays.asList( userIds );
            int size = useridSplit.size();
            int i = 0;
            Map<String, Object> map = new HashMap<>( 10 );
            for (String customerId : customerIds) {
                CustomerEntity customer = customerService.getById( Integer.valueOf( customerId ) );
                Integer uid = Integer.valueOf( useridSplit.get( i % size ) );
                UserEntity user = (UserEntity) userService.getById( uid );
                if (customer != null) {
                    assignCustomer( customerIds, uid, operId, user, customer, isHandover, type, assignFrom );
                    //判断如果有回访提醒，需要切换提醒人员
                    map.put( "customerId", Integer.parseInt( customerId ) );
                    List<CustomerRemindEntity> list = remindMapper.queryByConditions( map );
                    if (CollectionUtils.isNotEmpty( list )) {
                        for (CustomerRemindEntity entity : list) {
                            remindMapper.delete( entity.getId() );
                            entity.setCreateUserId( uid );
                            remindMapper.save( entity );
                        }
                    }
                }
                i++;
            }

        }
    }

    /**
     * 客户转移
     *
     * @param customerIds
     * @param userIds
     * @param operId
     * @param isHandover
     * @param type
     * @param assignFrom
     * @throws Exception
     */
    @Override
//    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void transferUser(final String[] customerIds, String[] userIds, final Integer operId, final String managerId, final boolean isHandover, final String type, final String assignFrom, final int count) throws Exception {
        if (customerIds != null && userIds != null) {
            for (String userId : userIds) {
                Integer uId = Integer.valueOf( userId );
                hgsCacheUtil.delUserSummary( uId );
            }
            redisUtils.setValueExpireNew( "transfer:process:" + operId + managerId, "0", 1, TimeUnit.HOURS );
            redisUtils.addKeyVal( "transfer:total:" + operId + managerId, String.valueOf( count ) );

            if (redisUtils.hasKey( "transfer:done:" + operId + managerId )) {
                redisUtils.deleteByKeyNew( "transfer:done:" + operId + managerId );
            }

            final List<String> useridSplit = Arrays.asList( userIds );
//            final int size = useridSplit.size();
//            int i = 0;
            if (redisUtils.hasKey( "transfer:done:" + operId + managerId )) {
                redisUtils.deleteByKeyNew( "transfer:done:" + operId + managerId );
            }
            ArrayList<Future<Integer>> futures = new ArrayList<>();
            ExecutorService executor = Executors.newFixedThreadPool( 5 );
            ExecutorCompletionService<Integer> completionService = new ExecutorCompletionService( executor );


            TransferCustomers t = new TransferCustomers( useridSplit, customerIds, operId, managerId, count, type, assignFrom );
            Future<Integer> f = completionService.submit( t );
            futures.add( f );
//            for (String customerId : customerIds) {
//                CustomerEntity customer = customerService.getById(Integer.valueOf(customerId));
//                Integer uid = Integer.valueOf(useridSplit.get(i % size));
//                UserEntity user = (UserEntity) userService.getById(uid);
//                if (customer != null) {
////                    TransferCustomers t = new TransferCustomers(customerIds, uid, operId, managerId, user, customer, isHandover, type, assignFrom, count);
//                    Future<Integer> f = completionService.submit(t);
//                    futures.add(f);
////                    assignCustomer(customerIds, uid, operId, user, customer, isHandover, type, assignFrom);
//                    //判断如果有回访提醒，需要切换提醒人员
//                    Map<String, Object> map = new HashMap<>(10);
//                    map.put("customerId", Integer.parseInt(customerId));
//                    List<CustomerRemindEntity> list = remindMapper.queryByConditions(map);
//                    if (CollectionUtils.isNotEmpty(list)) {
//                        for (CustomerRemindEntity entity : list) {
//                            remindMapper.delete(entity.getId());
//                            entity.setCreateUserId(uid);
//                            remindMapper.save(entity);
//                        }
//                    }
//                }
//                i++;
//            }
            int doenTask = 0;
            while (doenTask < futures.size()) {
                Integer res = completionService.take().get();
                LOGGER.info( "task done total handle num [{}]", res );
                doenTask++;
            }
            // 关闭线程池。
            executor.shutdown();
            redisUtils.addKeyVal( "active:process:" + operId + managerId, "1" );


//            pool.submit(){
//            Future<Integer> f = completionService.submit();
//            futures.add(f);
//            executor.execute(new Runnable() {
//                @Override
//                public void run() {
//                    for (int i=0;i<customerIds.length;i++) {
//                        CustomerEntity customer = customerService.getById(Integer.valueOf(customerIds[i]));
//                        Integer uid = Integer.valueOf(useridSplit.get(i % size));
//                        UserEntity user = (UserEntity) userService.getById(uid);
//                        if (customer != null) {
//                            doTransfer(customerIds, uid, operId, managerId, user, customer, isHandover, type, assignFrom, count);
//                            //判断如果有回访提醒，需要切换提醒人员
//                            Map<String, Object> map = new HashMap<>(10);
//                            map.put("customerId", Integer.parseInt(customerIds[i]));
//                            List<CustomerRemindEntity> list = remindMapper.queryByConditions(map);
//                            if (CollectionUtils.isNotEmpty(list)) {
//                                for (CustomerRemindEntity entity : list) {
//                                    remindMapper.delete(entity.getId());
//                                    entity.setCreateUserId(uid);
//                                    remindMapper.save(entity);
//                                }
//                            }
//                        }
//                    }
//
//                }
//            });
//            executor.shutdown();
            redisUtils.addKeyVal( "transfer:process:" + operId + managerId, "1" );
        }
    }

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void batch2Sea(String[] customerIds, Integer operId, String managerId, int count, String userName) throws Exception {
        redisUtils.setValueExpireNew( "remove:process:" + operId + managerId, "0", 1, TimeUnit.HOURS );
        redisUtils.addKeyVal( "remove:total:" + operId + managerId, String.valueOf( count ) );

        if (redisUtils.hasKey( "remove:done:" + operId + managerId )) {
            redisUtils.deleteByKeyNew( "remove:done:" + operId + managerId );
        }
        if (redisUtils.hasKey( "remove:done:" + operId + managerId )) {
            redisUtils.deleteByKeyNew( "remove:done:" + operId + managerId );
        }
        ArrayList<Future<Integer>> futures = new ArrayList<>();
        ExecutorService executor = Executors.newFixedThreadPool( 5 );
        ExecutorCompletionService<Integer> completionService = new ExecutorCompletionService( executor );


        BatchCustomers2Sea t = new BatchCustomers2Sea( customerIds, operId, managerId, count, userName );
        Future<Integer> f = completionService.submit( t );
        futures.add( f );

        int doenTask = 0;
        while (doenTask < futures.size()) {
            Integer res = completionService.take().get();
            LOGGER.info( "task done total handle num [{}]", res );
            doenTask++;
        }
        // 关闭线程池。
        executor.shutdown();
        redisUtils.addKeyVal( "remove:process:" + operId + managerId, "1" );
    }

    private class BatchCustomers2Sea implements Callable<Integer> {
        private AtomicInteger ai = new AtomicInteger( 0 );
        private String[] customerIds;
        private int operId;
        private String managerId;
        private int count;
        private String userName;

        public BatchCustomers2Sea(String[] customerIds, int operId, String managerId, int count, String userName) {
            this.customerIds = customerIds;
            this.operId = operId;
            this.managerId = managerId;
            this.count = count;
            this.userName = userName;
        }

        @Override
        public Integer call() throws Exception {

            for (String strCustomerId : customerIds) {
                Integer customerId = Integer.valueOf( strCustomerId );
                CustomerEntity entity = customerMapper.queryById( customerId );
                Map<String, Object> map = new HashMap<>( 10 );
                map.put( "managerId", entity.getManagerId() );
                map.put( "phone", entity.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() );
                            }
                            customerEntity.setOceanDate( new Date() );
                            customerEntity.setUpdater( String.valueOf( operId ) );
                            customerEntity.setUpdateTime( new Date() );
                            customerEntity.setLastManager( customerEntity.getManagerName() );
                            customerEntity.setManagerId( null );
                            customerEntity.setManagerName( null );
                            if (HGSConstant.CustomerSourceType.MARKET.getType().intValue() != customerEntity.getCustomerSourceType().intValue()) {
                                customerService.update( customerEntity );
                            }
                            customerUserService.removeStar( customerId, operId );
                            if (HGSConstant.CustomerSourceType.MARKET.getType().intValue() == customerEntity.getCustomerSourceType().intValue()) {
                                try {
                                    marketCustomerService.removeCustomer( customerEntity, operId );
                                } catch (Exception e) {
                                    LOGGER.error( "---------移入公海是该客户所在的营销活动客户数据异常-----------" );
                                    e.printStackTrace();
                                }
                            }
                            customerEntity.setManagerId( managerId );
                            logUtils.saveCustomerLog( customerEntity, 6, operId, userName );

                        }
                    }
                }
                ai.set( ai.get() + 1 );
                if (getFinishCount2( operId + managerId ) >= count || getFinishCount2( operId + managerId ) >= 500) {
                    break;
                } else {
                    Long completed = increaseDoneKey2( operId + managerId );
                    LOGGER.info( "---------移入公海:-----------" + completed );
                }
                try {
                    Thread.sleep( 200 );
                } catch (Exception e) {
                    LOGGER.error( "移入客户公海中途失败", e );
                }
                LOGGER.info( "---------移入公海已完成:-----------" + ai.get() );
            }
            return ai.get();
        }
    }

    /**
     * 云迹客户移入公海操作
     *
     * @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 );
        }
    }


    private class TransferCustomers implements Callable<Integer> {
        private AtomicInteger atomicInteger = new AtomicInteger( 0 );
        private List<String> useridSplit;
        private String[] customerIds;
        private int operId;
        private String managerId;
        private String type;
        private String assignFrom;
        private int count;

        public TransferCustomers(List<String> useridSplit, String[] customerIds, Integer operId, String managerId, int count, String type, String assignFrom) {
            this.useridSplit = useridSplit;
            this.customerIds = customerIds;
            this.operId = operId;
            this.managerId = managerId;
            this.count = count;
            this.type = type;
            this.assignFrom = assignFrom;
        }

        @Override
        public Integer call() throws Exception {
            final int size = useridSplit.size();
            int i = 0;
            for (String customerId : customerIds) {
                CustomerEntity customer = customerService.getById( Integer.valueOf( customerId ) );
                Integer userId = Integer.valueOf( useridSplit.get( i % size ) );
                UserEntity user = (UserEntity) userService.getById( userId );
                UserEntity logUser = (UserEntity) userService.getById( operId );
                if (customer != null) {
                    LOGGER.error( "----------转移操作开始customer.getManagerId()-----------------" + customer.getManagerId() );
                    if (customer.getManagerId() != null) {
                        LOGGER.info( "user [{}] :transfer customers [{}] from [{}] to [{}]", operId,
                                Joiner.on( "," ).join( customerIds ), customer.getManagerId(), userId );
                    } else {
                        LOGGER.info( "user [{}] :customers [{}] bind user[{}]", operId, Joiner.on( "," ).join( customerIds ), userId );
                    }
                    Date newdate = new Date();
                    Integer oldManagerId = customer.getManagerId();
                    String oldManagerName = customer.getManagerName();
                    String newManagerName = user.getRealName();
                    String oldPhone = customer.getPhone();
                    //将原有客户安家顾问信息一并转移
                    Map<String, Object> paramMap = new HashMap<>( 10 );
                    paramMap.put( "oldManagerId", oldManagerId );
                    paramMap.put( "oldManagerName", oldManagerName );
                    paramMap.put( "newManagerId", userId );
                    paramMap.put( "newManagerName", newManagerName );
                    paramMap.put( "phone", customer.getPhone() );
                    paramMap.put( "isDelete", "0" );
                    paramMap.put( "updater", operId );
                    paramMap.put( "updateTime", newdate );
                    paramMap.put( "isHandover", 1 );
                    customer.setIsHandover( 1 );
                    LOGGER.error( "----------转移操作1 时间1-----------------" + new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( new Date() ) );
                    customerMapper.transferManagerInfo( paramMap );
                    LOGGER.error( "----------转移操作1 时间2-----------------" + new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( new Date() ) );

                    customer.setManagerId( userId );
                    customer.setIsRecycled( 0 );
                    customer.setManagerName( newManagerName );
                    customer.setUpdateTime( newdate );
                    customer.setUpdater( String.valueOf( operId ) );
                    //重置客户绑定置业顾问时间
                    customer.setBindTime( newdate );

                    //转移后的安家顾问下此客户phone
                    paramMap.clear();
                    paramMap.put( "phone", customer.getPhone() );
                    paramMap.put( "managerId", userId );
                    CustomerEntity oldEntity = customermergemapper.getCustomerMerge( paramMap );

                    //客户转移:
                    LOGGER.error( "----------转移操作1:::-----------------" + oldEntity );
                    if (oldEntity == null) {
                        handleCustomerMerge( customer );
                        customer.setOldManagerId( oldManagerId );
                        customer.setOldManagerName( oldManagerName );
                        //此客户没有被当前被转移的安家顾问跟踪过，直接更新客户的安家顾问信息
                        LOGGER.error( "----------转移操作2 时间1-----------------" + new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( new Date() ) );
                        customermergemapper.updateCustomerMerge2( customer );
                        LOGGER.error( "----------转移操作2 时间2-----------------" + new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( new Date() ) );
                    } else {
                        LOGGER.error( "----------转移操作2222-----------------" + oldEntity );
                        //此客户被跟踪过,直接更新安家顾问对应的客户信息
                        mergeCustomerUtil.checkMergeCustomer( customer, oldEntity, operId, logUser.getRealName() );
                        // 意向等级、跟踪状态更新
                        oldEntity.setUpdateTime( newdate );
                        oldEntity.setUpdater( String.valueOf( operId ) );
                        oldEntity.setCreateTime( customer.getCreateTime() );
                        oldEntity.setBindTime( newdate );
                        oldEntity.setManagerId( userId );
                        oldEntity.setIsRecycled( 0 );
                        oldEntity.setIsHandover( 1 );
                        oldEntity.setManagerName( user.getRealName() );
                        //转移判断旧的客户是否有回访记录，有则变更活跃状态，无则不变
                        paramMap.clear();
                        paramMap.put( "phone", oldPhone );
                        paramMap.put( "cityCode", customer.getCityCode() );
                        paramMap.put( "managerId", customer.getManagerId() );
                        paramMap.put( "isPrivate", 1 );
                        List<CustomerEntity> list = customerMapper.queryByConditions( paramMap );
                        LOGGER.error( "----------转移操作333333-----------------" + oldEntity );
                        List<Integer> idList = new ArrayList<>();
                        if (CollectionUtils.isNotEmpty( list )) {
                            for (CustomerEntity c : list) {
                                idList.add( c.getId() );
                            }
                            paramMap.clear();
                            paramMap.put( "idList", idList );
                            List<CustomerCallbackLogEntity> backList = callbackMapper.queryByConditions( paramMap );
                            if (CollectionUtils.isNotEmpty( backList )) {
                                oldEntity.setIsActive( 0 );
                            }
                        }
                        //将客户标签一并合并给新的安家顾问名下该客户
                        paramMap.clear();
                        paramMap.put( "oldManagerId", oldManagerId );
                        paramMap.put( "customerId", customer.getId() );
                        paramMap.put( "newCustomerId", oldEntity.getId() );
                        LOGGER.error( "----------转移操作3 时间1-----------------" + new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( new Date() ) );
                        labelmapper.updateCustomerId( paramMap );
                        LOGGER.error( "----------转移操作3 时间2-----------------" + new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( new Date() ) );
                        //合并客户信息更新
                        Date oldlastCallTime = oldEntity.getLastCallTime();
                        Date currrentCallTime = customer.getLastCallTime();
                        if (currrentCallTime != null && oldlastCallTime.before( currrentCallTime )) {
                            oldEntity.setLastCallTime( currrentCallTime );
                        }
                        handleCustomerMerge( customer, oldEntity );
                        //合并客户
                        oldEntity.setOldManagerId( oldManagerId );
                        oldEntity.setOldManagerName( oldManagerName );
                        customermergemapper.updateCustomerMerge( oldEntity );
                        LOGGER.error( "----------转移操作3 时间3-----------------" + new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( new Date() ) );
                        //将被转移的客户删除:物理删除
                        customermergemapper.deleteSingleCustomerMerge( customer );
                        LOGGER.error( "----------转移操作4 时间4-----------------" + new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( new Date() ) );
                    }
                    //
                    atomicInteger.set( atomicInteger.get() + 1 );
                    if (getFinishCount( operId + managerId ) >= count || getFinishCount( operId + managerId ) >= 500) {
                        break;
                    } else {

                        Long completed = increaseDoneKey( operId + managerId );
                        LOGGER.error( "线程:" + Thread.currentThread().getId() + ",已完成:" + completed );
                        LOGGER.error( "-------------完成sss:-------------" + operId + managerId );
                        LOGGER.error( "-------------完成总数:-------------" + getFinishCount( operId + managerId ) );
                        //添加客户操作日志
                        int paramType = 7;
                        //客户转移 (同时要更新转移客户日志中安家顾问id)
                        paramMap.clear();
                        paramMap.put( "phone", customer.getPhone() );
                        paramMap.put( "oldManagerId", oldManagerId );
                        paramMap.put( "managerId", userId );
                        LOGGER.error( "----------转移操作5 时间5-----------------" + new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( new Date() ) );
                        customerLogMapper.updateManagerId( paramMap );
                        LOGGER.error( "----------转移操作6 时间6-----------------" + new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( new Date() ) );
                        //添加客户操作日志
                        logUtils.saveCustomerLog( customer, paramType, operId, logUser.getRealName() );
                        LOGGER.error( "----------转移操作7 时间7-----------------" + new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( new Date() ) );

                        // 如果当前客户是营销活动来的,需要更新market_customer表的派工时间和置业顾问
                        if (HGSConstant.CustomerSourceType.MARKET.getType().equals( customer.getCustomerSourceType() )) {
                            MarketCustomerEntity marketUser = marketCustomerService.queryByCustomerid( customer.getId() );
                            if (marketUser != null) {
                                marketUser.setManagerId( userId );
                                marketUser.setManagerName( user.getRealName() );
                                marketUser.setBindTime( customer.getBindTime() );
                                marketUser.setUpdateTime( new Date() );
                                marketUser.setUpdater( String.valueOf( operId ) );
                                marketCustomerService.update( marketUser );
                            }
                        }
                        //如果当前客户是云迹客户，需要更新cloud_customer 派工时间和置业顾问
                        if (customer.getCustomerSourceType() == 7) {
                            paramMap.clear();
                            if ("cloud".equals( type )) {
                                paramMap.put( "customerId", Integer.valueOf( assignFrom ) );
                            } else {
                                paramMap.put( "customerId", customer.getId() );
                            }
                            List<CloudCustomerEntity> list = cloudCustomerMapper.queryByConditions( paramMap );
                            if (CollectionUtils.isNotEmpty( list )) {
                                CloudCustomerEntity cloudCustomer = list.get( 0 );
                                cloudCustomer.setManagerId( userId );
                                cloudCustomer.setManagerName( user.getRealName() );
                                cloudCustomer.setBindTime( customer.getBindTime() );
                                cloudCustomer.setUpdateTime( new Date() );
                                cloudCustomer.setUpdater( String.valueOf( operId ) );
                                cloudCustomerMapper.update( cloudCustomer );
                            }
                        }
                        LOGGER.error( "----------转移操作0000000000-----------------" + new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( new Date() ) );
                    }
                    paramMap.clear();
                    paramMap.put( "customerId", Integer.parseInt( customerId ) );
                    LOGGER.error( "----------remindMapper start-----------------" + oldEntity );
                    List<CustomerRemindEntity> list = remindMapper.queryByConditions( paramMap );
                    LOGGER.error( "----------remindMapper end-----------------" + list.size() );
                    if (CollectionUtils.isNotEmpty( list )) {
                        for (CustomerRemindEntity entity : list) {
                            remindMapper.delete( entity.getId() );
                            entity.setCreateUserId( userId );
                            remindMapper.save( entity );
                        }
                    }
                    LOGGER.error( "----------转移操作000000000022222222-----------------" + new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ).format( new Date() ) );
                    try {
                        Thread.sleep( 100 );
                    } catch (Exception e) {
                        LOGGER.error( "转移客户中途失败", e );
                    }
                    i++;
                }
            }

            LOGGER.error( "***********最终结果返回值************:" + atomicInteger.get() );

            return atomicInteger.get();
        }
    }


    private synchronized Integer getFinishCount(String id) {
        return redisUtils.getIntegerByKey( "transfer:done:" + id );
    }

    private synchronized Integer getFinishCount2(String id) {
        return redisUtils.getIntegerByKey( "remove:done:" + id );
    }

    private synchronized Long increaseDoneKey(String id) {
        return redisUtils.increaseByKey( "transfer:done:" + id );
    }

    private synchronized Long increaseDoneKey2(String id) {
        return redisUtils.increaseByKey( "remove:done:" + id );
    }

    /**
     * 客户转移-处理合并客户最近回访时间
     *
     * @param currentCustomer
     * @param oldCustomerEntity
     * @return
     */
    private CustomerEntity handleCustomerMerge(CustomerEntity currentCustomer, CustomerEntity oldCustomerEntity) {
        //先去查询该客户的所有id
        List<CustomerEntity> customerIdList = getCustomerIds( currentCustomer.getId(), currentCustomer.getCityCode() );
        //再获取所有id的回访记录
        List<Integer> ids = new ArrayList<>();
        for (CustomerEntity entity : customerIdList) {
            ids.add( entity.getId() );
        }
        Map<String, Object> idsMap = new HashMap<>( 10 );
        idsMap.put( "ids", ids );
        if (ids.size() > 0) {
            List<CustomerCallbackLogEntity> callbacklist = getCallBackList( idsMap );
            if (callbacklist != null && callbacklist.size() > 0) {
                oldCustomerEntity.setLastCallTime( callbacklist.get( 0 ).getCreateTime() );
            }
        }
        return oldCustomerEntity;
    }

    /**
     * 非客户转移-处理合并最新回访时间
     *
     * @param currentCustomer
     * @return
     */
    private CustomerEntity handleCustomerMerge(CustomerEntity currentCustomer) {
        //先去查询该客户的所有id
        List<CustomerEntity> customerIdList = getCustomerIds( currentCustomer.getId(), currentCustomer.getCityCode() );
        //再获取所有id的回访记录
        List<Integer> ids = new ArrayList<>();
        for (CustomerEntity entity : customerIdList) {
            ids.add( entity.getId() );
        }
        Map<String, Object> idsMap = new HashMap<>( 10 );
        idsMap.put( "ids", ids );
        if (ids.size() > 0) {
            List<CustomerCallbackLogEntity> callbacklist = getCallBackList( idsMap );
            if (callbacklist != null && callbacklist.size() > 0) {
                currentCustomer.setLastCallTime( callbacklist.get( 0 ).getCreateTime() );
            }
        } else {
            currentCustomer.setLastCallTime( null );
        }
        return currentCustomer;
    }

    private void assignCustomer(String[] customerIds, Integer userId, Integer operId, UserEntity user, CustomerEntity customer, boolean isHandover, String type, String assignFrom) {
        if (customer.getManagerId() != null) {
            LOGGER.info( "user [{}] :transfer customers [{}] from [{}] to [{}]", operId,
                    Joiner.on( "," ).join( customerIds ), customer.getManagerId(), userId );
        } else {
            LOGGER.info( "user [{}] :customers [{}] bind user[{}]", operId, Joiner.on( "," ).join( customerIds ), userId );
        }
        Date newdate = new Date();
        Integer oldManagerId = customer.getManagerId();
        String oldManagerName = customer.getManagerName();
        String newManagerName = user.getRealName();
        String oldPhone = customer.getPhone();
        Map<String, Object> paramMap = new HashMap<>( 10 );
        //将原有客户安家顾问信息一并转移
        customer.setManagerId( userId );
        customer.setIsRecycled( 0 );
        customer.setManagerName( user.getRealName() );
        customer.setUpdateTime( newdate );
        customer.setUpdater( String.valueOf( operId ) );
        //重置客户绑定置业顾问时间
        customer.setBindTime( newdate );
        if (!isHandover) {
            customerService.update( customer );
        }
        if (isHandover && !userId.equals( oldManagerId )) {
            paramMap.put( "oldManagerId", oldManagerId );
            paramMap.put( "oldManagerName", oldManagerName );
            paramMap.put( "newManagerId", userId );
            paramMap.put( "newManagerName", newManagerName );
            paramMap.put( "phone", customer.getPhone() );
            paramMap.put( "isDelete", "0" );
            paramMap.put( "updater", operId );
            paramMap.put( "updateTime", newdate );
            paramMap.put( "bindTime", newdate );
            paramMap.put( "isHandover", 1 );
            customerMapper.transferManagerInfo( paramMap );
        }


        paramMap.clear();
        //转移后的安家顾问下此客户phone
        paramMap.put( "phone", customer.getPhone() );
        paramMap.put( "managerId", userId );
        CustomerEntity oldEntity = customermergemapper.getCustomerMerge( paramMap );
        UserEntity logUser = (UserEntity) userService.getById( operId );

        //客户转移
        if (isHandover && !userId.equals( oldManagerId )) {
            //客户转移:
            if (oldEntity == null) {
                handleCustomerMerge( customer );
                //此客户没有被当前被转移的安家顾问跟踪过，直接更新客户的安家顾问信息

                customermergemapper.updateCustomerMerge( customer );
            } else {
                //此客户被跟踪过,直接更新安家顾问对应的客户信息
                mergeCustomerUtil.checkMergeCustomer( customer, oldEntity, operId, logUser.getRealName() );
                // 意向等级、跟踪状态更新
                oldEntity.setUpdateTime( newdate );
                oldEntity.setUpdater( String.valueOf( operId ) );
                oldEntity.setCreateTime( customer.getCreateTime() );
                oldEntity.setBindTime( newdate );
                oldEntity.setManagerId( userId );
                oldEntity.setIsRecycled( 0 );
                oldEntity.setIsHandover( 1 );
                oldEntity.setManagerName( user.getRealName() );
                //转移判断旧的客户是否有回访记录，有则变更活跃状态，无则不变
                paramMap.clear();
                paramMap.put( "phone", oldPhone );
                paramMap.put( "cityCode", customer.getCityCode() );
                paramMap.put( "managerId", customer.getManagerId() );
                paramMap.put( "isPrivate", 1 );
                List<CustomerEntity> list = customerMapper.queryByConditions( paramMap );
                List<Integer> idList = new ArrayList<>();
                if (CollectionUtils.isNotEmpty( list )) {
                    for (CustomerEntity c : list) {
                        idList.add( c.getId() );
                    }
                    paramMap.clear();
                    paramMap.put( "idList", idList );
                    List<CustomerCallbackLogEntity> backList = callbackMapper.queryByConditions( paramMap );
                    if (CollectionUtils.isNotEmpty( backList )) {
                        oldEntity.setIsActive( 0 );
                    }
                }
                //将客户标签一并合并给新的安家顾问名下该客户
                paramMap.put( "oldManagerId", oldManagerId );
                paramMap.put( "customerId", customer.getId() );
                paramMap.put( "newCustomerId", oldEntity.getId() );
                labelmapper.updateCustomerId( paramMap );
                //合并客户信息更新
                Date oldlastCallTime = oldEntity.getLastCallTime();
                Date currrentCallTime = customer.getLastCallTime();

                if ((oldlastCallTime == null) || (currrentCallTime != null && oldlastCallTime.before( currrentCallTime ))) {
                    oldEntity.setLastCallTime( currrentCallTime );
                }
                handleCustomerMerge( customer, oldEntity );
                //合并客户
                customermergemapper.updateCustomerMerge( oldEntity );
                //将被转移的客户删除:物理删除
                customermergemapper.deleteSingleCustomerMerge( customer );
            }
        } else {
            //公海派工:待回访和400未跟踪的客户暂不处理;其余合并
            if ((customer.getIsWaitCall() == null || customer.getIsWaitCall() == 0) && customer.getStatus() != 98) {
                //如果是客户转移
                Map<String, Object> map2 = new HashMap<>( 10 );
                map2.put( "phone", customer.getPhone() );
                map2.put( "managerId", userId );
                CustomerEntity entity = customermergemapper.getCustomerMerge( map2 );
                if (entity == null) {
                    handleCustomerMerge( customer );
                    //此客户没有被当前的安家顾问跟踪过
                    customermergemapper.saveCustomerMerge( customer );
                    //公海客户查询
                    List<CustomerEntity> seaCustomers = getSeaCustomerByPhone( customer, user );
                    //公海派工、待回访派工,将原有属于该安家顾问名下的公海客户全派工 ,
                    if (seaCustomers != null && seaCustomers.size() > 0) {
                        updateSeaCustomerByPhone( customer, user );
                    }
                } else {
                    handleCustomerMerge( customer, entity );
                    //此客户被当前被转移的安家顾问跟踪过,直接此安家顾问对应的客户信息
                    mergeCustomerUtil.checkMergeCustomer( customer, oldEntity, operId, logUser.getRealName() );
                    // 意向等级、跟踪状态更新
                    oldEntity.setUpdateTime( newdate );
                    oldEntity.setCreateTime( customer.getCreateTime() );
                    oldEntity.setUpdater( String.valueOf( operId ) );
                    oldEntity.setBindTime( newdate );
                    //转移判断旧的客户是否有回访记录，有则变更活跃状态，无则不变
                    Map<String, Object> searchMap = new HashMap<>( 10 );
                    searchMap.put( "phone", oldPhone );
                    searchMap.put( "cityCode", customer.getCityCode() );
                    searchMap.put( "managerId", customer.getManagerId() );
                    searchMap.put( "isPrivate", 1 );
                    List<CustomerEntity> list = customerMapper.queryByConditions( searchMap );
                    List<Integer> idList = new ArrayList<>();
                    if (CollectionUtils.isNotEmpty( list )) {
                        for (CustomerEntity c : list) {
                            idList.add( c.getId() );
                        }
                        Map<String, Object> callBackMap = new HashMap<>( 10 );
                        callBackMap.put( "idList", idList );
                        List<CustomerCallbackLogEntity> backList = callbackMapper.queryByConditions( callBackMap );
                        if (CollectionUtils.isNotEmpty( backList )) {
                            oldEntity.setIsActive( 0 );
                            oldEntity.setIsHandover( 0 );
                        }
                    }
                    customermergemapper.updateCustomerMerge( oldEntity );
                }
            }
        }
        //添加客户操作日志
        int paramType;
        if (isHandover) {
            //客户转移 (同时要更新转移客户日志中安家顾问id)
            paramMap.clear();
            paramMap.put( "phone", customer.getPhone() );
            paramMap.put( "oldManagerId", oldManagerId );
            paramMap.put( "managerId", userId );
            customerLogMapper.updateManagerId( paramMap );
            paramType = 7;
        } else {
            if ("daihuifang".equals( type )) {
                paramType = 4;
            } else {
                paramType = 5;
            }
        }
        //添加客户操作日志
        logUtils.saveCustomerLog( customer, paramType, operId, logUser.getRealName() );

        // 如果当前客户是营销活动来的,需要更新market_customer表的派工时间和置业顾问
        if (HGSConstant.CustomerSourceType.MARKET.getType().equals( customer.getCustomerSourceType() )) {
            MarketCustomerEntity marketUser = marketCustomerService.queryByCustomerid( customer.getId() );
            if (marketUser != null) {
                marketUser.setManagerId( userId );
                marketUser.setManagerName( user.getRealName() );
                marketUser.setBindTime( customer.getBindTime() );
                marketUser.setUpdateTime( new Date() );
                marketUser.setUpdater( String.valueOf( operId ) );
                marketCustomerService.update( marketUser );
            }
        }
        //如果当前客户是云迹客户，需要更新cloud_customer 派工时间和置业顾问
        if (customer.getCustomerSourceType() == 7) {
            paramMap.clear();
            if ("cloud".equals( type )) {
                paramMap.put( "customerId", Integer.valueOf( assignFrom ) );
            } else {
                paramMap.put( "customerId", customer.getId() );
            }
            List<CloudCustomerEntity> list = cloudCustomerMapper.queryByConditions( paramMap );
            if (CollectionUtils.isNotEmpty( list )) {
                CloudCustomerEntity cloudCustomer = list.get( 0 );
                cloudCustomer.setManagerId( userId );
                cloudCustomer.setManagerName( user.getRealName() );
                cloudCustomer.setBindTime( customer.getBindTime() );
                cloudCustomer.setUpdateTime( new Date() );
                cloudCustomer.setUpdater( String.valueOf( operId ) );
                cloudCustomerMapper.update( cloudCustomer );
            }
        }
        Map<String, String> param = new HashMap<>();
        param.put( "customerId", String.valueOf( customer.getId() ) );
        customerService.sendMessageToWechat( NEWCUSTOMER, String.valueOf( user.getId() ), param );
    }

    /**
     * 云迹客户转派
     *
     * @param customerIds 改派的客户id数组
     * @param userId      改派后的用户id
     * @param operId      操作人id
     * @param user        改派后用户信息
     * @param customer    改派客户
     * @param assignFrom  改派云迹客户的customerId
     */
    private void assignCloudCustomer(String[] customerIds, Integer userId, Integer operId, UserEntity user, CustomerEntity customer, String assignFrom) {
        if (customer.getManagerId() != null) {
            LOGGER.info( "user [{}] :transfer customers [{}] from [{}] to [{}]", operId,
                    Joiner.on( "," ).join( customerIds ), customer.getManagerId(), userId );
        } else {
            LOGGER.info( "user [{}] :customers [{}] bind user[{}]", operId, Joiner.on( "," ).join( customerIds ), userId );
        }
        Date newDate = new Date();
        Integer oldManagerId = customer.getManagerId();
        String oldManagerName = customer.getManagerName();
        String newManagerName = user.getRealName();
        String oldPhone = customer.getPhone();

        Map<String, Object> paramMap = new HashMap<>( 10 );
        paramMap.put( "oldManagerId", oldManagerId );
        paramMap.put( "oldManagerName", oldManagerName );
        paramMap.put( "newManagerId", userId );
        paramMap.put( "newManagerName", newManagerName );
        paramMap.put( "phone", customer.getPhone() );
        paramMap.put( "isDelete", "0" );
        paramMap.put( "updater", operId );
        paramMap.put( "updateTime", newDate );
        paramMap.put( "isHandover", 1 );
        customer.setIsHandover( 1 );
        customerMapper.transferManagerInfo( paramMap );

        //转移后的安家顾问下此客户phone
        Map<String, Object> map = new HashMap<>( 10 );
        map.put( "phone", customer.getPhone() );
        map.put( "managerId", userId );
        CustomerEntity oldEntity = customermergemapper.getCustomerMerge( map );
        UserEntity logUser = (UserEntity) userService.getById( operId );

        CustomerEntity customerEntity = customerMapper.queryById( customer.getId() );
        //客户改派 类似于转移
        if (oldEntity == null) {
            handleCustomerMerge( customerEntity );
            //此客户没有被当前被转移的安家顾问跟踪过，直接更新客户的安家顾问信息
            customermergemapper.updateCustomerMerge( customerEntity );
        } else {
            //此客户被跟踪过,直接更新安家顾问对应的客户信息
            mergeCustomerUtil.checkMergeCustomer( customerEntity, oldEntity, operId, logUser.getRealName() );
            // 意向等级、跟踪状态更新
            oldEntity.setUpdateTime( newDate );
            oldEntity.setUpdater( String.valueOf( operId ) );
            oldEntity.setCreateTime( customer.getCreateTime() );
            oldEntity.setBindTime( newDate );
            oldEntity.setManagerId( userId );
            oldEntity.setIsRecycled( 0 );
            oldEntity.setIsHandover( 1 );
            oldEntity.setManagerName( user.getRealName() );
            //转移判断旧的客户是否有回访记录，有则变更活跃状态，无则不变
            Map<String, Object> searchMap = new HashMap<>( 10 );
            searchMap.put( "phone", oldPhone );
            searchMap.put( "cityCode", customer.getCityCode() );
            searchMap.put( "managerId", customer.getManagerId() );
            searchMap.put( "isPrivate", 1 );
            List<CustomerEntity> list = customerMapper.queryByConditions( searchMap );
            List<Integer> idList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty( list )) {
                for (CustomerEntity c : list) {
                    idList.add( c.getId() );
                }
                Map<String, Object> callBackMap = new HashMap<>( 10 );
                callBackMap.put( "idList", idList );
                List<CustomerCallbackLogEntity> backList = callbackMapper.queryByConditions( callBackMap );
                if (CollectionUtils.isNotEmpty( backList )) {
                    oldEntity.setIsActive( 0 );
                }
            }
            //将客户标签一并合并给新的安家顾问名下该客户
            Map<String, Object> labelMap = new HashMap<>( 10 );
            labelMap.put( "oldManagerId", oldManagerId );
            labelMap.put( "customerId", customerEntity.getId() );
            labelMap.put( "newCustomerId", oldEntity.getId() );
            labelmapper.updateCustomerId( labelMap );
            //合并客户信息更新
            Date oldlastCallTime = oldEntity.getLastCallTime();
            Date currrentCallTime = customerEntity.getLastCallTime();
            if (currrentCallTime != null && oldlastCallTime.before( currrentCallTime )) {
                oldEntity.setLastCallTime( currrentCallTime );
            }
            handleCustomerMerge( customerEntity, oldEntity );
            //合并客户
            customermergemapper.updateCustomerMerge( oldEntity );
            //将被转移的客户删除:物理删除 （过滤派给当前人的情况）
            customermergemapper.deleteSingleCustomerMerge( customer );

        }

        //客户转移 (同时要更新转移客户日志中安家顾问id)
        Map<String, Object> updateMap = new HashMap<>( 10 );
        updateMap.put( "phone", customerEntity.getPhone() );
        updateMap.put( "oldManagerId", oldManagerId );
        updateMap.put( "managerId", userId );
        customerLogMapper.updateManagerId( updateMap );

        //添加客户操作日志
        logUtils.saveCustomerLog( customerEntity, 9, operId, logUser.getRealName() );

        //更新云迹客户信息
        Map<String, Object> queryMap = new HashMap<>( 5 );
        queryMap.put( "customerId", Integer.valueOf( assignFrom ) );
        List<CloudCustomerEntity> list = cloudCustomerMapper.queryByConditions( queryMap );
        if (CollectionUtils.isNotEmpty( list )) {
            CloudCustomerEntity cloudCustomer = list.get( 0 );
            cloudCustomer.setManagerId( userId );
            cloudCustomer.setManagerName( user.getRealName() );
            cloudCustomer.setBindTime( customer.getBindTime() );
            cloudCustomer.setUpdateTime( new Date() );
            cloudCustomer.setUpdater( String.valueOf( operId ) );
            cloudCustomerMapper.update( cloudCustomer );
        }

        Map<String, String> param = new HashMap<>( 10 );
        param.put( "customerId", String.valueOf( customer.getId() ) );
        customerService.sendMessageToWechat( NEWCUSTOMER, String.valueOf( user.getId() ), param );
    }

    //平均派工
    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void bindUser(String customerIds, String userId, Integer operId, String userName, int type) throws Exception {
        if (!Strings.isNullOrEmpty( customerIds ) && !Strings.isNullOrEmpty( userId )) {
            int size = 1;
            List<String> useridSplit = new ArrayList<>();
            if (userId.contains( "," )) {
                useridSplit.addAll( Sets.newHashSet( userId.split( "," ) ) );
                size = useridSplit.size();
            }

            if (CollectionUtils.isNotEmpty( useridSplit )) {
                customerIds = Joiner.on( "," ).join( Sets.newHashSet( customerIds.split( "," ) ) );
                List<MarketCustomerEntity> customerList = marketCustomerService.queryByIds( customerIds );
                //if user size bigger than customer size, maybe someone can not get customer
                int i = 1;
                //校验私客不能被改派
                for (MarketCustomerEntity mcustomer : customerList) {
                    if (null != mcustomer.getCustomerId()) {
                        CustomerEntity customer = customerService.getById( mcustomer.getCustomerId() );
                        if (customer.getManagerId() != null && customer.getIsWaitCall() != 1 && customer.getIsDelete() == 0) {
                            throw new ServiceException( "手机号为" + customer.getPhone() + "的客户已被" + customer.getManagerName() + "跟进,不能改派,请剔除后重新选择改派" );
                        }
                    }
                }
                for (MarketCustomerEntity mcustomer : customerList) {
                    MarketingActivityEntity activityEntity = (MarketingActivityEntity) marketingActivityService.getById(
                            mcustomer.getActiveId() );

                    if (activityEntity.getFinishTime().before( new Date() )) {
                        throw new ServiceException( "活动已结束!" );
                    }

                    Integer uid = Integer.valueOf( useridSplit.get( i % size ) );
                    UserEntity user = (UserEntity) userService.getById( uid );
                    if (null != user) {
                        Integer id = null;
                        CustomerEntity customer = null;
                        if (null != mcustomer.getCustomerId()) {
                            customer = customerService.getById( mcustomer.getCustomerId() );

                            id = mcustomer.getCustomerId();
                        } else {
                            customer = mcustomer.convertCustomer();
                        }
                        int oldManagerId = -10;
                        if (customer.getManagerId() != null) {
                            oldManagerId = customer.getManagerId();
                        }
                        Integer sourceId = null;
                        String key = "actSourceId_" + mcustomer.getActSource();
                        if (redisUtils.hasKey( key )) {
                            sourceId = redisUtils.getIntegerByKey( key );
                        } else {
                            //更新来源
                            sourceId = customerSourceService.updateSource( mcustomer.getCityCode(),
                                    mcustomer.getActSource(),
                                    mcustomer.getCreateSource(), "CRM" );
                            redisUtils.addKeyVal( key, String.valueOf( sourceId ) );
                        }
                        customer.setActSourceId( sourceId );
                        customer.setActSource( mcustomer.getActSource() );
                        customer.setSingupTime( mcustomer.getSignupTime() );
                        customer.setCustomerSourceType( HGSConstant.CustomerSourceType.MARKET.getType() );
                        customer.setManagerId( uid );
                        customer.setIsRecycled( 0 );
                        customer.setManagerName( user.getRealName() );
                        customer.setUpdateTime( new Date() );
                        customer.setUpdater( String.valueOf( operId ) );
                        //数据公海中客户购房意向为“无效”的客户，如果被派工后，统一提升客户的“购房意向”为：待定
                        customer.setBuyIntention( mcustomer.getBuyIntention() );
                        customer.setIsDelete( 0 );
                        customer.setLatestSource( Strings.isNullOrEmpty(
                                mcustomer.getSignupSourceName() ) ? "" : mcustomer.getSignupSourceName() );
                        customer.setBakPhone1( Strings.isNullOrEmpty(
                                mcustomer.getSignupHouseName() ) ? "" : mcustomer.getSignupHouseName() );
                        //重置客户绑定置业顾问时间
                        customer.setBindTime( new Date() );
                        customer.setIsWaitCall( 1 );
                        customer.setMarketActId( activityEntity.getId() );
                        customer.setMarketActName( activityEntity.getName() );
                        if (null != mcustomer.getCustomerId()) {
                            customerService.update( customer );
                        } else {
                            id = customerService.save( customer );
                        }
                        //改派需要将新表原有数据删除
                        customermergemapper.deleteSingleCustomerMerge( customer );
                        //如果是营销活动改派，需要更新客户日志表managerId
                        if (oldManagerId > 0) {
                            Map<String, Object> updateMap = new HashMap<>( 10 );
                            updateMap.put( "phone", customer.getPhone() );
                            updateMap.put( "oldManagerId", oldManagerId );
                            updateMap.put( "managerId", uid );
                            customerLogMapper.updateManagerId( updateMap );
                        }
                        //记录客户派工日志（营销活动派工）
                        logUtils.saveCustomerLog( customer, type, operId, userName );
                        Map<String, String> param = new HashMap<>( 10 );
                        param.put( "customerId", String.valueOf( id ) );
                        customerService.sendMessageToWechat( NEWCUSTOMER, String.valueOf( user.getId() ), param );

                        mcustomer.setManagerId( uid );
                        mcustomer.setManagerName( user.getRealName() );
                        mcustomer.setUpdateTime( customer.getBindTime() );
                        mcustomer.setUpdater( String.valueOf( operId ) );
                        //数据公海中客户购房意向为“无效”的客户，如果被派工后，统一提升客户的“购房意向”为：待定
                        //重置客户绑定置业顾问时间
                        mcustomer.setBindTime( customer.getBindTime() );
                        mcustomer.setCustomerId( id );
                        mcustomer.setStatus( 1 );
                        marketCustomerService.update( mcustomer );

                        hgsCacheUtil.delUserSummary( uid );
                        i++;
                    }
                }
            }
        }
    }


    /**
     * 云迹活动客户派工
     *
     * @param customerIds 派工客户的id集合
     * @param userId      派工的人的id
     * @param operId      操作人id
     * @param userName    操作人姓名
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void bindCloudUser(String customerIds, String userId, Integer operId, String userName, int type) throws Exception {
        if (!Strings.isNullOrEmpty( customerIds ) && !Strings.isNullOrEmpty( userId )) {
            int size = 1;
            Date date = new Date();
            List<String> userIdSplit = new ArrayList<>();
            if (userId.contains( "," )) {
                userIdSplit.addAll( Sets.newHashSet( userId.split( "," ) ) );
                size = userIdSplit.size();
            }
            List<Integer> idList = new ArrayList<>();
            if (customerIds.contains( "," )) {
                String[] idArrays = customerIds.split( "," );
                for (String s : idArrays) {
                    idList.add( Integer.valueOf( s ) );
                }
            } else {
                idList.add( Integer.valueOf( customerIds ) );
            }

            if (CollectionUtils.isNotEmpty( userIdSplit )) {
                Map<String, Object> searchMap = new HashMap<>( 10 );
                searchMap.put( "idList", idList );
                List<CloudCustomerEntity> customerList = cloudCustomerMapper.queryByConditions( searchMap );
                int i = 1;
                CloudActivityEntity activityEntity = activityMapper.getById( customerList.get( 0 ).getActiveId() );
                for (CloudCustomerEntity cloudCustomer : customerList) {
                    Integer uid = Integer.valueOf( userIdSplit.get( i % size ) );
                    UserEntity user = (UserEntity) userService.getById( uid );
                    if (null != user) {
                        //判断是改派还是直接派工
                        CustomerEntity customer;
                        Integer id;
                        if (cloudCustomer.getCustomerId() == 0) {
                            customer = cloudCustomer.convertCustomer();

                            customer.setActSourceId( cloudCustomer.getActSourceId() );
                            customer.setActSource( cloudCustomer.getActSource() );
                            customer.setSingupTime( cloudCustomer.getSignupTime() );
                            //设置type 为云迹活动派工
                            customer.setCustomerSourceType( 7 );
                            customer.setManagerId( uid );
                            customer.setIsRecycled( 0 );
                            customer.setManagerName( user.getRealName() );
                            customer.setUpdateTime( date );
                            customer.setUpdater( String.valueOf( operId ) );
                            //数据公海中客户购房意向为“无效”的客户，如果被派工后，统一提升客户的“购房意向”为：待定
                            customer.setBuyIntention( cloudCustomer.getBuyIntention() );
                            customer.setIsDelete( 0 );
                            customer.setLatestSource( Strings.isNullOrEmpty(
                                    cloudCustomer.getLatestSource() ) ? "" : cloudCustomer.getLatestSource() );
                            customer.setBakPhone1( cloudCustomer.getBakPhone1() );
                            //重置客户绑定置业顾问时间
                            customer.setBindTime( date );
                            customer.setIsWaitCall( 0 );
                            customer.setMarketActId( activityEntity.getId() );
                            customer.setMarketActName( activityEntity.getName() );
                            customer.setLastCallTime( date );

                            id = customerService.save( customer );

                            Map<String, Object> map1 = new HashMap<>( 5 );
                            map1.put( "phone", cloudCustomer.getPhone() );
                            map1.put( "managerId", uid );
                            List<CustomerEntity> mergeList = customermergemapper.queryByConditions( map1 );
                            //判断走合并还是直接新增
                            if (CollectionUtils.isNotEmpty( mergeList )) {
                                CustomerEntity mergeEntity = mergeList.get( 0 );
                                mergeCustomerUtil.checkMergeCustomer( customer, mergeEntity, operId, userName );
                                // 意向等级、跟踪状态更新
                                mergeEntity.setUpdateTime( date );
                                mergeEntity.setBindTime( date );
                                mergeEntity.setUpdater( String.valueOf( user.getId() ) );
                                mergeEntity.setIsHandover( mergeEntity.getIsHandover() );
                                customermergemapper.updateCustomerMerge( mergeEntity );
                            } else {
                                customer.setId( id );
                                customermergemapper.saveCustomerMerge( customer );
                            }
                            //添加默认回访
                            CustomerCallbackLogEntity logEntity = new CustomerCallbackLogEntity();
                            logEntity.setCustomerId( id );
                            logEntity.setManagerId( 0 );
                            logEntity.setManagerName( "云迹" );
                            logEntity.setContent( "云迹备注:" + cloudCustomer.getSignupHouseName() );
                            logEntity.setResult( "" );
                            logEntity.setCreateTime( date );
                            logEntity.setCreater( "云迹" );
                            callbackMapper.saveCallBackLog( logEntity );

                            //记录客户派工日志（云迹活动派工）
                            logUtils.saveCustomerLog( customer, type, operId, userName );
                            Map<String, String> param = new HashMap<>( 10 );
                            param.put( "customerId", String.valueOf( id ) );
                            customerService.sendMessageToWechat( NEWCUSTOMER, String.valueOf( user.getId() ), param );
                            cloudCustomer.setManagerId( uid );
                            cloudCustomer.setManagerName( user.getRealName() );
                            cloudCustomer.setUpdateTime( customer.getBindTime() );
                            cloudCustomer.setUpdater( String.valueOf( operId ) );
                            //重置客户绑定置业顾问时间
                            cloudCustomer.setBindTime( customer.getBindTime() );
                            cloudCustomer.setCustomerId( id );
                            cloudCustomer.setStatus( 1 );
                            cloudCustomerMapper.update( cloudCustomer );

                            hgsCacheUtil.delUserSummary( uid );
                            i++;

                        } else {
                            customer = customerService.getById( cloudCustomer.getCustomerId() );
                            //判断如果转派后的人等同于当前顾问，不做变动 已经回公海的客户不做变动
                            if (customer.getManagerId() != null && !customer.getManagerId().equals( uid )) {
                                String assignForm = cloudCustomer.getCustomerId().toString();
                                Map<String, Object> map1 = new HashMap<>( 5 );
                                map1.put( "phone", cloudCustomer.getPhone() );
                                map1.put( "managerId", cloudCustomer.getManagerId() );
                                List<CustomerEntity> mergeList = customermergemapper.queryByConditions( map1 );
                                if (!mergeList.get( 0 ).getId().equals( customer.getId() )) {
                                    customer.setId( mergeList.get( 0 ).getId() );
                                    customer.setBuyIntention( mergeList.get( 0 ).getBuyIntention() );
                                }
                                String[] idArrays = customerIds.split( "," );
                                //云迹活动改派，区别于营销活动改派，类似客户转移
                                assignCloudCustomer( idArrays, uid, operId, user, customer, assignForm );
                                //判断如果有回访提醒，需要切换提醒人员
                                Map<String, Object> map = new HashMap<>( 10 );
                                map.put( "customerId", cloudCustomer.getCustomerId() );
                                List<CustomerRemindEntity> list = remindMapper.queryByConditions( map );
                                if (CollectionUtils.isNotEmpty( list )) {
                                    for (CustomerRemindEntity entity : list) {
                                        remindMapper.delete( entity.getId() );
                                        entity.setCreateUserId( uid );
                                        remindMapper.save( entity );
                                    }
                                }
                                i++;
                            }
                        }
                    }
                }
                int count = i - 1;
                activityEntity.setSentCount( activityEntity.getSentCount() + count );
                activityEntity.setWaitCount( activityEntity.getWaitCount() - count );
                activityMapper.updateCount( activityEntity );
            }
        }
    }

    /**
     * 项目转移
     *
     * @param projectId
     * @param customerId
     * @param creater
     * @throws Exception
     */
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    @Override
    public String bindTurnProject(String projectId, String customerId, int operId, String creater, String oldProjectId) throws Exception {
//        String[] projectIds = projectId.split(",");
        projectId = projectId.substring( 0, projectId.length() - 1 );
        String[] customerIds = customerId.split( "," );
        Map<Integer, ProjectEntity> projectEntityMap = new HashMap<>( 10 );
        String msg = "";
        boolean exsits = false;
        ProjectEntity pe = projectMapper.queryNameById( Integer.valueOf( projectId ) );
        ProjectEntity pe2 = projectMapper.queryNameById( Integer.valueOf( oldProjectId ) );
        for (String cId : customerIds) {
            if (Strings.isNullOrEmpty( cId )) {
                continue;
            }
            CustomerEntity customerEntity = customerService.getById( Integer.valueOf( cId ) );
            if (customerEntity != null) {
                //转移项目是否存在同一号码
                List<CustomerProjectEntity> phones = customerProjectMapper.getPhonesById( projectId );
                for (CustomerProjectEntity cpe : phones) {
                    if (customerEntity.getPhone().equals( cpe.getCustomerPhone() )) {
                        msg += cpe.getCustomerPhone() + ",";
                        exsits = true;
                    }
                }
            }
        }
        if (exsits) {
            msg = msg.substring( 0, msg.length() - 1 );
            msg = "[" + msg + "]";
            return msg;
        }
        for (String cId : customerIds) {
            CustomerEntity customerEntity = customerService.getById( Integer.valueOf( cId ) );
            //不存在继续转移
            Map<String, String> paramMap = new HashMap<>();
            paramMap.put( "oldPid", oldProjectId );
            paramMap.put( "newPid", projectId );
            paramMap.put( "customerId", cId );
            paramMap.put( "newProjectName", pe.getProjectName() );

            paramMap.put( "newContract", pe.getContractCode() );
            paramMap.put( "newHouseName", pe.getBuildingName() );
            customerProjectMapper.updateOldPid2NewPid( paramMap );
            //更新客户项目状态信息
            customerStatusLogMapper.updateNewProjectId( paramMap );
            //记录转移日志
            logUtils.saveCustomerLog2( customerEntity, 10, operId, creater, pe2.getProjectName(), pe.getProjectName() );
        }
        return "1";
    }


    /**
     * 约看楼盘
     *
     * @param projectId
     * @param customerId
     * @param creater
     * @throws Exception
     */
    @Override
    public void bindProject(String projectId, String customerId, String creater) throws Exception {
        String[] projectIds = projectId.split( "," );
        String[] customerIds = customerId.split( "," );
        Map<Integer, ProjectEntity> projectEntityMap = new HashMap<>( 10 );
        for (String customer : customerIds) {
            if (Strings.isNullOrEmpty( customer )) {
                continue;
            }
            CustomerEntity customerEntity = customerService.getById( Integer.valueOf( customer ) );
            if (customerEntity != null) {
                for (String pid : projectIds) {
                    if (Strings.isNullOrEmpty( pid )) {
                        continue;
                    }

                    CustomerProjectEntity cp = new CustomerProjectEntity();
                    Map<String, Object> checkExsitSearchMap = new HashMap<>( 10 );
                    checkExsitSearchMap.put( "EQ_customerId", customerEntity.getId() );
                    checkExsitSearchMap.put( "EQ_projectId", pid );
                    QueryParams checkExsit = new QueryParams( checkExsitSearchMap );
                    int exsitCount = customerProjectService.getTotalCount( checkExsit );
                    if (exsitCount > 0) {
                        continue;
                    }

                    //cache project
                    ProjectEntity project = new ProjectEntity();
                    if (!projectEntityMap.containsKey( pid )) {
                        project = (ProjectEntity) projectService.getById( Integer.valueOf( pid ) );
                        if (project != null && null != project.getId()) {
                            projectEntityMap.put( project.getId(), project );
                        } else {
                            continue;
                        }
                    } else {
                        project = projectEntityMap.get( pid );
                    }

                    //有到访认筹认购签约状态，标记为重客
                    int repeatCount = customerProjectService.checkRepeat( customerEntity.getPhone(), pid );

                    cp.setCreateTime( new Date() );
                    cp.setCreater( creater );
                    cp.setStatus( Constant.CustomerStatusEnum.RECORDED.getStatus() );
                    cp.setRecordedTime( new Date() );
                    cp.setLastChangeStatusTime( new Date() );
                    cp.setContract( project.getContractCode() );
                    cp.setCustomerId( customerEntity.getId() );
                    cp.setCustomerPhone( customerEntity.getPhone() );
                    cp.setHouseName( project.getBuildingName() );
                    cp.setProjectName( project.getProjectName() );
                    cp.setProjectId( project.getId() );
                    if (repeatCount > 0) {
                        cp.setIsRepeat( 1 );
                    } else {
                        cp.setIsRepeat( 0 );
                    }
                    cp.setProjectId( project.getId() );

                    String remark = "楼盘约看";
                    if (repeatCount > 0) {
                        remark += "【" + DateTimeUtils.getCurrentDateString() + "】【重客】";
                    }
                    customerStatusLogService.addStatusLogWithProject( customerEntity.getId(), null,
                            Constant.CustomerStatusEnum.RECORDED.getStatus(),
                            remark, creater, null, project.getId(), cp.getIsRepeat(),
                            1 );

                    final Integer cpid = customerProjectService.save( cp );

                    final CustomerEntity customerEntity1 = customerEntity;
                    final ProjectEntity projectEntity = project;
                    final CustomerProjectEntity cpe = cp;

                    final List<String> mobiles = userService.getMobilesByProject( project.getId() );

                    // 配置文件
                    final String url = MemoryPropertyPlaceholderConfigurer.getContextProperty(
                            "system.customer.noticeUrl" );
                    final String date = DateTimeUtils.getDateString( new Date(),
                            DateTimeUtils.DEFAULT_DATE_FORMAT_PATTERN_SHORT );
                    final String smsMsg = "您好！客户[" + customerEntity.getName() + "] [" + customerEntity.getPhone() + "]在[" + date + "]被置业顾问[" + customerEntity.getManagerName() + "]约看,约看至[" + projectEntity.getProjectName() + "]，请核对!";
                    final String paras = "@1@::[" + com.house365.web.util.StringUtils.StringFilter(
                            customerEntity.getName() ) + "]||@2@::[" + customerEntity.getPhone() + "]||@3@::[" + date + "]||@4@::[" + customerEntity.getManagerName() + "]||@5@::[" + projectEntity.getProjectName() + "]";
                    final String city = projectEntity.getCity();

                    ExecutorService executor = Executors.newCachedThreadPool();
                    executor.execute( new Runnable() {
                        @Override
                        public void run() {
                            try {
                                for (String mobile : mobiles) {
                                    SmsUtils.hgsCustomerRecordSendSms( city, mobile, smsMsg, paras, url );
                                }

                                String result = customerProjectService.postToCRM( cpe, new Date(), projectEntity,
                                        customerEntity1 );
                                LOGGER.info( "call CRM change customer status result:{}", result );


                            } catch (java.io.IOException e) {
                                LOGGER.error( "call CRM ERROR:" + e.getMessage(), e );
                            }
                        }
                    } );

                    //send wechat msg
                    executor.execute( new Runnable() {
                        @Override
                        public void run() {
                            try {
                                final List<String> ids = userService.getIdsByProject( projectEntity.getId() );
                                Map<String, String> param = new HashMap<>();
                                param.put( "customerId", String.valueOf( customerEntity1.getId() ) );
                                param.put( "projectName", projectEntity.getProjectName() );
                                param.put( "customerName", customerEntity1.getName() );
                                param.put( "customerPhone", customerEntity1.getPhone() );
                                param.put( "managerName", customerEntity1.getManagerName() );
                                param.put( "customerProjectId", String.valueOf( cpid ) );
                                customerService.sendMessageToWechat( NEWRECORDCUSTOMER, Joiner.on( "|" ).join( ids ), param );

                            } catch (Exception e) {
                                LOGGER.error( "call CRM ERROR:" + e.getMessage(), e );
                            }
                        }
                    } );

                }
            }
        }

    }

    /**
     * 将客户移到公海
     *
     * @param customerId
     * @param userId
     */
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    @Override
    public void removeCustomer(Integer customerId, Integer userId) throws Exception {
        customerService.removeCustomer( customerId, userId, false );
        CustomerEntity customer = customerService.getById( customerId );
        if (customer != null) {
            Map<String, Object> map = new HashMap<>( 5 );
            map.put( "customerId", customer.getId() );
            remindMapper.updateStatus( map );
        }
    }

    /**
     * 批量转移客户到公海
     *
     * @param customerIds
     * @param userId
     * @throws Exception
     */
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    @Override
    public void batchRemoveCustomer(String customerIds, Integer userId, String userName) throws Exception {
        customerService.batchRemoveCustomer( customerIds, userId, userName );
        //移出公海时判断是否有回访提醒记录,有则删除记录
        String[] arrCustomerId = org.apache.commons.lang3.StringUtils.split( customerIds, "," );
        for (String strCustomerId : arrCustomerId) {
            Integer customerId = Integer.valueOf( strCustomerId );
            CustomerEntity customer = customerService.getById( customerId );
            if (customer != null) {
                Map<String, Object> map = new HashMap<>( 5 );
                map.put( "customerId", customer.getId() );
                remindMapper.updateStatus( map );
            }
        }

    }

    /**
     * hqc
     */
    @Override
    public void removeUserCustomer(Integer delUserId, Integer userId) {
        QueryParams<CustomerEntity> queryParams = new QueryParams<>();
        queryParams.setPaging( new Page( Integer.MAX_VALUE ) );
        Map<String, Object> map = new HashMap<>( 10 );
        map.put( "EQ_managerId", delUserId );
        queryParams.setSearchParams( map );
        List<CustomerEntity> queryAll = customerService.queryAll( queryParams );
        for (CustomerEntity customerEntity : queryAll) {
            try {
                removeCustomer( customerEntity.getId(), userId );
            } catch (Exception e) {
                LOGGER.error( e.getMessage(), e );
            }
        }
    }

    @Override
    public String getCRMViewURL(String city, String phone) {
        String url = "";
        if (!Strings.isNullOrEmpty( city ) && !Strings.isNullOrEmpty( phone )) {
            Date date = new Date();
            String crmUrl = MemoryPropertyPlaceholderConfigurer.getContextProperty( "CRM.CUSTOMER.INFO.URL" );
            List<NameValuePair> pairs = new ArrayList<>();
            pairs.add( new BasicNameValuePair( "city", city ) );
            pairs.add( new BasicNameValuePair( "memphone", phone ) );
            LOGGER.info( "getCRMCustomerURL :city {},memphone:{}", city, phone );
            crmUrl += "&signature=" + MD5(
                    "" + (date.getTime() / 1000) + "hgs" ) + "&timestamp=" + (date.getTime() / 1000);
            try {
                URLEncoder.encode( crmUrl, "utf8" );
                String res = HttpClientUtil.doPostWithCharset( crmUrl, pairs, "utf8", "utf8" );

                JSONObject jsonObject = new JSONObject();
                if (StringUtils.isNotBlank( res )) {
                    jsonObject = JSONObject.fromObject( res );
                    if (jsonObject.get( "data" ) != null && "1".equalsIgnoreCase(
                            String.valueOf( jsonObject.get( "result" ) ) )) {
                        url = String.valueOf( jsonObject.get( "data" ) );
                    }
                }

                LOGGER.info( "getCRMCustomerURL :{},url:{}", crmUrl, url );
            } catch (Exception e) {
                LOGGER.error( e.getMessage(), e );
            }
        }
        return url;
    }

    @Override
    public String getCRMCustomerURL(Integer customerId, String curid, String cunname,Integer showMobile) {
        String url = "";
        CustomerEntity ce = customerService.getById( customerId );

        if (ce != null) {
            Date date = new Date();

            String crmUrl = MemoryPropertyPlaceholderConfigurer.getContextProperty( "CRM.CUSTOMER.INFO.URL" );
            List<NameValuePair> pairs = new ArrayList<>();
            pairs.add( new BasicNameValuePair( "city", ce.getCityCode() ) );
            pairs.add( new BasicNameValuePair( "memphone", ce.getPhone() ) );
            pairs.add( new BasicNameValuePair( "showMobile", String.valueOf(showMobile) ) );
            crmUrl += "&signature=" + MD5(
                    "" + (date.getTime() / 1000) + "hgs" ) + "&timestamp=" + (date.getTime() / 1000);
            crmUrl += "&admin_id=" + curid + "&admin_name=" + cunname;
            try {
                URLEncoder.encode( crmUrl, "utf8" );
                String res = HttpClientUtil.doPostWithCharset( crmUrl, pairs, "utf8", "utf8" );

                net.sf.json.JSONObject jsonObject = new net.sf.json.JSONObject();
                if (StringUtils.isNotBlank( res )) {
                    jsonObject = net.sf.json.JSONObject.fromObject( res );
                    if (jsonObject.get( "data" ) != null && "1".equalsIgnoreCase(
                            String.valueOf( jsonObject.get( "result" ) ) )) {
                        url = String.valueOf( jsonObject.get( "data" ) );
                    }
                }

                LOGGER.info( "getCRMCustomerURL :{},url:{}", res, url );
            } catch (Exception e) {
                LOGGER.error( e.getMessage(), e );
            }
        }
        return url;
    }

    /**
     * crm 接口调用
     *
     * @param customerId
     * @return
     */
    @Override
    public String crmAddCallBack(Integer customerId) {
        String url = "";
        CustomerEntity ce = customerService.getById( customerId );
        if (ce != null) {
            final String crmUrl = MemoryPropertyPlaceholderConfigurer.getContextProperty( "CRM.CUSTOMER.CALLBACK" );
            final String city = ce.getCityCode();
            final String phone = ce.getPhone();
            final String buyIntention = ce.getBuyIntention();
            hgsCacheUtil.delUserSummary( ce.getManagerId() );
            ce.setLastCallTime( new Date() );
            customerService.update( ce );

            if (Strings.isNullOrEmpty( phone )) {
                return "";
            }
            final String crmId = Strings.isNullOrEmpty( ce.getCrmId() ) ? "null" : ce.getCrmId();
            ExecutorService executor = Executors.newCachedThreadPool();
            executor.execute( new Runnable() {
                @Override
                public void run() {
                    try {
                        List<NameValuePair> pairs = new ArrayList<>();
                        pairs.add( new BasicNameValuePair( "city", city ) );
                        pairs.add( new BasicNameValuePair( "phones", phone ) );
                        pairs.add( new BasicNameValuePair( "buy_intention", buyIntention ) );
                        pairs.add( new BasicNameValuePair( "crm_ids", crmId ) );
                        String result = HttpClientUtil.doGet( crmUrl, pairs );
                        LOGGER.info( "call_CRM_add_customer_callback_result:{}", result );
                    } catch (Exception e) {
                        LOGGER.error( e.getMessage(), e );
                    }
                }
            } );

        }
        return url;
    }

    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    @Override
    public void abandonCustomer(String customerId, int userId, String oper, Integer callLogId) {
        Date cur = new Date();
        CustomerEntity customerEntity = customerService.getById( Integer.valueOf( customerId ) );
        if (customerEntity != null) {
            customerEntity.setIsDelete( 1 );
            customerEntity.setUpdateTime( cur );
            customerEntity.setUpdater( String.valueOf( userId ) );
            customerService.update( customerEntity );

            //新增客户删除日志
            logUtils.saveCustomerLog( customerEntity, 3, userId, oper );

            MarketCustomerEntity marketCustomer = marketCustomerService.queryByCustomerid( Integer.valueOf( customerId ) );
            if (marketCustomer != null) {
                marketCustomer.setIsabandon( 1 );
                marketCustomer.setStatus( 3 );
                marketCustomer.setAbandonTime( new Date() );
                marketCustomer.setUpdater( String.valueOf( userId ) );
                marketCustomer.setAbandonLogID( callLogId );
                marketCustomer.setUpdateTime( cur );
                marketCustomer.setLastManager( marketCustomer.getManagerName() );
                marketCustomerService.update( marketCustomer );
            }
        }
    }

    @Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    @Override
    public void abandonHotlineCustomer(String customerId, int userId, String oper, Integer callLogId) {
        Date cur = new Date();
        CustomerEntity customerEntity = customerService.getById( Integer.valueOf( customerId ) );
        if (customerEntity != null) {
            customerEntity.setStatus( 2 );//2:放弃
            customerEntity.setUpdateTime( cur );
            customerEntity.setUpdater( String.valueOf( userId ) );
            customerService.update( customerEntity );
        }
    }

    //获取最后评论记录，customerIds为逗号隔开，返回customerId和content
    @Override
    public House365RestResponse getLastestCallback(String customerIds) {
        House365RestResponse restResponse = new House365RestResponse();
        House365RestObject<Map<String, Object>> restObject = new House365RestObject();
        List<Map<String, Object>> result = customerService.getLastestCallback( customerIds );
        restObject.setList( result );
        restResponse.setData( restObject );
        return restResponse;
    }

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

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void updatePeer(int customerId, int isPeer, Date returnRemindTime, int userId, String cityCode) {
        CustomerEntity customerEntity = customerMapper.queryById( customerId );
        Map<String, Object> map = new HashMap<>( 10 );
        map.put( "id", customerId );
        map.put( "isPeer", isPeer );
        map.put( "updateTime", new Date() );
        customerMapper.updatePeer( map );
        //更新新表字段
        Map<String, Object> queryMap = new HashMap<>( 5 );
        queryMap.put( "phone", customerEntity.getPhone() );
        queryMap.put( "managerId", customerEntity.getManagerId() );
        CustomerEntity mergeEntity = customermergemapper.getCustomerMerge( queryMap );
        if (mergeEntity != null) {
            customermergemapper.updatePeer( map );
        }
        final int oldIsPeer = customerEntity.getIsPeer();

        if (returnRemindTime != null) {
            //添加或更新回访时间提醒记录
            Map<String, Object> searchMap = new HashMap<>( 10 );
            searchMap.put( "userId", userId );
            searchMap.put( "customerId", customerId );
            searchMap.put( "cityCode", cityCode );
            List<CustomerRemindEntity> list = remindMapper.queryByConditions( searchMap );
            if (CollectionUtils.isNotEmpty( list )) {
                for (CustomerRemindEntity e : list) {
                    e.setReturnRemindTime( returnRemindTime );
                    remindMapper.update( e );
                }
            } else {
                CustomerRemindEntity entity = new CustomerRemindEntity();

                entity.setCityCode( cityCode );
                entity.setCreateTime( new Date() );
                entity.setCreateUserId( userId );
                entity.setCustomerId( customerId );
                entity.setCustomerName( customerEntity.getName() );
                entity.setIsDelete( 0 );
                entity.setReturnRemindTime( returnRemindTime );
                remindMapper.save( entity );
            }
        }
//        同步crm系统(状态发生变化时推送)
        final int id = customerId;
        final String status = String.valueOf( isPeer );
        ExecutorService executor = Executors.newFixedThreadPool( 10 );
        executor.execute( new Runnable() {
            @Override
            public void run() {
                try {
                    CustomerEntity entity = customerMapper.queryById( id );
                    if (oldIsPeer != Integer.parseInt( status )) {
                        String mobile = entity.getPhone();
                        String city = entity.getCityCode();
                        List<NameValuePair> districtParam = new ArrayList<>();
                        districtParam.add( new BasicNameValuePair( "city", city ) );
                        districtParam.add( new BasicNameValuePair( "phone", mobile ) );
                        districtParam.add( new BasicNameValuePair( "status", status ) );
                        String result = HttpClientUtil.doGet( crmSyncUrl, districtParam );
                        if (Strings.isNullOrEmpty( result )) {
                            throw new Exception( "同步用户同行状态失败" + mobile + city + status );
                        } else {
                            ObjectMapper objectMapper = new ObjectMapper();
                            Map<String, Map> map = objectMapper.readValue( result, Map.class );
                            Number code = (Number) map.get( "code" );
                            if (code.intValue() != 200) {
                                throw new Exception( "同步用户同行状态失败:" + mobile + city + status );
                            }
                        }
                    }

                } catch (Exception e) {
                    LOGGER.error( "同步用户同行状态失败", e );
                }
            }
        } );

    }

    @Override
    public void updateCustomerStar(int customerId, int star) {
        Map<String, Object> map = new HashMap<>( 10 );
        map.put( "id", customerId );
        map.put( "star", star );
        customermergemapper.updateCustomerStar( map );
    }

    @Override
    public void updateOldCustomerStar(int customerId, int star) {
        Map<String, Object> map = new HashMap<>( 10 );
        map.put( "id", customerId );
        map.put( "star", star );
        customerMapper.updateOldCustomerStar( map );
    }

    @Override
    public void updatePtCustomerStar(int customerId, int starPtCustomer) {
        Map<String, Object> map = new HashMap<>( 10 );
        map.put( "id", customerId );
        map.put( "star", starPtCustomer );
        customerMapper.updatePtCustomerStar( map );
    }

    @Override
    public void updateOldCustomers(String phone, Integer managerId, Integer operId) {
        Map<String, Object> map = new HashMap<>( 10 );
        map.put( "phone", phone );
        map.put( "managerId", managerId );
        map.put( "oceanDate", new Date() );
        map.put( "updateTime", new Date() );
        map.put( "updater", operId );
        customerMapper.updateOldCustomers( map );
    }

    @Override
    public void saveCustomerMerge(CustomerEntity customerEntity) {
        customermergemapper.saveCustomerMerge( customerEntity );
    }

    @Override
    public void updateCustomerMerge(CustomerEntity customerEntity) {
        customermergemapper.updateCustomerMerge( customerEntity );
    }

    @Override
    public void updateCustomerMerge4AddCall(CustomerEntity customerEntity) {
        customermergemapper.updateCustomerMerge4AddCall( customerEntity );
    }

    @Override
    public void deleteCustomerMergeById(Map<String, Object> idMap) {
        customermergemapper.deleteCustomerMergeById( idMap );
    }

    @Override
    public void deleteSingleCustomer(CustomerEntity customerEntity) {
        customermergemapper.deleteSingleCustomerMerge( customerEntity );
    }

    @Override
    public List<CustomerEntity> queryByConditions(Map<String, Object> map) {
        List<CustomerEntity> list = customerMapper.queryByConditions( map );
        if (CollectionUtils.isNotEmpty( list )) {
            return list;
        }
        return Collections.emptyList();
    }

    @Override
    public List<CustomerEntity> queryCustomers(Map<String, Object> map) {
        List<CustomerEntity> list = customerMapper.queryCustomers( map );
        if (CollectionUtils.isNotEmpty( list )) {
            return list;
        }
        return Collections.emptyList();
    }

    @Override
    public List<CustomerRemindEntity> queryByCondition(Map<String, Object> map) {
        List<CustomerRemindEntity> list = remindMapper.queryByConditions( map );
        if (CollectionUtils.isNotEmpty( list )) {
            return list;
        }
        return Collections.emptyList();
    }

    @Override
    public CustomerEntity getCustomerMerge(String phone, Integer id) {
        Map<String, Object> map = new HashMap<>( 10 );
        map.put( "phone", phone );
        map.put( "managerId", id );
        return customermergemapper.getCustomerMerge( map );
    }

    @Override
    public CustomerEntity getCustomerMergeById(Integer oldCustomerId) {
        Map<String, Object> map = new HashMap<>( 10 );
        map.put( "oldCustomerId", oldCustomerId );
        return customermergemapper.getCustomerMergeById( map );
    }

    @Override
    public CustomerEntity getMergeCustomerId(Map<String, Object> map) {
        return customermergemapper.getMergeCustomerId( map );
    }

    @Override
    public List<CustomerEntity> getCustomerMergeList(Map<String, Object> map) {
        return customermergemapper.getCustomerMergeList( map );
    }

    @Override
    public Integer countCustomer(Map<String, Object> map) {
        return customermergemapper.countCustomer( map );
    }

    @Override
    public Integer countCustomer2(Map<String, Object> map) {
        return customermergemapper.countCustomer2( map );
    }

    @Override
    public Integer countCustomer3(Map<String, Object> map) {
        return customermergemapper.countCustomer3( map );
    }

    @Override
    public Integer countCustomer4(Map<String, Object> map) {
        return customermergemapper.countCustomer4( map );
    }

    @Override
    public List<CustomerEntity> getAllCustomer(Map<String, Object> map) {
        return customermergemapper.getAllCustomer( map );
    }

    @Override
    public List<CustomerEntity> getAllCustomer2(Map<String, Object> map) {
        return customermergemapper.getAllCustomer2( map );
    }

    @Override
    public List<CustomerEntity> getAllCustomer3(Map<String, Object> map) {
        return customermergemapper.getAllCustomer3( map );
    }

    @Override
    public List<CustomerEntity> getAllCustomer4(Map<String, Object> map) {
        return customermergemapper.getAllCustomer4( map );
    }

    @Override
    public void updateSeaCustomerByPhone(CustomerEntity customerEntity, UserEntity userEntity) {
        Map<String, Object> map = new HashMap<>( 10 );
        map.put( "phone", customerEntity.getPhone() );
        map.put( "lastManagerName", userEntity.getRealName() );
        map.put( "isDelete", "0" );
        map.put( "updater", userEntity.getId() );
        map.put( "updateTime", new Date() );
        map.put( "managerId", userEntity.getId() );
        customerMapper.updateSeaCustomerByPhone( map );
    }

    @Override
    public List<CustomerEntity> getSeaCustomerByPhone(CustomerEntity customerEntity, UserEntity userEntity) {
        Map<String, Object> map = new HashMap<>( 10 );
        map.put( "phone", customerEntity.getPhone() );
        map.put( "lastManagerName", userEntity.getRealName() );
        map.put( "isDelete", "0" );
        map.put( "updater", userEntity.getId() );
        map.put( "updateTime", new Date() );
        map.put( "managerId", userEntity.getId() );
        return customerMapper.getSeaCustomerByPhone( map );
    }

    @Override
    public Integer getCustomersById(Map<String, Object> map) {
        return customerMapper.getCustomersById( map );
    }

    @Override
    public void clearCustomerByManagerId(Map<String, Object> map, int userId, String userName) {
        //旧表回公海
        customerMapper.clearCustomerByManagerId( map );
        //新表删除
        customermergemapper.deleteCustomerMergeByManager( map );
        //添加客户进入公海日志
        List<CustomerEntity> list = customerMapper.queryByConditions( map );
        if (CollectionUtils.isNotEmpty( list )) {
            for (CustomerEntity c : list) {
                logUtils.saveCustomerLog( c, 6, userId, userName );
            }
        }
    }

    @Override
    public void deleteTips(int id) {
        remindMapper.delete( id );
    }

    @Override
    public List<CustomerEntity> getCustomerIds(Integer id, String cityCode) {
        Map<String, Object> map = new HashMap<>( 10 );
        map.put( "id", id );
        map.put( "cityCode", cityCode );
        return customerMapper.getCustomerIds( map );
    }

    @Override
    public List<CustomerCallbackLogEntity> getCallBackList(Map<String, Object> map) {
        return callbackMapper.getCallBackList( map );
    }

    @Override
    public List<CustomerEntity> getDetailCustomers(String phone, Integer managerId) {
        Map<String, Object> map = new HashMap<>( 10 );
        map.put( "phone", phone );
        map.put( "managerId", managerId );
        return customerMapper.getDetailCustomers( map );
    }

    @Override
    public CustomerEntity queryById(int id) {
        return customermergemapper.queryById( id );
    }

    @Override
    public List<CustomerEntity> queryMergeByConditions(Map<String, Object> map) {
        List<CustomerEntity> list = customermergemapper.queryByConditions( map );
        if (CollectionUtils.isNotEmpty( list )) {
            return list;
        }
        return Collections.emptyList();
    }

    @Override
    public void saveLog(CustomerLogEntity entity) {
        customerLogMapper.save( entity );
    }

    @Override
    public void update(Map<String, Object> map) {
        customermergemapper.update( map );
    }

    @Override
    public List<CustomerEntity> queryForAddHot(Map<String, Object> map) {
        List<CustomerEntity> list = customermergemapper.queryForAddHot( map );
        if (CollectionUtils.isNotEmpty( list )) {
            return list;
        }
        return Collections.emptyList();
    }

    @Override
    public int queryCount(Map<String, Object> map) {
        return customermergemapper.queryCount( map );
    }

    @Override
    public MapListResponse successList(MapListRequest request, UserEntity userEntity) {
        MapListResponse response = new MapListResponse();

        Map<String, Object> map = new HashMap<>( 10 );
        Map<String, Object> searchParams = request.getSearchParams();
        int start = 100 * (request.getPaging().getCurrentPage() - 1);
        map.put( "city", searchParams.get( "city" ) );
        map.put( "start", start );
        map.put( "limit", 100 );
        map.put( "name", searchParams.get( "name" ) );
        map.put( "phone", searchParams.get( "phone" ) );
        map.put( "managerName", searchParams.get( "managerName" ) );
        map.put( "projectName", searchParams.get( "projectName" ) );
        map.put( "startTime", searchParams.get( "createTimeStart" ) );
        if (null != searchParams.get( "createTimeEnd" ) && StringUtils.isNotBlank( searchParams.get( "createTimeEnd" ).toString() )) {
            String endTime = searchParams.get( "createTimeEnd" ) + " 23:59:59";
            map.put( "endTime", endTime );
        }
        map.put( "callStartTime", searchParams.get( "lastCallTimeStart" ) );
        if (null != searchParams.get( "lastCallTimeEnd" ) && StringUtils.isNotBlank( searchParams.get( "lastCallTimeEnd" ).toString() )) {
            String endTime = searchParams.get( "lastCallTimeEnd" ) + " 23:59:59";
            map.put( "callEndTime", endTime );
        }
        int userId = Integer.parseInt( searchParams.get( "userId" ).toString() );
        if (userId != 1) {
            map.put( "createId", userId );
        }
        if (null != searchParams.get( "orderByTime" )) {
            String sort = searchParams.get( "orderByTime" ).toString();
            switch (sort) {
                case "1":
                    map.put( "sort", 1 );
                    break;
                case "2":
                    map.put( "sort", 2 );
                    break;
                case "3":
                    map.put( "sort", 3 );
                    break;
                case "4":
                    map.put( "sort", 4 );
                    break;
                case "5":
                    map.put( "sort", 5 );
                    break;
                case "6":
                    map.put( "sort", 6 );
                    break;
                default:
                    map.put( "sort", 1 );
                    break;
            }
        } else {
            map.put( "sort", 1 );
        }

        List<Map<String, Object>> list = customerProjectMapper.querySuccessList( map );
        if (CollectionUtils.isNotEmpty( list )) {
            for (Map<String, Object> m : list) {
                int customerId = Integer.parseInt( m.get( "id" ).toString() );
                List<CustomerCallbackLogEntity> callLogList;
                Map<String, Object> cpMap = new HashMap<>( 10 );
                Map<String, Object> searchMap = new HashMap<>( 10 );
                //区分查询回访记录
                if (null != m.get( "managerId" )) {
                    int managerId = Integer.parseInt( m.get( "managerId" ).toString() );
                    String phone = m.get( "phone" ).toString();
                    Map<String, Object> idMap = new HashMap<>( 10 );
                    idMap.put( "phone", phone );
                    idMap.put( "managerId", managerId );
                    idMap.put( "isPrivate", 1 );
                    List<CustomerEntity> oldList = customerMapper.queryByConditions( idMap );
                    List<Integer> customerIdList = new ArrayList<>();
                    customerIdList.add( customerId );
                    if (CollectionUtils.isNotEmpty( oldList )) {
                        for (CustomerEntity e : oldList) {
                            customerIdList.add( e.getId() );
                        }
                    }
                    cpMap.put( "idList", customerIdList );
                    searchMap.put( "idList", customerIdList );
                } else {
                    cpMap.put( "customerIdNew", customerId );
                    searchMap.put( "customerId", customerId );
                }
                //查询回访记录
                callLogList = callbackMapper.queryByConditions( searchMap );
                boolean hasCustomerProjects = false;
                boolean hasNewCustomerProjects = false;
                //查询约看项目
                List<CustomerProjectEntity> cpList = customerProjectMapper.queryByConditions( cpMap );
                if (CollectionUtils.isNotEmpty( cpList )) {
                    hasCustomerProjects = true;
                    for (CustomerProjectEntity cp : cpList) {
                        if (userEntity.getPreLoginTime() != null && cp.getLastChangeStatusTime() != null) {
                            if (userEntity.getPreLoginTime().before( cp.getLastChangeStatusTime() )) {
                                hasNewCustomerProjects = true;
                            }
                        }
                    }
                }
                m.put( "hasCustomerProjects", hasCustomerProjects );
                m.put( "hasNewCustomerProjects", hasNewCustomerProjects );
                m.put( "callbackLogEntities", callLogList );
                m.put( "customerProjects", cpList );
            }
        }
        int count = customerProjectMapper.querySuccessListCount( map );
        request.getPaging().setRecords( count );
        response.setPaging( request.getPaging() );
        response.setObjectList( list );
        response.setResultCode( ReturnResult.SUCCESS.getResultCode() );
        response.setResultMessage( ReturnResult.SUCCESS.getResultMessage() );
        return response;
    }

    @Override
    public MapListResponse seaList(MapListRequest request, String type) {
        MapListResponse response = new MapListResponse();
        try {
            Map<String, Object> map = new HashMap<>( 10 );
            Map<String, Object> searchParams = request.getSearchParams();
            int start = 100 * (request.getPaging().getCurrentPage() - 1);
            map.put( "start", start );
            map.put( "limit", 100 );
            map.put( "city", searchParams.get( "city" ) );
            map.put( "phone", searchParams.get( "phone" ) );
            map.put( "name", searchParams.get( "name" ) );
            map.put( "lastManager", searchParams.get( "lastManager" ) );
            map.put( "buyIntention", searchParams.get( "buyIntention" ) );
            map.put( "oceanDateStart", searchParams.get( "oceanDateStart" ) );
            map.put( "oceanDateEnd", searchParams.get( "oceanDateEnd" ) );
            map.put( "createSource", searchParams.get( "createSource" ) );
            if ("1".equals( type )) {
                // CRM导入
                map.put( "createSource", "CRM导入" );
                map.put( "isRecycled", 0 );
                map.put( "notBuyIntention", "5" );
            } else if ("2".equals( type )) {
                // 系统回收
                map.put( "isRecycled", 1 );
                map.put( "notBuyIntention", "5" );
            } else if ("3".equals( type )) {
                // 无效客户
                map.put( "buyIntention", "5" );
            }
            List<Map<String, Object>> list = customerMapper.querySeaList( map );
            int count = customerMapper.querySeaCount( map );

            request.getPaging().setRecords( count );
            response.setPaging( request.getPaging() );
            response.setObjectList( list );
            response.setResultCode( ReturnResult.SUCCESS.getResultCode() );
            response.setResultMessage( ReturnResult.SUCCESS.getResultMessage() );
        } catch (Exception e) {
            LOGGER.error( e.getMessage(), e );
            response.setResultCode( ReturnResult.FAIL.getResultCode() );
            response.setResultMessage( e.getMessage() );
        }
        return response;
    }

    @Override
    public HResult deleteById(int id, int userId, String userName) {
        HResult result = new HResult();
        CustomerEntity customer = customerMapper.queryById( id );
        if (null == customer.getManagerId()) {
            customer.setIsDelete( 1 );
            customerService.update( customer );
            //新增客户删除日志
            logUtils.saveCustomerLog( customer, 3, userId, userName );
        } else {
            result.setStatus( 500 );
            result.setErrorMessage( "客户未回公海，不能删除" );
        }
        return result;
    }

    /**
     * 批量软删除customerid
     *
     * @param idList
     * @param userId
     * @param userName
     * @return
     */
    @Override
    public HResult deleteIdList(List<Integer> idList, int userId, String userName) {
        HResult result = new HResult();
        try {
            int updateCount = customerMapper.updateIdList( idList );
            LOGGER.info( "updateCount:" + updateCount );
            result.setStatus( 0 );
            result.setData( updateCount );
        } catch (Exception e) {
            LOGGER.error( e.getMessage(), e );
            result.fail( 500, e.getMessage() );
        }
        return result;
    }

    /**
     * 根据用户id查询该用户在平台管理的数量
     *
     * @param userId
     * @return
     */
    @Override
    public int queryCountById(Integer userId){
        return customerMapper.queryCountById( userId );
    }

    @Override
    @Transactional
    public void batchTransferCreator(String[] customerIds, String[] userIds, UserEntity userEntity, int type) throws Exception {
        if(customerIds.length <= userIds.length){
            for (int i = 0; i < customerIds.length; i++) {
                String customer = customerIds[i];
                String userId = userIds[i];
                if (Strings.isNullOrEmpty( customer )) {
                    continue;
                }
                if (Strings.isNullOrEmpty( userId )) {
                    continue;
                }
                batchTransferCreator(userId,customer,userEntity);
            }
        }else {
            int j = 0;
            for (int i = 0; i < customerIds.length; i++) {
                String customer = customerIds[i];
                String userId = "";
                if (Strings.isNullOrEmpty( customer )) {
                    continue;
                }
                if(i > userIds.length -1){
                    if(j > userIds.length -1 ){
                        j=0;
                    }
                    userId  = userIds[j];
                    j++;
                }else {
                    userId = userIds[i];
                }
                batchTransferCreator(userId,customer,userEntity);
            }
        }

    }

    /**
     *
     * @param userId
     * @param customerId
     */
    private void batchTransferCreator(String userId,String customerId,UserEntity userEntity){
        CustomerEntity customerEntity = customerMapper.queryById( Integer.valueOf( customerId ) );
        Map<String, Object> map = new HashMap<>( 10 );
        map.put( "creater" ,userId);
        map.put( "customerId",customerId );
        customerMapper.updatePtCustomerCreater( map );
        customerMapper.updatePtCustomerCreaterMerge( map );
        //记录日志
        logUtils.saveCustomerLog2( customerEntity, 11, userEntity.getId(),userEntity.getRealName(),customerEntity.getCreater(),userId );
    }

    /**
     * 以下均为自动生成
     */
    @Override
    public Object exectue(Parameter parameter) throws ServiceRunException {
        return null;
    }

    @Override
    public boolean isControlService() {
        return false;
    }

    @Override
    public boolean isLogService() {
        return false;
    }

    @Override
    public boolean isMonitorService() {
        return false;
    }

    @Override
    public Object rollback() {
        return null;
    }

    @Override
    public void commit() {
    }

    /**
     * 判断手机号是都在表里
     * @param phoneList
     * @param type  0，【公海】
     *              1，【待派】待派CRM
     *              2，【私客】待回访
     *              3,【私客】customer_merge表
     * @return
     */
    @Override
    public List<CustomerEntity> getExistByPhone(List<String> phoneList, int type) {
        Map<String, Object> map = new HashMap<>( 10 );
        map.put("phoneList",phoneList);
        map.put("is_delete",0);
        if(type == 0) {
            map.put("manager_id",0);//不能有manager_id
        } else if (type == 1) {
            // CRM导入
            map.put( "createSource", "CRM导入" );
            map.put( "isRecycled", 0 );
            map.put( "notBuyIntention", "5" );
            map.put("manager_id",0);
        } else if(type == 2) {
            map.put("hotlone",0);
            map.put("isWaitCall",1);
            map.put("manager_id",1);
        }
        if(type == 3) {
            Map<String,Object> param = new HashMap<>();
            param.put("phoneList",phoneList);
            return customermergemapper.getExistByPhone(param);
        }
        return customerMapper.getExistByPhone(map);
    }


}
