package com.sunxung.factoring.service.sys.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.base.Joiner;
import com.sunxung.factoring.component.cache.CacheKeyGenerator;
import com.sunxung.factoring.component.cache.RedisCache;
import com.sunxung.factoring.component.exception.BusinessException;
import com.sunxung.factoring.component.exception.ValidatorException;
import com.sunxung.factoring.component.util.*;
import com.sunxung.factoring.dict.impl.FileModuleDict;
import com.sunxung.factoring.entity.GridPage;
import com.sunxung.factoring.entity.ValidatorEntity.ValidatorType;
import com.sunxung.factoring.entity.sys.*;
import com.sunxung.factoring.entity.sys.vo.GradationVo;
import com.sunxung.factoring.entity.sys.vo.SeachUser;
import com.sunxung.factoring.entity.sys.vo.SysGradationVo;
import com.sunxung.factoring.entity.weekWorkPlan.vo.SearchWeekWorkPlan;
import com.sunxung.factoring.mapper.sys.UserMapper;
import com.sunxung.factoring.service.sys.OrgService;
import com.sunxung.factoring.service.sys.PermissionService;
import com.sunxung.factoring.service.sys.RoleService;
import com.sunxung.factoring.service.sys.UserService;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @Description:系统用户业务层实现类
 * @Author:JingJiang
 * @E-mail:254702920@qq.com
 * @Date:2017年6月6日 下午6:27:50
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private OrgService orgService;
    @Autowired
    private RoleService roleService;
    @Autowired
    RedisCache redisCache;
    @Autowired
    private PermissionService permissionService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public User add(User user) {
        ValidatorUtil.validator(ValidatorType.ADD, user);
        user.setPassword(PasswordUtil.createHash(user.getPassword()));
        userMapper.add(user);
        addUserOrgRel(user);// 添加用户组织机构关联关系表
        Role role = null;
        if (user.getLoginName().equals(ConstantConversionUtil.ADMINISTORIES)) {
            role = roleService.getByRoleName(ConstantConversionUtil.ADMINISTORIES_DISPLAYNAME);
        } else if (user.getLoginName().equals(ConstantConversionUtil.BUSINESS_ADMINISTORIES)) {
            role = roleService.getByRoleName(ConstantConversionUtil.BUSINESS_ADMINISTORIES_DISPLAYNAME);
        }
        if (null != role) {
            UserRoleRel userRoleRel = new UserRoleRel();
            userRoleRel.setUserId(user.getId());
            userRoleRel.setAdmin(user.getAdmin());
            userRoleRel.setRoleId(role.getId());
            addUserRoleRel(userRoleRel);// 添加超级管理员或业务超管角色
        }
        user = get(user.getId());
        return user;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public User addUser(User user, HttpServletRequest request) {
        try {
            ValidatorUtil.validator(ValidatorType.ADD, user);
            // 上传头像
            addUserHeadImag(user, request);
            if (user.isRelationDingDing()) {
                // 同步用户信息数据到钉钉
                synchUser(user);
                if (StringUtil.isEmpty(user.getUserid())) {
                    throw new ValidatorException(CodeUtil.FAIL, "钉钉内用户ID不能为空");
                }
            }
            user.setPassword(PasswordUtil.createHash(user.getPassword()));
            user.setEnabled(true);
            //设置推荐码  姓名全拼大写字母+数字
            String s = PinYinUtil.toPinyin(user.getName()).toUpperCase();
            String code = "001";
            List<User> listByName = userMapper.getListByName(user.getName());
            if(listByName==null||listByName.size()>0){
                 code = String.format("%03d", listByName.size()+1);
            }
            user.setReferenceNumber(s+code);
            user.setPassword(PasswordUtil.createHash(user.getPassword()));
            userMapper.add(user);
            // 添加用户组织机构关联关系表
            addUserOrgRel(user);
            user = get(user.getId());
        } catch (Exception e) {
            throw new BusinessException(CodeUtil.FAIL, "新增用户信息出错了:" + e.getMessage());
        }
        return user;
    }

    private void addUserHeadImag(User user, HttpServletRequest request) throws IOException {
//        if (request instanceof MultipartHttpServletRequest) {
//            MultiValueMap<String, MultipartFile> multiValueMap = ((MultipartHttpServletRequest) request)
//                    .getMultiFileMap();
//            if (multiValueMap != null && CollectionUtil.isNotEmpty(multiValueMap.values())) {
//                String path = FileUtil.uploadSingleFile(request, FileModuleDict.ChildEnum.SYS_USER);
//                user.setHeadImgUrl(path);
//            }
//        }
    }

    private void synchUser(User user) {
        List<Long> dingDingOrgIdList = new ArrayList<>();
        if (null != user && null != user.getOrgIdList() && user.getOrgIdList().size() > 0) {
            List<Long> list = user.getOrgIdList();
            for (Long orgId : list) {
                Org org = orgService.get(orgId);
                if (null != org && null != org.getDepartmentId()) {
                    dingDingOrgIdList.add(org.getDepartmentId());
                }
            }
        }
    }

    /**
     * 添加用户和部门的关系
     *
     * @param user 用户对象实体类
     */
    private void addUserOrgRel(User user) {
        if (null != user && null != user.getId()) {
            List<UserOrgRel> userOrgRelList = user.getUserOrgRelList();
            if (null != userOrgRelList && userOrgRelList.size() > 0) {
                userOrgRelList.forEach((ug) -> {
                    Long orgId = ug.getOrgId();
                    String orgCode = orgService.get(orgId).getInternalCode();
                    Integer gradation = userMapper.getMaxGradationByOrgId(orgId);
                    userMapper.addUserOrgRel(user.getId(), orgId, orgCode, ug.isUserIdentity(),
                            gradation == null ? 0 : (gradation + 1));
                });
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public User update(User user, HttpServletRequest request) {
        try {
            ValidatorUtil.validator(ValidatorType.UPDATE, user);
            User before = get(user.getId());
            if (null != before) {
                String dingdingUserid = before.getUserid();
                // 添加用户头像
                addUserHeadImag(user, request);
                /* 修改当前用户的用户名，登录名 */
                userMapper.update(user);
                /** 1、关联到钉钉 **/
                if (user.isRelationDingDing()) {
                    /** 1.1、之前有绑定过 **/
                    if (StringUtil.isNotEmpty(dingdingUserid)) {
                        // 先删除用户和组织机构的关系
                        userMapper.deleteUserOrgRel(user.getId());
                        // 重新添加用户和组织机构的关系
                        addUserOrgRel(user);
                        // 填充钉钉部门
                        // 获取钉钉部门ID
                        List<Long> dingOrgIds = new ArrayList<Long>();
                        for (Long orgid : user.getOrgIdList()) {
                            Org org = orgService.get(orgid);
                            dingOrgIds.add(org.getDepartmentId());
                        }
                    } else {
                        /** 1.2、之前没有绑定过，同步到钉钉 **/
                        synchUser(user);
                        userMapper.update(user);
                    }
                } else {
                    /** 2、 不关联到钉钉 **/
                    // 先删除用户和组织机构的关系
                    userMapper.deleteUserOrgRel(user.getId());
                    // 重新添加用户和组织机构的关系
                    addUserOrgRel(user);
                }
            }
        } catch (Exception e) {
            throw new BusinessException(CodeUtil.FAIL, "修改用户信息出错了:" + e.getMessage());
        }
        return user;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(User user) {
        userMapper.update(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public User updateSimpleUserInfo(User user) {
        String mobile = user.getMobile();
        String name = user.getName();
        user = get(user.getId());
        user.setMobile(mobile);
        user.setName(name);
        ValidatorUtil.validator(ValidatorType.UPDATE, user);
        userMapper.update(user);
        // 当不是超级管理员的时候，修改用户名和手机号码，需要同步到钉钉
        return get(user.getId());
    }

    /**
     * 删除用户与岗位的关系
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean delete(Long id) {
        User user = userMapper.get(id);
        if (user != null) {
            redisCache.remove(CacheKeyGenerator.generateCacheKeyFromId(User.class, id));
        }
        // 删除当前用户岗位关系
        userMapper.deleteUserRoleRel(id);
        userMapper.deleteUserOrgRel(id);
        return userMapper.delete(id) > 0;
    }

    @Override
    public User get(Long id) {
        User user = (User) redisCache.get(CacheKeyGenerator.generateCacheKeyFromId(User.class, id));
        if (user == null) {
            user = userMapper.get(id);
        }
        return user;
    }

    @Override
    public User getDetail(Long id, Long orgId) {
        User user = get(id);
        autoRelativeName(user);
        // 根据orgId，查找该用户在当前部门是什么身份
        List<UserOrgRel> ugList = userMapper.getUserOrgRelByUserId(id);
        if (null != ugList && ugList.size() > 0) {
            ugList.forEach((u) -> {
                Org org = orgService.get(u.getOrgId());
                if (null != org) {
                    u.setOrgName(org.getName());
                }
            });
        }
        user.setUserOrgRelList(ugList);
        return user;
    }

    private void autoRelativeName(User user) {
        if (null != user && null != user.getId()) {
            List<UserOrgRel> userOrgRelList = userMapper.getOrgRelByUserId(user.getId());
            List<Long> orgIdList = new ArrayList<>();
            //StringBuffer relativeName = new StringBuffer();
            List<String> relativeNames = Lists.newArrayList();
            if (null != userOrgRelList && userOrgRelList.size() > 0) {
                for (UserOrgRel userOrgRel : userOrgRelList) {
                    Long orgId = userOrgRel.getOrgId();
                    relativeNames.add(orgService.getOrgRealNameExceptRoot(orgId));
                    orgIdList.add(orgId);
                }
            }
            if (!CollectionUtils.isEmpty(relativeNames)) {
                user.setRelativeName(Joiner.on("、").join(relativeNames));
            }else {
                user.setRelativeName("");
            }
            user.setOrgIdList(orgIdList);
        }
    }

    @Override
    public User getByLoginName(String loginName) {
        return userMapper.getByLoginName(loginName);
    }

    @Override
    public List<String> findAllLoginName() {
        return userMapper.findAllLoginName();
    }

    @Override
    public User validatorLoginName(String loginName, Long userId) {
        if (userId != null) {
            // 修改的时候验证登录名是否重复
            User user = get(userId);
            if (null != user) {
                String existLoginName = user.getLoginName();
                if (!existLoginName.equals(loginName)) {
                    return userMapper.getByLoginName(loginName);
                }
            }
        } else {
            // 新增的时候验证
            return userMapper.getByLoginName(loginName);
        }
        return null;
    }

    @Override
    public boolean updatePassword(Long id, String password, String oldPassword, String password1) {
        boolean bo = true;
        if (id == null || id.equals("") || !password.equals(password1)) {
            bo = false;
            throw new ValidatorException(CodeUtil.FAIL, "修改密码失败");
        }
        User user = userMapper.get(id);
        if (user == null) {
            bo = false;
            throw new ValidatorException(CodeUtil.FAIL, "修改密码失败");
        }
        if (!password.matches("[0-9A-Za-z]{6,16}")) {
            bo = false;
            throw new ValidatorException(CodeUtil.FAIL, "密码必须是6~16位数字和字母的组合！");
        }
        if (!PasswordUtil.validatePassword(oldPassword, user.getPassword())) {
            bo = false;
            throw new ValidatorException(CodeUtil.FAIL, "旧密码错误！");
        }
        if (bo == true && userMapper.resetPassword(user.getId(), PasswordUtil.createHash(password)) == 0) {
            bo = false;
            throw new ValidatorException(CodeUtil.FAIL, "用户密码修改失败！");
        }
        try {
            redisCache.flushAll();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean resetPassword(User user) {
        boolean flag = true;
        // 业务层老旧密码相似查询比较,重置密码
        if (null == user.getId()) {
            flag = false;
        }
        if (PasswordUtil.validatePassword(user.getPassword(), userMapper.getUserPasswordSimilar(user.getId()))) {
            flag = false;
            throw new ValidatorException(CodeUtil.FAIL, "该用户密码已经存在！");
        }
        if (userMapper.resetPassword(user.getId(), PasswordUtil.createHash(user.getPassword())) == 0) {
            flag = false;
            throw new ValidatorException(CodeUtil.FAIL, "该用户密码修改失败！");
        }
        return flag;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean modifyEnabled(String[] ids, boolean enabled) {
        boolean flag = true;
        if (null == ids || ids.length < 1) {
            throw new ValidatorException(CodeUtil.FAIL, "请选择数据");
        }
        for (String id : ids) {
            Long userId = Long.valueOf(id);
            flag = userMapper.modifyLock(userId, enabled) > 0;
            if (!flag) {
                return flag;
            }
        }
        return flag;
    }

    @Override
    public GridPage<User> findBySearch(SeachUser seachData) {
        Page<Object> objects = PageHelper.startPage(seachData.getPage(), seachData.getRows());
        List<User> listUser = userMapper.findBySearch(seachData);
        //Integer count = userMapper.countBySearch(seachData);

        return new GridPage<User>(seachData.getRows(), seachData.getPage(), objects.getTotal(), listUser);
    }

    /**
     * 用户管理修改模态框预加载已选中岗位多选框
     */
    @Override
    public User getUserRoleRelCheck(Long id) {
        User user = userMapper.get(id);
        // 岗位
        // List<Role> roles = roleService.findByOrgId(user.getOrg().getId());
        List<Role> roles = roleService.findAll();
        // 被选中的岗位
        List<UserRoleRel> userRoleRels = userMapper.getUserRoleByUserId(id);
        if (userRoleRels.isEmpty()) {
            for (Role role : roles) {
                role.setCheck(false);
            }
            user.setRoles(roles);
        } else {
            for (Role role : roles) {
                boolean is_check = false;
                boolean is_admin = false;
                for (UserRoleRel userRoleRel : userRoleRels) {
                    if (userRoleRel.getRoleId().equals(role.getId())) {
                        is_check = true;
                        if (userRoleRel.isAdmin()) {
                            is_admin = true;
                        }
                    }
                }
                role.setCheck(is_check);
                role.setAdmin(is_admin);
            }
            user.setRoles(roles);
        }
        return user;
    }

    /**
     * 获取所有岗位id
     */
    @Override
    public List<UserRoleRel> getUserRoleByUserId(Long id) {
        return userMapper.getUserRoleByUserId(id);
    }

    /**
     * 根据userId获取缓存中的user信息
     *
     * @param userId
     * @return
     */
    public User getRedisByUserId(String userId) {
        User user = (User) redisCache.get(CacheKeyGenerator.generateCacheKeyFromString(User.class, userId));
        return user;
    }

    /**
     * 缓存user
     *
     * @param user
     */
    private void cacheUser(User user) {
        if (user != null) {
            String cacheKey = CacheKeyGenerator.generateCacheKeyFromId(User.class, user.getId());
            redisCache.set(cacheKey, user);
            String cacheKey2 = CacheKeyGenerator.generateCacheKeyFromString(User.class, user.getLoginName());
            redisCache.set(cacheKey2, user);
        }
    }

    @Override
    public Boolean isRoleAdmin(Long roleId, Long userId) {
        return userMapper.isRoleAdmin(roleId, userId);
    }

    @Override
    public Integer countAllUser() {
        int count = userMapper.countBySearch(new SeachUser());
        return count;
    }

    @Override
    public List<User> findByUserAll() {
        return userMapper.findBySearch(null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deletes(String[] ids) {
        boolean flag = true;
        if (null == ids || ids.length < 1) {
            throw new ValidatorException(CodeUtil.FAIL, "请选择删除的数据");
        }
        for (String id : ids) {
            Long userId = Long.valueOf(id);
            userMapper.deleteUserOrgRel(userId);
            User user = get(userId);
            flag = delete(userId);
            if (!flag) {
                return flag;
            }
        }
        return flag;
    }

    @Override
    public List<Long> getOrgIdByUserId(Long userId) {
        List<Long> orgIdList = new ArrayList<>();
        List<UserOrgRel> userOrgRelList = userMapper.getOrgRelByUserId(userId);
        for (UserOrgRel userOrgRel : userOrgRelList) {
            orgIdList.add(userOrgRel.getOrgId());
        }
        return orgIdList;
    }

    @Override
    public Integer countByOrgcode(SearchWeekWorkPlan search) {
        return userMapper.countByOrgcode(search);
    }

    @Override
    public Integer countUserOrgRelByOrgCode(String orgCode) {
        return userMapper.countUserOrgRelByOrgCode(orgCode);
    }

    @Override
    public void addUserRoleRel(UserRoleRel userRoleRel) {
        userMapper.addUserRoleRel(userRoleRel);
    }

    @Override
    public UserRoleRel getRoleRelByRoleId(Long roleId, Long userId) {
        return userMapper.getRoleRelByRoleId(roleId, userId);
    }

    @Override
    public GridPage<User> findByRoleId(SeachUser seachData) {
        Page<User> page = PageHelper.startPage(seachData.getPage(), seachData.getRows());
        List<User> listUser = userMapper.findByRoleId(seachData);
        if (null != listUser && listUser.size() > 0) {
            for (User u : listUser) {
                autoRelativeName(u);
            }
        }
        return new GridPage<User>(seachData.getRows(), seachData.getPage(), page.getTotal(), listUser);
    }

    @Override
    public GridPage<User> findByOrgcode(SearchWeekWorkPlan search) {
        List<User> userList = new ArrayList<User>();
        List<Org> normalOrgList = new ArrayList<Org>();
        List<Org> orgList = new ArrayList<Org>();
        if (null != search && null != search.getDepartment()) {
            Org org = orgService.get(search.getDepartment().getId());
            search.setDepartment(org);
        }
        // 判断当前登录用户是否具有查看全部人员的权限
        List<Long> permissionIds = permissionService.getPermissionIdByUserId(ThreadLocalUtil.getUser().getId());
        Permission permission = permissionService.getByEname(ConstantConversionUtil.PLAN_SEE_ALL_ENAME);
        if (null != permission && permissionIds.contains(permission.getId())) {
            search.setSellAll(true);
        } else {
            // 获取当前登录用户所属的所有部门
            List<Long> orgIdsList = ThreadLocalUtil.getUser().getOrgIdList();
            if (null != orgIdsList && orgIdsList.size() > 0) {
                for (Long orgId : orgIdsList) {
                    Org org = orgService.get(orgId);
                    orgList.add(org);
                    // 判断当前登录用户所在的当前部门的身份是否是普通身份，是则添加到集合中
                    UserOrgRel orgRel = getByUserIdAndOrgId(ThreadLocalUtil.getUser().getId(), orgId);
                    if (null != orgRel && !orgRel.isUserIdentity()) {
                        normalOrgList.add(org);
                    }
                }
            }
            // 这里虽然返回的user对象，但是SQL语句为了使用distinct去重只是查询用户ID单个字段，所以需要再次调用get方法填充user的完整数据，并且重新定义的userList集合存放用户完整数据
            search.setNormalOrgList(normalOrgList);
            search.setOrgList(orgList);
        }
        PageHelper.startPage(search.getPage(), search.getRows()).size();
        List<User> list = userMapper.findByOrgcode(search);
        Integer count = userMapper.countByOrgcode(search);
        if (null != list && list.size() > 0) {
            for (User user : list) {
                User us = get(user.getId());
                List<Long> orgIdList = getOrgIdByUserId(user.getId());
                us.setOrgIdList(orgIdList);
                userList.add(us);
            }
        }
        return new GridPage<User>(search.getRows(), search.getPage(), count, userList);
    }

    @Override
    public UserOrgRel getByUserIdAndOrgId(Long userId, Long orgId) {
        return userMapper.getByUserIdAndOrgId(userId, orgId);
    }

    @Override
    public List<User> findByOrgcodeList(SearchWeekWorkPlan search) {
        List<Org> normalOrgList = new ArrayList<Org>();
        List<Org> orgList = new ArrayList<Org>();
        if (null != search && null != search.getDepartment()) {
            Org org = orgService.get(search.getDepartment().getId());
            search.setDepartment(org);
        }
        // 判断当前登录用户是否具有查看周工作计划统计全部人员的权限
        // List<Long> permissionIds = permissionService.getPermissionIdByUserId(ThreadLocalUtil.getUser().getId());
        // Permission permission = permissionService.getByEname(ConstantConversionUtil.MEETING_SELL_ALL_ENAME);
        // if (null != permission && permissionIds.contains(permission.getId())) {
        // search.setSellAll(true);
        // }
        // 判断当前登录用户是否具有查看周工作计划统计全部人员的权限，无权限则需筛选出可查看的用户
        if (null == search.getSellAll()) {
            // 获取当前登录用户所属的所有部门
            List<Long> orgIdsList = ThreadLocalUtil.getUser().getOrgIdList();
            if (null != orgIdsList && orgIdsList.size() > 0) {
                for (Long orgId : orgIdsList) {
                    Org org = orgService.get(orgId);
                    orgList.add(org);
                    // 判断当前登录用户所在的当前部门的身份是否是普通身份，是则添加到集合中
                    UserOrgRel orgRel = getByUserIdAndOrgId(ThreadLocalUtil.getUser().getId(), orgId);
                    if (null != orgRel && !orgRel.isUserIdentity()) {
                        normalOrgList.add(org);
                    }
                }
            }
            // 这里虽然返回的user对象，但是SQL语句为了使用distinct去重只是查询用户ID单个字段，所以需要再次调用get方法填充user的完整数据，并且重新定义的userList集合存放用户完整数据
            search.setNormalOrgList(normalOrgList);
            search.setOrgList(orgList);
        }
        List<User> list = userMapper.findByOrgcode(search);
        if (null != list && list.size() > 0) {
            for (User user : list) {
                user.setName(get(user.getId()).getName());
            }
        }
        return list;
    }

    @Override
    public User getByDingdingUserId(String userId) {
        User user = userMapper.getByDingdingUserId(userId);
        if (null != user) {
            List<Long> orgIds = getOrgIdByUserId(user.getId());
            if (null != orgIds && orgIds.size() > 0) {
                String department = "";
                for (Long orgId : orgIds) {
                    department += orgService.getOrgRealNameExceptRoot(orgId) + "\t\t";
                }
                user.setDepartment(department);
            }
        }
        return user;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean adjustOrder(SysGradationVo sysVo) {
        boolean b = false;
        if (null != sysVo && null != sysVo.getList() && sysVo.getList().size() > 0) {
            for (GradationVo vo : sysVo.getList()) {
                if (null != vo.getId()) {
                    b = userMapper.adjustOrder(vo.getId(), vo.getGradation(), vo.getUserId()) > 0;
                }
            }
        }
        return b;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean adjustDepartment(User user) {
        boolean b = false;
        if (null != user) {
            // 重新添加用户和组织机构的关系
            updateUserOrgRel(user);
            // 调整钉钉用户部门关系
            if (null != user.getOrgIdList() && user.getOrgIdList().size() > 0) {
            }
        }
        return b;
    }

    private void updateUserOrgRel(User user) {
        if (null != user && null != user.getId() && user.getOrgIdList().size() > 0) {
            Long userId = user.getId();
            List<UserOrgRel> oldList = userMapper.getOrgRelByUserId(userId);
            Map<Long, UserOrgRel> map = new HashMap<>();
            if (null != oldList) {
                for (UserOrgRel userOrgRel : oldList) {
                    map.put(userOrgRel.getOrgId(), userOrgRel);
                }
            }
            // 先删除用户和组织机构关系
            userMapper.deleteUserOrgRel(user.getId());
            for (Long orgId : user.getOrgIdList()) {
                String orgCode = orgService.get(orgId).getInternalCode();
                // UserOrgRel userOrgRel = getByUserIdAndOrgId(user.getId(), orgId);
                UserOrgRel userOrgRel = map.get(orgId);
                // 获取当前部门下面最大的排序数字
                Integer gradation = userMapper.getMaxGradationByOrgId(orgId);
                if (null != userOrgRel) {
                    userMapper.addUserOrgRel(user.getId(), orgId, orgCode, userOrgRel.isUserIdentity(),
                            gradation == null ? 0 : (gradation + 1));
                } else {
                    userMapper.addUserOrgRel(user.getId(), orgId, orgCode, false,
                            gradation == null ? 0 : (gradation + 1));
                }
            }
        }
    }

    @Override
    public List<User> getUserList(Long orgId) {
        SeachUser search = new SeachUser();
        search.setOrgId(orgId);
        return userMapper.findBySearch(search);
    }

    @Override
    public List<User> findList(String keyword) {
        return userMapper.findList(keyword);
    }

    @Override
    public String getDepartmentByUserId(Long userId) {
        List<Long> orgIds = getOrgIdByUserId(userId);
        String department = "";
        if (null != orgIds && orgIds.size() > 0) {
            for (Long orgId : orgIds) {
                department += orgService.getOrgRealNameExceptRoot(orgId) + "\t\t";
            }
        }
        return department;
    }

    @Override
    public List<Long> findSuperiorByUserId(Long userId) {
        List<Long> superiorList = new ArrayList<>();
        List<UserOrgRel> userOrgRelList = userMapper.findUserOrgRel(userId, null);
        List<UserOrgRel> superiorRelList = null;
        if (null != userOrgRelList && userOrgRelList.size() > 0) {
            for (UserOrgRel rel : userOrgRelList) {
                if (rel.isUserIdentity()) {// 当userId为“上级”则获取父部门“上级”身份的用户。
                    Org org = orgService.get(rel.getOrgId());
                    if (null != org.getParent()) {
                        superiorRelList = userMapper.findUserOrgRel(null, org.getParent().getId());
                    }
                } else {
                    superiorRelList = userMapper.findUserOrgRel(null, rel.getOrgId());
                }
                if (null != superiorRelList && superiorRelList.size() > 0) {
                    for (UserOrgRel superior : superiorRelList) {
                        // 注意：userId为多个平级部门的“上级”，那么父部门就会出现重复，此时需要过滤掉重复获取的父部门“上级”身份的用户
                        if (superior.isUserIdentity() && !superiorList.contains(superior.getUserId())) {
                            superiorList.add(superior.getUserId());
                        }
                    }
                }
            }
        }
        return superiorList;
    }

    @Override
    public List<Long> findSuperiorByOrgId(Long orgId) {
        List<Long> superiorList = new ArrayList<>();
        List<UserOrgRel> userOrgRelList = userMapper.findUserOrgRel(null, orgId);
        if (null != userOrgRelList && userOrgRelList.size() > 0) {
            for (UserOrgRel rel : userOrgRelList) {
                if (rel.isUserIdentity()) {
                    superiorList.add(rel.getUserId());
                }
            }
        }
        return superiorList;
    }

    @Override
    public List<Long> findSuperiorByOrgIdUserId(Long orgId, Long userId) {
        if (null != orgId && null != userId) {
            List<Long> superiorList = new ArrayList<>();
            List<UserOrgRel> userOrgRelList = userMapper.findUserOrgRel(null, orgId);
            if (null != userOrgRelList && userOrgRelList.size() > 0) {
                List<UserOrgRel> filter = userOrgRelList.stream()
                        .filter(t -> t.isUserIdentity() && (long) t.getUserId() == (long) userId)
                        .collect(Collectors.toList());
                if (null != filter && filter.size() > 0) {
                    Org org = orgService.get(orgId);
                    if (null != org.getParent()) {
                        userOrgRelList = userMapper.findUserOrgRel(null, org.getParent().getId());
                    }
                }
                for (UserOrgRel rel : userOrgRelList) {
                    if (rel.isUserIdentity()) {
                        superiorList.add(rel.getUserId());
                    }
                }
            }
            return superiorList;
        }
        return null;
    }

    @Override
    public List<Long> findCurrentAndParentOrgUserByUserId(Long userId) {
        if (null != userId) {
            List<UserOrgRel> userOrgRelList = userMapper.findUserOrgRel(userId, null);
            if (null != userOrgRelList && userOrgRelList.size() > 0) {
                List<Long> list = new ArrayList<>();
                for (UserOrgRel rel : userOrgRelList) {
                    // 本部门用户ID
                    list.addAll(userMapper.findUserIdByOrgId(rel.getOrgId()));
                    // 本部门所有父部门用户ID
                    Org org = orgService.get(rel.getOrgId());
                    while (null != org && null != org.getParent()) {
                        list.addAll(userMapper.findUserIdByOrgId(org.getParent().getId()));
                        org = orgService.get(org.getParent().getId());
                    }
                }
                return list.parallelStream().distinct().collect(Collectors.toList());
            }
        }
        return null;
    }

    @Override
    public List<Long> findCurrentAndSubOrgUserByUserId(Long userId) {
        if (null != userId) {
            List<UserOrgRel> userOrgRelList = userMapper.findUserOrgRel(userId, null);
            if (null != userOrgRelList && userOrgRelList.size() > 0) {
                List<Long> list = new ArrayList<>();
                for (UserOrgRel rel : userOrgRelList) {
                    list.addAll(orgService.findUserIdByOrgCode(rel.getOrgCode()));
                }
                return list.parallelStream().distinct().collect(Collectors.toList());
            }
        }
        return null;
    }

    @Override
    public List<Long> findUserIdByOrgId(Long orgId) {
        return userMapper.findUserIdByOrgId(orgId);
    }

    @Override
    public List<User> findDetailSuperiorByOrgId(Long orgId) {
        List<User> superiorList = new ArrayList<>();
        List<UserOrgRel> userOrgRelList = userMapper.findUserOrgRel(null, orgId);
        if (null != userOrgRelList && userOrgRelList.size() > 0) {
            for (UserOrgRel rel : userOrgRelList) {
                if (rel.isUserIdentity()) {
                    superiorList.add(userMapper.get(rel.getUserId()));
                }
            }
        }
        return superiorList;
    }

    @Override
    public List<UserOrgRel> findOrgRelByUserId(Long userId) {
        List<UserOrgRel> userOrgRelList = userMapper.findUserOrgRel(userId, null);
        if (null != userOrgRelList && userOrgRelList.size() > 0) {
            for (UserOrgRel rel : userOrgRelList) {
                if (null != rel) {
                    Org org = orgService.get(rel.getOrgId());
                    if (null != org) {
                        rel.setOrgName(org.getName());
                    }
                }
            }
        }
        return userOrgRelList;
    }

    @Override
    public List<User> findUserByRoleId(Long roleId) {
        SeachUser search = new SeachUser();
        search.setRoleId(roleId);
        List<User> list = userMapper.findByRoleId(search);
        return list;
    }

    @Override
    public List<User> findUserByRoleName(String roleName) {
        List<User> list = new ArrayList<>();
        List<Long> userIds = findUserIdByRole(roleName);
        if (null != userIds && userIds.size() > 0) {
            for (Long userId : userIds) {
                User user = get(userId);
                list.add(user);
            }
        }
        return list;
    }

    @Override
    public List<Long> findUserIdByRole(String roleName) {
        Role role = roleService.getByRoleName(roleName);
        if (null != role) {
            return userMapper.findUserIdByRoleId(role.getId());
        }
        return null;
    }

    @Override
    public List<Long> findViewByOrgCode(SearchWeekWorkPlan search) {
        List<Org> normalOrgList = new ArrayList<Org>();
        List<Org> orgList = new ArrayList<Org>();
        // if (null != search && null != search.getDepartment()) {
        // Org org = orgService.get(search.getDepartment().getId());
        // search.setDepartment(org);
        // }
        // // 判断当前登录用户是否具有查看周工作计划统计全部人员的权限
        // List<Long> permissionIds = permissionService.getPermissionIdByUserId(ThreadLocalUtil.getUser().getId());
        // Permission permission = permissionService.getByEname(ConstantConversionUtil.MEETING_SELL_ALL_ENAME);
        // if (null != permission && permissionIds.contains(permission.getId())) {
        // search.setSellAll(true);
        // } else {
        // 获取当前登录用户所属的所有部门
        List<Long> orgIdsList = ThreadLocalUtil.getUser().getOrgIdList();
        if (null != orgIdsList && orgIdsList.size() > 0) {
            for (Long orgId : orgIdsList) {
                Org org = orgService.get(orgId);
                orgList.add(org);
                // 判断当前登录用户所在的当前部门的身份是否是普通身份，是则添加到集合中
                UserOrgRel orgRel = getByUserIdAndOrgId(ThreadLocalUtil.getUser().getId(), orgId);
                if (null != orgRel && !orgRel.isUserIdentity()) {
                    normalOrgList.add(org);
                }
            }
        }
        // 这里虽然返回的user对象，但是SQL语句为了使用distinct去重只是查询用户ID单个字段，所以需要再次调用get方法填充user的完整数据，并且重新定义的userList集合存放用户完整数据
        search.setNormalOrgList(normalOrgList);
        search.setOrgList(orgList);
        // }
        List<Long> list = userMapper.findViewByOrgCode(search);
        return list;
    }

    @Override
    public User getByName(String name) {
        return userMapper.getByName(name);
    }

    @Override
    public List<User> orderUserByOrgGradation(SearchWeekWorkPlan search) {
        return userMapper.orderUserByOrgGradation(search);
    }

    @Override
    public List<Map<String, Object>> findAll() {
        List<User> userList = userMapper.findBySearch(null);
        List<Map<String, Object>> mapList = userList.stream().filter(distinctByKey(User::getId)).filter(user -> user.isEnabled()).map(user -> {
            Map<String, Object> result = new HashMap<>();
            result.put("id", user.getId());
            result.put("name", user.getName());
            return result;
        }).collect(Collectors.toList());

        return mapList;
    }

    @Override
    public List<String> findAllEnabledUserEmail() {
        return userMapper.findAllEnabledUserEmail();
    }

    @Override
    public User selectByEnterpriseCustomerId(long enterpriseCustomerId) {
        User user = userMapper.selectByEnterpriseCustomerId(enterpriseCustomerId);
        return user;
    }

    @Override
    public void addCustomerUser(User user) {
        user.setPassword(PasswordUtil.createHash(user.getPassword()));
        userMapper.add(user);
    }

    @Override
    public void updateCustomerUser(User user) {
        user.setPassword(PasswordUtil.createHash(user.getPassword()));
        userMapper.update(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteUserOrgRelByOrgId(Long orgId) {
        userMapper.deleteUserOrgRelByOrgId(orgId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addUserOrgRel(UserOrgRel userOrgRel) {
        userMapper.addUserOrgRel(userOrgRel.getUserId(), userOrgRel.getOrgId(),
                userOrgRel.getOrgCode(), userOrgRel.isUserIdentity(), userOrgRel.getGradation());
    }

    @Override
    public User addBySop(User user) {
        ValidatorUtil.validator(ValidatorType.ADD, user);
        userMapper.add(user);
        user = get(user.getId());
        return user;
    }


    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Set<Object> seen = ConcurrentHashMap.newKeySet();
        return t -> seen.add(keyExtractor.apply(t));
    }
}
