/**
 * Description: 账户WS接口
 * Copyright:   Copyright (c)2016
 * Company:     江苏三六五网络股份有限公司
 *
 * @author: 江苏三六五网络股份有限公司
 * @version: 1.0
 * Create at:   2016-09-14 下午 17:27:22
 * <p>
 * Modification History:
 * Date         Author      Version     Description
 * ------------------------------------------------------------------
 * 2016-09-14   江苏三六五网络股份有限公司   1.0         Initial
 */
package com.house365.ws.interfaces.impl;

import com.google.common.base.Joiner;
import com.google.common.base.Strings;
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.rest.context.Parameter;
import com.house365.rest.exception.ServiceException;
import com.house365.rest.exception.ServiceRunException;
import com.house365.web.util.MemoryPropertyPlaceholderConfigurer;
import com.house365.web.util.SpringContextUtil;
import com.house365.web.util.StringUtils;
import com.house365.ws.beans.request.*;
import com.house365.ws.beans.response.*;
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.IDepartment;
import com.house365.ws.interfaces.server.IUser;
import com.house365.ws.service.interfaces.*;
import com.house365.ws.system.ReturnResult;
import com.house365.ws.util.PathUtil;
import net.sf.json.JSONObject;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.security.MessageDigest;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/**
 * 账户WS接口<br>
 *
 * @author 江苏三六五网络股份有限公司
 * @version 1.0, 2016-09-14
 * @see
 * @since 1.0
 */
@Service("user")
public class UserImpl implements IUser {
    /**
     * 日志记录器
     */
    private static final Logger logger = LoggerFactory.getLogger(UserImpl.class);

    /**
     * 账户服务对象
     */
    @Autowired
    private IUserService<UserEntity> userService;

    @Autowired
    private IUserDeletedService<UserDeletedEntity> userDeletedService;

    @Autowired
    private IRoleService<RoleEntity> roleService;

    @Autowired
    private IPermissionService<PermissionEntity> permissionService;

    @Autowired
    private IWechatService wechatService;

    @Autowired
    private IHgsCacheUtil hgsCacheUtil;

    @Autowired
    private IDepartmentService departmentService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LabelMapper labelmapper;

    @Autowired
    private WxUserMapper wxUserMapper;

    @Autowired
    private UserWxRelationMapper relationMapper;

    @Autowired
    private MessageLogMapper messageLogMapper;
    @Autowired
    private ProjectRecommendMapper recommendMapper;
    @Autowired
    private IAttachmentService attachmentService;
    @Autowired
    private IDepartment department;

    @Override
    public List<DutyStaffEntity> getOndutyById(Integer uid) {
        return userMapper.getOndutyById(uid);
    }


    @Override
    public List<LabelEntity> getCustomerLabelById(LabelEntity labelentity) {
        return labelmapper.getCustomerLabelById(labelentity);
    }

    @Override
    public List<LabelEntity> getCustomerLabelIds(LabelEntity labelentity) {
        return labelmapper.getCustomerLabelIds(labelentity);
    }

    @Override
    public List<LabelEntity> getColorLabel(Map<String, Object> labelMap) {
        return labelmapper.getColorLabel(labelMap);
    }

    @Override
    public List<LabelEntity> getColorLabel4MyCustomer(Map<String, Object> labelMap) {
        return labelmapper.getColorLabel4MyCustomer(labelMap);
    }

    @Override
    public List<LabelEntity> getLabelColor(Map<String, Object> labelMap) {
        return labelmapper.getLabelColor(labelMap);
    }

    @Override
    public List<LabelEntity> getAllLabelsByOwn(Map<String, Object> labelMap) {
        return labelmapper.getAllLabelsByOwn(labelMap);
    }

    @Override
    public UserEntity getLimitLoginById(String name) {
        return userMapper.getLimitLoginById(name);
    }

    @Override
    public void addLabel(LabelEntity entity) {
        labelmapper.addLabel(entity);
    }

    @Override
    public void saveCustomersLabels(List<LabelEntity> paramList) {
        labelmapper.saveCustomersLabels(paramList);
    }

    @Override
    public void updateLabel(LabelEntity entity) {
        labelmapper.updateLabel(entity);
    }

    @Override
    public void updateUserCustomerLabel(LabelEntity entity) {
        labelmapper.updateUserCustomerLabel(entity);
    }

    @Override
    public void delLabel(LabelEntity entity) {
        labelmapper.delLabel(entity);
    }

    @Override
    public void delCustomerLabel(LabelEntity entity) {
        labelmapper.delCustomerLabel(entity);
    }

    @Override
    public void addRequestLoginInfo(RequestLoginEntity requestlogin) {
        userMapper.addRequestLoginInfo(requestlogin);
    }

    @Override
    public List<RequestLoginEntity> getRequestLoginInfo(RequestLoginEntity requestloginentity) {
        return userMapper.getRequestLoginInfo(requestloginentity);
    }

    @Override
    public List<LabelEntity> queryCustomerLabel(Integer userId, Integer customerId) {
        Map<String, Integer> map = new HashMap<>(10);
        map.put("userId", userId);
        map.put("customerId", customerId);
        return labelmapper.queryCustomerLabel(map);
    }

    @Override
    public List<LabelEntity> queryUserLabel(Integer userId) {
        Map<String, Integer> map = new HashMap<>(10);
        map.put("userId", userId);
        map.put("isDelete", 0);
        return labelmapper.queryUserLabel(map);
    }

    @Override
    public List<LabelEntity> queryUserCustomerLabel(Integer userId, Integer customerId) {
        Map<String, Integer> map = new HashMap<>(10);
        map.put("customerId", customerId);
        map.put("managerId", userId);
        return labelmapper.queryUserCustomerLabel(map);
    }

    @Override
    public RequestLoginEntity getRequestLoginInfoById(Integer id) {
        return userMapper.getRequestLoginInfoById(id);
    }

    @Override
    public Map<String, Object> validate(AuthenticationToken token) {
        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        String username = userToken.getUsername();
        String password = new String(userToken.getPassword());
        QueryParams<UserEntity> queryParams = new QueryParams<>();
        queryParams.setPaging(new Page(10));
        Map<String, Object> map = new HashMap<>(5);
        map.put("EQ_name", username);
        queryParams.setSearchParams(map);
        List<UserEntity> userList = userService.queryByPage(queryParams);
        logger.info("*******************:" + userList.get(0).getEnabled());
        if (CollectionUtils.isNotEmpty(userList) && !userList.get(0).getEnabled()) {
            throw new RuntimeException("该账户已被锁定，禁止登录");
        }
        if (CollectionUtils.isNotEmpty(userList) && userList.get(0).getPassword().equals(password)) {
            Map<String, Object> permissions = getUserPermissions(userList.get(0).getId());
            logger.info("*******************:" + permissions.toString());
            return permissions;
        } else {
            throw new RuntimeException("login_error");
        }

    }

    private Map<String, Object> getUserRoles(Integer userId) {
        List<RoleEntity> roles = roleService.getRolesByUserId(userId);
        Map<String, Object> rolesMap = new HashMap<>(5);
        rolesMap.put("roles", roles);
        return rolesMap;
    }

    private Map<String, Object> getUserPermissions(Integer userId) {
        List<PermissionEntity> permissions = permissionService.getPermissionsByUserId(userId);
        Map<String, Object> permissionsMap = new HashMap<>(5);
        permissionsMap.put("permissions", permissions);
        return permissionsMap;
    }

    /**
     * 账户列表查询
     *
     * @param request 账户列表查询请求
     * @return 账户列表查询响应s
     */
    @Override
    public UserListResponse getUserList(UserListRequest request) {
        UserListResponse response = new UserListResponse();
        try {
            QueryParams<UserEntity> queryParams = new QueryParams<>(request.getSearchParams());
            queryParams.setPaging(request.getPaging());
            queryParams.setOrderColumn(request.getOrderColumn());
            queryParams.setOrderMode(request.getOrderMode());
            List<UserEntity> users = userService.queryByPage(queryParams);
            response.setPaging(queryParams.getPaging());
            response.setObjectList(users);
            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 LabelResponse getLabelList(LabelRequest request) {
        LabelResponse response = new LabelResponse();
        try {
            QueryParams<LabelEntity> queryParams = new QueryParams<>(request.getSearchParams());
            queryParams.setPaging(request.getPaging());
            Map<String, Object> map = new HashMap<>(10);
            map.put("OrderColumn", request.getOrderColumn());
            map.put("OrderMode", request.getOrderMode());
            map.put("PageNumber", ((request.getPaging().getCurrentPage() - 1) * request.getPaging().getPageSize()));
            map.put("pageSize", request.getPaging().getPageSize());
            map.put("labelName", request.getSearchParams().get("LIKE_labelName"));
            map.put("createId", request.getSearchParams().get("EQ_createId"));
            map.put("cityCode", request.getSearchParams().get("EQ_cityCode"));
            List<LabelEntity> label = labelmapper.getLabelList(map);
            Integer labelCount = labelmapper.getLabelListCount(map);
            if (CollectionUtils.isNotEmpty(label)) {
                int finalPages = labelCount % 1 == 0 ? labelCount : labelCount + 1;
                queryParams.getPaging().setPages(finalPages);
                queryParams.getPaging().setRecords(labelCount);
            }
            response.setPaging(queryParams.getPaging());
            response.setObjectList(label);
            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 VersionListResponse getAppVersionList(VersionListRequest request) {
        VersionListResponse response = new VersionListResponse();
        try {
            QueryParams<VersionEntity> queryParams = new QueryParams<>(request.getSearchParams());
            queryParams.setPaging(request.getPaging());
            queryParams.setOrderColumn(request.getOrderColumn());
            queryParams.setOrderMode(request.getOrderMode());
            List<VersionEntity> version = userService.getAppVersionList(queryParams);
            if (CollectionUtils.isNotEmpty(version)) {
                int finalPages = version.size() % 1 == 0 ? version.size() : version.size() + 1;
                queryParams.getPaging().setPages(finalPages);
                queryParams.getPaging().setRecords(version.size());
            }
            response.setPaging(queryParams.getPaging());
            response.setObjectList(version);
            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 void authorizationById(RequestLoginEntity entity) {
        userMapper.authorizationById(entity);
    }

    @Override
    public void updateRequestById(RequestLoginEntity requestloginentity) {
        userMapper.updateRequestById(requestloginentity);
    }

    @Override
    public AuthorizationResponse getAuthorizationList(AuthorizationRequest listRequest) {
        AuthorizationResponse response = new AuthorizationResponse();
        try {
            QueryParams<RequestLoginEntity> queryParams = new QueryParams<>(listRequest.getSearchParams());
            queryParams.setPaging(listRequest.getPaging());
            queryParams.setOrderColumn(listRequest.getOrderColumn());
            queryParams.setOrderMode(listRequest.getOrderMode());
            List<RequestLoginEntity> list = userService.getAuthorizationList(queryParams);
            Integer totalNum = userService.countAuthorizationList(queryParams);
            if (CollectionUtils.isNotEmpty(list)) {
                int finalPages = totalNum / 10 == 0 ? 1 : totalNum / 10 + 1;
                queryParams.getPaging().setPages(finalPages);
                queryParams.getPaging().setRecords(totalNum);
            }
            response.setPaging(queryParams.getPaging());
            response.setObjectList(list);
            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 UserResponse addUser(UserRequest request) {
        UserResponse response = new UserResponse();
        try {
            UserEntity entity = request.getEntity();
            userService.save(entity);
            int promoteId = syncUserToPromote(entity);
            entity.setPromoteId(promoteId);
            userService.update(entity);
            response.setEntity(entity);
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());

            final UserEntity entityPost = entity;
            ExecutorService executor = Executors.newCachedThreadPool();
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        wechatService.callWechatUserAPI(entityPost, "/enterprise/user/create");
                    } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                    }
                }
            });

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

    /**
     * 删除账户通过唯一标识
     *
     * @param id 唯一标识
     * @return 删除账户响应
     */
    @Override
    public UserResponse deleteUserById(Integer id, int userId) {
        UserResponse response = new UserResponse();
        try {
            // 插入delete_user表
            UserEntity user = userService.getById(id);
            UserDeletedEntity userDeleted = new UserDeletedEntity();
            ConvertUtils.register(new BooleanConverter(null), Boolean.class);
            ConvertUtils.register(new LongConverter(null), Long.class);
            ConvertUtils.register(new IntegerConverter(null), Integer.class);
            ConvertUtils.register(new DoubleConverter(null), Double.class);
            ConvertUtils.register(new DateConverter(null), Date.class);
            BeanUtils.copyProperties(userDeleted, user);
            //添加删除日志
            userDeleted.setCreateUserid(userId);
            userDeletedService.save(userDeleted);

            // 从user表删除用户
            userService.delete(id);

            List<NameValuePair> directParams = new ArrayList<>();
            directParams.add(new BasicNameValuePair("serviceCode", "TaoFangHui"));
            directParams.add(new BasicNameValuePair("serviceName", "updateBindPeople"));
            directParams.add(new BasicNameValuePair("userId", id.toString()));
            directParams.add(new BasicNameValuePair("status", "1"));
            //调用淘房汇更新绑定人员接口
            HttpClientUtil.doGet(MemoryPropertyPlaceholderConfigurer.getContextProperty("tangfanghui.server.url"), directParams);
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());

            final Integer postId = id;
            ExecutorService executor = Executors.newCachedThreadPool();
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        wechatService.deleteWechatUser(postId);
                        //已经删除账号的安家顾问，楼盘推荐自动下架
                        recommendMapper.deleteByUserId(postId);
                    } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                    }
                }
            });

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

    /**
     * 修改账户
     *
     * @param request 修改账户请求
     * @return 修改账户响应
     */
    @Override
    public UserResponse updateUser(UserRequest request) {
        UserResponse response = new UserResponse();
        try {
            UserEntity entity = request.getEntity();
            Boolean enabled = entity.getEnabled();
            List<NameValuePair> directParams = new ArrayList<>();
            directParams.add(new BasicNameValuePair("serviceCode", "TaoFangHui"));
            directParams.add(new BasicNameValuePair("serviceName", "updateBindPeople"));
            directParams.add(new BasicNameValuePair("userId", entity.getId().toString()));
            //设置为不启用时调用淘房汇接口
            if (!enabled) {
                directParams.add(new BasicNameValuePair("status", "1"));
                //调用淘房汇更新绑定人员接口
                HttpClientUtil.doGet(MemoryPropertyPlaceholderConfigurer.getContextProperty("tangfanghui.server.url"), directParams);
            } else {
                directParams.add(new BasicNameValuePair("status", "0"));
                //调用淘房汇更新绑定人员接口
                HttpClientUtil.doGet(MemoryPropertyPlaceholderConfigurer.getContextProperty("tangfanghui.server.url"), directParams);
            }
            userService.update(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 void syncUserList() {
        Map<String, Object> map = new HashMap<>(5);
        List<UserEntity> list = userMapper.queryByConditions(map);
        if (CollectionUtils.isNotEmpty(list)) {
//            if (list.size() > 10) {
//                list = list.subList(0, 10);
//            }
            for (UserEntity u : list) {
                int promoteId = syncUserToPromote(u);
                u.setPromoteId(promoteId);
                userService.update(u);
            }
        }
    }

    /**
     * 同步用户至推广宝
     *
     * @param user
     * @return
     */
    private int syncUserToPromote(UserEntity user) {
        int promoteId = 0;
        try {
            String url = MemoryPropertyPlaceholderConfigurer.getContextProperty("promote.url");
            List<NameValuePair> directParams = new ArrayList<>();

            directParams.add(new BasicNameValuePair("appId", "7"));
            directParams.add(new BasicNameValuePair("platformId", user.getId().toString()));
            directParams.add(new BasicNameValuePair("name", user.getRealName()));
            directParams.add(new BasicNameValuePair("tel", user.getMobile()));
            List<BaseAttachment> headImg = attachmentService.queryByResourceIdAndResouceType(String.valueOf(user.getId()), "hgs_user_headImg");
            if (CollectionUtils.isNotEmpty(headImg)) {
                directParams.add(new BasicNameValuePair("head_img", headImg.get(0).getRemotePath()));
            }

            directParams.add(new BasicNameValuePair("wx_code", user.getWxCodeImgUrl()));
            DepartmentResponse departmentResponse = department.getDepartmentById(user.getDeptId());
            DepartmentEntity dept = departmentResponse.getEntity();
            Integer realDept = PathUtil.extractDept(dept.getUrlPath());
            if (!user.getDeptId().equals(realDept)) {
                dept = department.getDepartmentById(realDept).getEntity();
            }
            String cityId = dept.getCityID();
            DepartmentResponse departmentResponse2 = department.getDepartmentById(Integer.valueOf(cityId));
            String cityCode = departmentResponse2.getEntity().getDescripition();
            directParams.add(new BasicNameValuePair("city", cityCode));
            //1:安家顾问,3:新房房博士 6 二手房房博士 10 租房房博士 7 客服 20 平台人员
            if (org.apache.commons.lang3.StringUtils.isNotBlank(user.getIdentityType())) {
                String typeName;
                switch (user.getIdentityType()) {
                    case "1":
                        typeName = "安家顾问";
                        break;
                    case "3":
                        typeName = "新房房博士";
                        break;
                    case "6":
                        typeName = "二手房房博士";
                        break;
                    case "7":
                        typeName = "客服";
                        break;
                    case "10":
                        typeName = "租房房博士";
                        break;
                    case "20":
                        typeName = "平台人员";
                        break;
                    default:
                        typeName = "其他";
                        break;
                }
                directParams.add(new BasicNameValuePair("position", typeName));
            }
            directParams.add(new BasicNameValuePair("profile", user.getGoodat()));
            //新增时不传推广部id
            if (user.getPromoteId() > 0) {
                directParams.add(new BasicNameValuePair("tgbId", String.valueOf(user.getPromoteId())));
            }
            if (org.apache.commons.lang3.StringUtils.isNotBlank(user.getHotlinephone())) {
                String phone = "4008908365," + user.getHotlinephone();
                directParams.add(new BasicNameValuePair("tel400", phone));
            }
            directParams.add(new BasicNameValuePair("appkey", "1595236845"));
            directParams.add(new BasicNameValuePair("appSecret", "890725e6c3499616"));

            String result = HttpClientUtil.doPost(url, directParams);
            JSONObject json = JSONObject.fromObject(result);
            Number code = (Number) json.get("code");
            if (code.intValue() == 200) {
                promoteId = Integer.valueOf(json.get("data").toString());
            } else {
                promoteId = 0;
            }
            return promoteId;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("推送用户至推广部失败", e);
        }
        return promoteId;
    }

    @Override
    public UserResponse updateUserAndSyncToWechat(UserRequest request) {
        UserResponse response = new UserResponse();
        try {
            UserEntity entity = request.getEntity();
            int promoteId = syncUserToPromote(entity);
            entity.setPromoteId(promoteId);
            userService.update(entity);
            response.setResultCode(ReturnResult.SUCCESS.getResultCode());
            response.setResultMessage(ReturnResult.SUCCESS.getResultMessage());

            UserEntity ur = userService.getById(entity.getId());
            String cookieKey = "weChat:userInfo:isValid:" + ur.getMobile();
            //修改后，删除wechat的cookie的key；
            RedisUtilsInterface redisUtils = (RedisUtilsInterface) SpringContextUtil.getBean("redisUtils");
            redisUtils.deleteKey(cookieKey);

            final UserEntity entityPost = ur;
            ExecutorService executor = Executors.newCachedThreadPool();
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        wechatService.callWechatUserAPI(entityPost, "/enterprise/user/update");
                    } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                    }
                }
            });
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(ex.getMessage());
        }
        return response;
    }

    @Override
    public void syncToWechat(UserRequest request) {
        UserResponse response = new UserResponse();
        try {
            final UserEntity entityPost = request.getEntity();
            ExecutorService executor = Executors.newCachedThreadPool();
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        wechatService.callWechatUserAPI(entityPost, "/enterprise/user/create");
                    } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                    }
                }
            });

        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            response.setResultCode(ReturnResult.FAIL.getResultCode());
            response.setResultMessage(ex.getMessage());
        }
    }

    /**
     * IM身份信息更新
     */
    @Override
    public void updateIM(UserEntity ue) {
        userService.update(ue);
        //更新IM同时通知推广宝
        UserEntity user = userService.getById(ue.getId());
        int promoteId = syncUserToPromote(user);
        user.setPromoteId(promoteId);
        userService.update(user);
    }

    @Override
    public List<UserEntity> getManagerByPid(Integer uid, String managername) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", uid);
        map.put("realName", managername);
        return userMapper.getManagerByPid(map);
    }

    /**
     * 通过ID获取账户
     *
     * @param id 唯一标识
     * @return 通过ID获取账户响应
     */
    @Override
    public UserResponse getUserById(Integer id) {
        UserResponse response = new UserResponse();
        try {
            UserEntity entity = userService.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;
    }

    @Override
    public List<DepartmentEntity> getChildDepartList(Integer deptId) {
        return hgsCacheUtil.getChildDeptments(deptId);
    }

    @Override
    public UserEntity getRemotePath(Integer resourceId) {
        return userService.getRemotePath(resourceId);
    }

    @Override
    public UserListResponse getUserListByDept(DepartmentEntity dept, Map<String, Object> userParaMap, Page page) {
        return hgsCacheUtil.getUserListByDept(dept, userParaMap, page);
    }

    //获取自己和所有下属id
    @Override
    public List<Integer> getUserIdOnPath(Integer parentId) {
        return userService.getUserIdOnPath(parentId);
    }

    @Override
    public Map<String, Object> getSummary(String managerId) {
        return hgsCacheUtil.getSummary(managerId);
    }

    @Override
    public String unbindHotlinePhone(UserEntity userEntity) {
        String result = "";
        DepartmentEntity dept = (DepartmentEntity) departmentService.getById(userEntity.getDeptId());
        if (!Strings.isNullOrEmpty(userEntity.getHotlinephone()) && dept != null) {
            try {
                //获取signature
                String deciceId = com.house365.web.util.StringUtils.getRandomNumber(10);
                String randStr = com.house365.web.util.StringUtils.getRandomChars(13);
                String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
                String signature = getSignature(deciceId, randStr, timestamp);
                //1.先获取acce_token作为入参
                HashMap<String, String> tokenMap = new HashMap<>(10);
                tokenMap.put("version", "v3.0");
                String accessToken = getAccessToken(tokenMap, timestamp, randStr, signature, deciceId);
                //2.解绑  解绑URl
                String unbindUrl = MemoryPropertyPlaceholderConfigurer.getContextProperty("unbindcornet.url");
                HashMap<String, String> unBindMap = new HashMap<>(10);
                unBindMap.put("version", "v3.0");

                unBindMap.put("access-token", accessToken);
                List<NameValuePair> unbindInParam = new ArrayList<>();
                List<String> newUnbindParams = new ArrayList<>();
                unbindInParam.add(new BasicNameValuePair("short_tel", userEntity.getHotlinephone()));

                for (NameValuePair pair : unbindInParam) {
                    newUnbindParams.add(pair.getName() + "=" + pair.getValue());
                }
                String newUnbindUrl = unbindUrl + "?" + Joiner.on("&").join(newUnbindParams);
                String unbindResult = getHttpRequest(newUnbindUrl, unBindMap, 100000, "utf-8");
                logger.warn("user unbind hotline phone , [{}]", userEntity.getRealName());
                JSONObject jo = JSONObject.fromObject(unbindResult);
                if ("1".equals(jo.getString("code"))) {

                    userEntity.setHotlinephone(null);
                    userEntity.setUpdateTime(new Date());
                    userEntity.setUpdateUserid(userEntity.getId());
                    userService.update(userEntity);
                    result = "success";
                } else if ("-8".equals(jo.getString("code"))) {
                    result = "notexist";
                } else {
                    result = "fail";
                }
            } catch (Exception e) {
                logger.error(e.getMessage() + "_user_" + userEntity.getId(), e);
            }
        }
        return result;
    }

    private final static 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;
        }
    }

    /**
     * 生成signature
     *
     * @return
     */
    private static String getSignature(String deciceId, String randStr, String timestamp) {
        //获取signature
        List<NameValuePair> signatureInParam = new ArrayList<>();
        signatureInParam.add(new BasicNameValuePair("app_id", "12558119"));
        signatureInParam.add(new BasicNameValuePair("app_secret", "OHuJNOfHSMixNeoedRwScEmzcDAuxnJw"));
        signatureInParam.add(new BasicNameValuePair("device_id", deciceId));
        signatureInParam.add(new BasicNameValuePair("rand_str", randStr));
        signatureInParam.add(new BasicNameValuePair("timestamp", timestamp));
        List<String> newParams = new ArrayList<>();
        for (NameValuePair pair : signatureInParam) {
            newParams.add(pair.getName() + "=" + pair.getValue());
        }
        String newStr = Joiner.on("&").join(newParams);
        String signature = MD5(newStr);
        return signature;
    }

    private static String getAccessToken(HashMap<String, String> tokenMap, String timestamp, String randStr, String signature, String deciceId) {
        //获取acceToken接口URl
        String getAccessTokenUrl = "http://tel400.house365.com/api/5aaf0c48ed105";
        List<NameValuePair> tokenInParam = new ArrayList<>();
        tokenInParam.add(new BasicNameValuePair("timestamp", timestamp));
        tokenInParam.add(new BasicNameValuePair("app_id", "12558119"));
        tokenInParam.add(new BasicNameValuePair("rand_str", randStr));
        tokenInParam.add(new BasicNameValuePair("signature", signature));
        tokenInParam.add(new BasicNameValuePair("device_id", deciceId));
        List<String> newTokenParams = new ArrayList<>();
        for (NameValuePair pair : tokenInParam) {
            newTokenParams.add(pair.getName() + "=" + pair.getValue());
        }
        String newTokenUrl = getAccessTokenUrl + "?" + Joiner.on("&").join(newTokenParams);
        String tokenResult = "";
        try {
            tokenResult = getHttpRequest(newTokenUrl, tokenMap, 100000, "utf-8");
            if (Strings.isNullOrEmpty(tokenResult)) {
                throw new ServiceException("get token failed");
            }
            JSONObject json = JSONObject.fromObject(tokenResult);
            JSONObject jo = json.getJSONObject("data");
            String accessToken = jo.getString("access_token");
            return accessToken;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return null;
    }

    private static String getHttpRequest(String url, Map<String, String> map, int timeOut, String charSet) throws IOException {

        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse httpResponse = null;
        long beginTime = System.currentTimeMillis();
        try {
            HttpGet httpGet = new HttpGet();
            URIBuilder builder = new URIBuilder(url);
            httpGet.setURI(builder.build());
            if (StringUtils.isNotBlank(map.get("version"))) {
                httpGet.addHeader("version", "v3.0");
            }
            if (StringUtils.isNotBlank(map.get("access-token"))) {
                httpGet.addHeader("access-token", map.get("access-token"));
            }
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeOut).setConnectTimeout(timeOut).build();//设置请求和传输超时时间
            httpGet.setConfig(requestConfig);
            httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();

            String body = null;
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK && httpEntity != null) {
                if (StringUtils.isNotBlank(charSet)) {
                    body = EntityUtils.toString(httpEntity, charSet);
                } else {
                    body = EntityUtils.toString(httpEntity, "UTF-8");
                }
                EntityUtils.consume(httpEntity);
            }
            if (logger.isInfoEnabled()) {
                logUrlInfo(beginTime, url);
            }
            return body;
        } catch (Exception e) {
            logger.error(e.toString(), e);
        } finally {
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    logger.error(e.toString(), e);
                }
            }

            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    logger.error(e.toString(), e);
                }
            }
        }
        return null;
    }

    private static void logUrlInfo(long beginTime, String url) {
        if (System.currentTimeMillis() - beginTime > 1000) {
            logger.info("call url [{}] , use [{}] ms", url, System.currentTimeMillis() - beginTime);
        }
    }

    @Override
    public void saveUnbindLog(UserEntity entity) {
        userService.saveUnbindLog(entity);
    }

    /**
     * 通过userId判断是否为主管
     *
     * @param userId
     * @return
     */
    @Override
    public Boolean isDirector(Integer userId) {
        return userService.isDirector(userId);
    }

    @Override
    public UserEntity getById(int id) {
        return userMapper.getById(id);
    }

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

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

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

    @Override
    public void saveWxUser(WxUserEntity entity) {
        Map<String, Object> map = new HashMap<>(5);
        map.put("wxId", entity.getWxId());
        List<WxUserEntity> list = wxUserMapper.queryByConditions(map);
        if (CollectionUtils.isEmpty(list)) {
            wxUserMapper.save(entity);
        }
    }

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

    @Override
    public HResult saveRelation(UserWxRelation userWxRelation) {
        HResult result = new HResult();
        Map<String, Object> map = new HashMap<>(5);
        map.put("userId", userWxRelation.getUserId());
        map.put("wxId", userWxRelation.getWxId());
        List<UserWxRelation> list = relationMapper.queryByConditions(map);
        if (CollectionUtils.isNotEmpty(list)) {
            result.setStatus(-1);
            result.setErrorMessage("关系已存在，请勿添加");
            return result;
        }
        relationMapper.save(userWxRelation);
        return result;
    }

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

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

    @Autowired
    private DepartMapper departMapper;

    @Override
    public MapListResponse list(Map<String, Object> searchParams) {
        MapListResponse response = new MapListResponse();
        try {
            List<Map<String, Object>> list = relationMapper.queryList(searchParams);
            if (CollectionUtils.isNotEmpty(list)) {
                for (Map<String, Object> m : list) {
                    if (null != m.get("deptId")) {
                        int deptId = Integer.parseInt(m.get("deptId").toString());
                        DepartmentEntity dept = departMapper.queryById(deptId);
                        String cityId = dept.getCityID();
                        DepartmentResponse departmentResponse = department.getDepartmentById(Integer.valueOf(cityId));
                        DepartmentEntity departmentEntity = departmentResponse.getEntity();
                        m.put("city", departmentEntity.getName());
                    } else {
                        m.put("city", "");
                    }
                }
            }
            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 UserWxRelation getRelationById(int id) {
        return relationMapper.getById(id);
    }

    @Override
    public void update(UserWxRelation userWxRelation) {
        relationMapper.update(userWxRelation);
    }

    @Override
    public String getCityById(String userId) {
        return userMapper.getCityById(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() {
    }

    @Override
    public List<UserEntity> getDutyUserByCity(String cityCode) {
        Map<String, Object> param = new HashMap<>();
        param.put("cityCode", cityCode);
        return userMapper.getDutyUserByCity(param);
    }

    @Override
    public List<UserEntity> getUserByCity(String cityCode) {
        Map<String, Object> param = new HashMap<>();
        param.put("cityCode", cityCode);
        return userMapper.getUserByCity(param);
    }

    @Override
    public void deleteDutyById(Integer userId) {
        userMapper.deleteDutyById(userId);
    }

    @Override
    public void addDuty(UserEntity userEntity, Integer order) {
        userMapper.addDuty(userEntity.getRealName(), userEntity.getId(), new Date(), order);

    }

    @Override
    public void updateDutyStaff(DutyStaffEntity entity) {
        userMapper.updateDutyStaff(entity);
    }

    @Override
    public void updateDuty(Integer order, Integer id) {
        userMapper.updateDuty(order, id, new Date());
    }

    @Override
    public DutyStaffEntity pbelist(Integer userId) {

        return userMapper.selectBuyDutyId(userId);
    }
}
