package com.sunyard.ssp.modules.user.controller;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.sunyard.chsm.constant.SecurityConstant;
import com.sunyard.ssp.common.PageVo;
import com.sunyard.ssp.common.Result;
import com.sunyard.ssp.common.constant.CommonConstant;
import com.sunyard.ssp.common.enums.UserHeaderTypeEnum;
import com.sunyard.ssp.modules.user.entity.ScDepartment;
import com.sunyard.ssp.modules.user.entity.ScDepartmentHeader;
import com.sunyard.ssp.modules.user.entity.ScPermission;
import com.sunyard.ssp.modules.user.entity.ScRole;
import com.sunyard.ssp.modules.user.entity.ScUser;
import com.sunyard.ssp.modules.user.entity.ScUserRole;
import com.sunyard.ssp.modules.user.service.IScDepartmentHeaderService;
import com.sunyard.ssp.modules.user.service.IScDepartmentService;
import com.sunyard.ssp.modules.user.service.IScRoleService;
import com.sunyard.ssp.modules.user.service.IScUserRoleService;
import com.sunyard.ssp.modules.user.service.IScUserService;
import com.sunyard.ssp.modules.user.utils.validator.UserValidator;
import com.sunyard.ssp.redis.RedisObjectOperation;
import com.sunyard.ssp.utils.PageUtil;
import com.sunyard.ssp.utils.ResultUtil;
import com.sunyard.ssp.utils.SecurityUtil;
import com.sunyard.ssp.utils.UsernameUtil;
import com.sunyard.ssp.vo.ScUserVo;
import com.sunyard.ssp.vo.SearchVo;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static com.sunyard.ssp.common.constant.CommonConstant.DEFAULT_USER_ROOT_ID;
import static com.sunyard.ssp.common.constant.CommonConstant.DEPARTMENT_ROOT_ID;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author tsz
 * @since 2020-03-11
 */
@RestController
@Slf4j
@RequestMapping("/user")
@Transactional
public class ScUserController {

    @Autowired
    UserValidator userValidator;

    @Autowired
    SecurityUtil securityUtil;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    private RedisObjectOperation redisObjectOperation;

    @Autowired
    IScUserService userService;

    @Autowired
    IScUserRoleService userRoleService;

    @Autowired
    IScDepartmentService departmentService;

    @Autowired
    IScDepartmentHeaderService departmentHeaderService;

    @Autowired
    IScRoleService roleService;


    @RequestMapping(value = "/info",method = RequestMethod.GET)
    public Result<ScUser> getUserInfo(){

        ScUser u = securityUtil.getCurrUser();
        return new ResultUtil<ScUser>().setData(u);
    }

    @RequestMapping(value = "/infoResult", method = RequestMethod.GET)
    public Result<Object> getUserInfoResult(@RequestParam List<String> powers) {

        ScUser u = securityUtil.getCurrUser();
        // 清除持久上下文环境 避免后面语句导致持久化
        List<String> collect = u.getPermissions().stream().map(ScPermission::getTitle).collect(Collectors.toList());
        List<String> permissions = new ArrayList<>();
        for (String power : powers) {
            boolean contains = collect.contains(power);
            if ( contains ){
                permissions.add(power);
            }
        }

        return new ResultUtil<Object>().setData(permissions);
    }

    @RequestMapping(value = "/initialization/check", method = RequestMethod.GET)
    public Result<Object> initializationCheck() {
        QueryWrapper<ScUser> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.like("USERNAME", "admin%");
        List<ScUser> list = userService.list(userQueryWrapper);
        for (ScUser scUser : list) {
            if (scUser.getUPublickey()!=null) {
                return new ResultUtil<Object>().setData(false);
            }
        }
        return new ResultUtil<Object>().setData(true);
    }

    @RequestMapping(value = "/edit",method = RequestMethod.POST)
    public Result<Object> editOwn(@ModelAttribute("user") ScUser u){

        if(DEFAULT_USER_ROOT_ID.equals(u.getId())){
            String resStr = "默认用户禁止编辑";
            if(u.getStatus() != null){
                resStr = "默认用户禁止禁用";
            }
            return new ResultUtil<Object>().setErrorMsg(resStr);
        }
        try {
            ScUser old = securityUtil.getCurrUser();
            u.setUsername(old.getUsername());
            u.setPassword(old.getPassword());
            u.setId(securityUtil.getCurrUser().getId());
            u.setPassUpdateTime(old.getPassUpdateTime());

            //若修改手机或邮箱,判断是否合法,非法就不改
            if(StrUtil.isNotBlank(u.getTel())){
                if (!UsernameUtil.Mobile(u.getTel())){
                    return new ResultUtil<Object>().setErrorMsg("手机号格式错误");
                }
                u.setTel(old.getTel());
            }

            if(StrUtil.isNotBlank(u.getEmail())){
                if (!UsernameUtil.Email(u.getEmail())){
                    return new ResultUtil<Object>().setErrorMsg("邮箱格式错误");
                }
                u.setEmail(old.getEmail());
            }

            // 若修改了手机和邮箱判断是否唯一
            if ( StrUtil.isNotBlank(u.getTel())&&!old.getTel().equals(u.getTel()) ){
                if(userService.list(new QueryWrapper<ScUser>().lambda().eq(ScUser::getTel,u.getTel()))!=null){
                    return new ResultUtil<Object>().setErrorMsg("该手机号已绑定其他账户");
                }
            }

            if ( StrUtil.isNotBlank(u.getEmail())&&!old.getEmail().equals(u.getEmail()) ){
                if(userService.list(new QueryWrapper<ScUser>().lambda().eq(ScUser::getEmail,u.getEmail()))!=null){
                    return new ResultUtil<Object>().setErrorMsg("该邮箱已绑定其他账户");
                }
            }

            /*if(StringUtils.isNotBlank(u.getPosition()) && !u.getPosition().equals(old.getPosition())){
                throw new KeeperException("职位仅限管理员修改");
            }*/

            if(!userService.updateById(u)){
                return new ResultUtil<Object>().setErrorMsg("修改失败");
            }

            return new ResultUtil<Object>().setSuccessMsg("修改成功");
        } catch ( Exception e ){
            log.error("用户修改个人信息失败", e.getMessage() , e);
            return new ResultUtil<Object>().setErrorMsg("修改失败");
        }

    }

    @RequestMapping(value = "/admin/edit",method = RequestMethod.POST)
    public Result<Object> edit(@ModelAttribute("user") ScUser u,
                               @RequestParam(required = false) Long[] roleIds){
        if(DEFAULT_USER_ROOT_ID.equals(u.getId())){
            String resStr = "默认用户禁止编辑";
            if(u.getStatus() != null){
                resStr = "默认用户禁止禁用";
            }
            return new ResultUtil<Object>().setErrorMsg(resStr);
        }

        try {
            if( StrUtil.isBlank(u.getUsername()) || StrUtil.isBlank(u.getUsername())){
                return new ResultUtil<Object>().setErrorMsg("缺少必需字段");
            }
            ScUser old = userService.getById(u.getId());

            //若修改了用户名
            if(!old.getUsername().equals(u.getUsername())){
                return new ResultUtil<Object>().setErrorMsg("用户名禁止修改");
            }

            //若修改手机或邮箱,判断是否合法,非法就不改
            if(StrUtil.isNotBlank(u.getTel()) && !UsernameUtil.Mobile(u.getTel())){
                u.setTel(old.getTel());
            }

            if(StrUtil.isNotBlank(u.getEmail()) && !UsernameUtil.Email(u.getEmail())){
                u.setEmail(old.getTel());
            }

            // 若修改了手机和邮箱判断是否唯一
            if ( StrUtil.isNotBlank(u.getTel())&&!u.getTel().equals(old.getTel()) ){
                if(CollectionUtils.isNotEmpty(userService.list(new QueryWrapper<ScUser>().lambda().eq(ScUser::getTel,u.getTel())))){
                    return new ResultUtil<Object>().setErrorMsg("该手机号已绑定其他账户");
                }
            }

            if ( StrUtil.isNotBlank(u.getEmail())&&!u.getEmail().equals(old.getEmail()) ){
                if(CollectionUtils.isNotEmpty(userService.list(new QueryWrapper<ScUser>().lambda().eq(ScUser::getEmail,u.getEmail())))){
                    return new ResultUtil<Object>().setErrorMsg("该邮箱已绑定其他账户");
                }
            }

            u.setPassword(old.getPassword());
            u.setPassUpdateTime(old.getPassUpdateTime());
            if(!userService.updateById(u)){
                return new ResultUtil<Object>().setErrorMsg("修改失败");
            }

            //删除该用户角色
            userRoleService.remove(new QueryWrapper<ScUserRole>().lambda().eq(ScUserRole::getUserId,u.getId()));
            if(roleIds!=null&&roleIds.length>0){
                //新角色
                for(Long roleId : roleIds){
                    ScUserRole ur = new ScUserRole();
                    ur.setRoleId(roleId);
                    ur.setUserId(u.getId());
                    userRoleService.save(ur);
                }
            }
            //手动删除缓存
            String loginTimekey = "loginTimeLimit:"+u.getUsername();
            String flagKey = "loginFailFlag:"+u.getUsername();

            redisTemplate.delete(loginTimekey);
            redisTemplate.delete(flagKey);
            redisTemplate.delete("userRole::"+u.getId());
            redisTemplate.delete("userRole::depIds:"+u.getId());
            return new ResultUtil<Object>().setSuccessMsg("修改成功");
        } catch (Exception e){
            return new ResultUtil<Object>().setErrorMsg(e.getMessage());
        }

    }

    @InitBinder("user")
    public void initUserBinder(WebDataBinder binder) {
        binder.replaceValidators(userValidator);
    }

    @RequestMapping(value = "/modifyPass", method = RequestMethod.POST)
    public Result<Object> modifyPass(@RequestParam String password,
                                     @RequestParam String newPass,
                                     @RequestParam String passStrength) {

        ScUser user = securityUtil.getCurrUser();

        if (!new BCryptPasswordEncoder().matches(password, user.getPassword())) {
            return new ResultUtil<Object>().setErrorMsg("旧密码不正确");
        }

        String newEncryptPass = new BCryptPasswordEncoder().encode(newPass);
        user.setPassword(newEncryptPass);
        user.setPassUpdateTime(LocalDateTime.now());
        if(!userService.updateById(user)){
            return new ResultUtil<Object>().setErrorMsg("修改密码失败");
        }

        //手动更新缓存
        redisTemplate.delete("user::" + user.getUsername());

        return new ResultUtil<Object>().setSuccessMsg("修改密码成功");
    }

    @RequestMapping(value = "/reset", method = RequestMethod.POST)
    public Result<Object> reset() {
        UpdateWrapper<ScUser> updateWrapper = new UpdateWrapper<ScUser>();
        // 将绑定的UKEY证书都清空
        updateWrapper.set("U_PUBLICKEY", null);
        userService.update(updateWrapper);
        return new ResultUtil<Object>().setSuccessMsg("重置成功");
    }




    @RequestMapping(value = "/admin/modifyPass", method = RequestMethod.POST)
    public Result<Object> adminModifyPass(@RequestParam String newPass, @RequestParam String userId) {

        ScUser user = userService.getById(userId);

        if(user == null){
            return new ResultUtil<Object>().setErrorMsg("用户不存在");
        }

        String newEncryptPass = new BCryptPasswordEncoder().encode(newPass);
        user.setPassword(newEncryptPass);
        user.setPassUpdateTime(LocalDateTime.now());
        if(!userService.updateById(user)){
            return new ResultUtil<Object>().setErrorMsg("修改密码失败");
        }

        //手动更新缓存
        String loginTimekey = "loginTimeLimit:"+user.getUsername();
        String flagKey = "loginFailFlag:"+user.getUsername();

        redisTemplate.delete(loginTimekey);
        redisTemplate.delete(flagKey);
        redisTemplate.delete("user::" + user.getUsername());

        return new ResultUtil<Object>().setSuccessMsg("修改密码成功");
    }


    @RequestMapping(value = "/getByCondition", method = RequestMethod.GET)
    public Result<org.springframework.data.domain.Page<ScUser>> getByCondition(@ModelAttribute() ScUser user,
                                                                             @ModelAttribute SearchVo searchVo,
                                                                             @ModelAttribute PageVo pageVo) {

        org.springframework.data.domain.Page<ScUser> page = userService.findByCondition(user, searchVo, PageUtil.initPage(pageVo));
        for (ScUser u : page.getContent()) {
            // 关联部门
            if (u.getOrganizationId() != null) {
                ScDepartment department = departmentService.getById(u.getOrganizationId());
                u.setDepartmentTitle(department.getTitle());
            }

            //记录用户是否为部门负责人
            Integer type = departmentHeaderService.getHeaderTypeByUserId(u.getId());
            u.setHeaderTypeKey(type);
            u.setHeaderTypeName(UserHeaderTypeEnum.getNameByKey(type));

            // 关联角色
            List<ScRole> list = userRoleService.findByUserId(u.getId());
            u.setRoles(list);
            // 清除持久上下文环境 避免后面语句导致持久化
            u.setPassword(null);
        }
        return new ResultUtil<org.springframework.data.domain.Page<ScUser>>().setData(page);
    }


    @RequestMapping(value = "/searchByName", method = RequestMethod.GET)
    @ApiOperation(value = "通过用户名搜索用户")
    public Result<List<ScUser>> searchByName(@RequestParam String username) throws UnsupportedEncodingException {

        List<ScUser> list = userService.list(new QueryWrapper<ScUser>().lambda()
                .like(ScUser::getUsername, "%" + URLDecoder.decode(username, "utf-8") + "%")
                .eq(ScUser::getStatus, CommonConstant.STATUS_NORMAL));
        return new ResultUtil<List<ScUser>>().setData(list);
    }

    @RequestMapping(value = "/searchByNickName", method = RequestMethod.GET)
    @ApiOperation(value = "通过昵称搜索用户")
    public Result<List<ScUser>> searchByNickName(@RequestParam String nickName) throws UnsupportedEncodingException {

        List<ScUser> list = userService.list(new QueryWrapper<ScUser>().lambda()
                .like(ScUser::getRealname, "%" + URLDecoder.decode(nickName, "utf-8") + "%")
                .eq(ScUser::getStatus, CommonConstant.STATUS_NORMAL));
        for (ScUser u : list) {
            // 关联部门
            if (u.getOrganizationId() != null) {
                ScDepartment department = departmentService.getById(u.getOrganizationId());
                u.setDepartmentTitle(department.getTitle());
            }
            u.setPassword(null);
        }
        return new ResultUtil<List<ScUser>>().setData(list);
    }

    @RequestMapping(value = "/getByUserName/{username}", method = RequestMethod.GET)
    @ApiOperation(value = "通过用户名获取用户")
    public Result<ScUser> getByUserName(@PathVariable String username) {
        return new ResultUtil<ScUser>().setData(userService.findByUsername(username));
    }

    @RequestMapping(value = "/getAll", method = RequestMethod.GET)
    @ApiOperation(value = "获取全部用户数据")
    public Result<List<ScUser>> getByCondition() {

        List<ScUser> list = userService.list();
        for (ScUser u : list) {
            // 关联部门
            if (u.getOrganizationId() != null) {
                ScDepartment department = departmentService.getById(u.getOrganizationId());
                u.setDepartmentTitle(department.getTitle());
            }
            u.setPassword(null);
            //记录用户是否为部门负责人
            Integer type = departmentHeaderService.getHeaderTypeByUserId(u.getId());
            u.setHeaderTypeKey(type);
            u.setHeaderTypeName(UserHeaderTypeEnum.getNameByKey(type));
        }
        return new ResultUtil<List<ScUser>>().setData(list);
    }

    @RequestMapping(value = "/selectList", method = RequestMethod.GET)
    @ApiOperation(value = "获取全部用户数据")
    public Result<List<ScUser>> selectList(@RequestParam(required = false) String nickName) {

        List<ScUser> list = userService.list(new QueryWrapper<ScUser>().lambda().eq(ScUser::getRealname,nickName));
        for (ScUser u : list) {
            u.setPassword(null);
            u.setHeaderTypeName(UserHeaderTypeEnum.getNameByKey(u.getHeaderTypeKey()));
        }
        return new ResultUtil<List<ScUser>>().setData(list);
    }


    @RequestMapping(value = "/admin/add", method = RequestMethod.POST)
    @ApiOperation(value = "添加用户")
    public Result<Object> regist(@ModelAttribute("user") @Validated ScUserVo uv,
                                 @RequestParam(required = false) Long[] roleIds) {
        try {
            ScUser u = new ScUser();
            BeanUtils.copyProperties(uv, u);
            u.setPassUpdateTime(LocalDateTime.now());
            userService.regist(u, roleIds);
        } catch (Exception e) {
            return new ResultUtil<Object>().setErrorMsg(e.getMessage());
        }
        return new ResultUtil<Object>().setSuccessMsg("添加成功");
    }

    @RequestMapping(value = "/admin/init", method = RequestMethod.POST)
    @ApiOperation(value = "初始化admin")
    public Result<Object> init(@ModelAttribute("user") @Validated ScUserVo uv,
                                 @RequestParam(required = false) Long[] roleIds) {
        try {
            ScUser u = new ScUser();
            BeanUtils.copyProperties(uv, u);
            u.setPassUpdateTime(LocalDateTime.now());
            userService.regist(u, roleIds);
            return new ResultUtil<Object>().setData(u.getId(),"添加成功");
        } catch (Exception e) {
            userService.remove(new QueryWrapper<>());
            return new ResultUtil<Object>().setErrorMsg(e.getMessage());
        }
    }

    @RequestMapping(value = "/admin/disable/{userId}", method = RequestMethod.POST)
    @ApiOperation(value = "后台禁用用户")
    public Result<Object> disable(@ApiParam("用户唯一id标识") @PathVariable String userId) {
        if(DEFAULT_USER_ROOT_ID.equals(Long.valueOf(userId))){
            return new ResultUtil<Object>().setErrorMsg("默认用户禁止禁用");
        }
        ScUser user = userService.getById(userId);
        if (user == null) {
            return new ResultUtil<Object>().setErrorMsg("通过userId获取用户失败");
        }
        user.setStatus(CommonConstant.USER_STATUS_LOCK);
        userService.updateById(user);
        //手动更新缓存
        redisTemplate.delete("user::" + user.getUsername());
        String oldToken = redisTemplate.opsForValue().get(SecurityConstant.USER_TOKEN + user.getUsername());
        if(StrUtil.isNotBlank(oldToken)){
            redisTemplate.delete(SecurityConstant.TOKEN_PRE + oldToken);
        }
        return new ResultUtil<Object>().setSuccessMsg("操作成功");
    }

    @RequestMapping(value = "/admin/enable/{userId}", method = RequestMethod.POST)
    @ApiOperation(value = "后台启用用户")
    public Result<Object> enable(@ApiParam("用户唯一id标识") @PathVariable String userId) {
        try {
            ScUser user = userService.getById(userId);
            if (user == null) {
                return new ResultUtil<Object>().setErrorMsg("通过userId获取用户失败");
            }
            user.setStatus(CommonConstant.USER_STATUS_NORMAL);
            userService.updateById(user);

            //手动更新缓存
            String loginTimekey = "loginTimeLimit:"+user.getUsername();
            String flagKey = "loginFailFlag:"+user.getUsername();

            redisTemplate.delete(loginTimekey);
            redisTemplate.delete(flagKey);
            redisTemplate.delete("user::" + user.getUsername());
            return new ResultUtil<Object>().setSuccessMsg("操作成功");
        } catch (Exception e) {
            log.error("启用用户失败", e.getMessage(), e);
            return new ResultUtil<Object>().setErrorMsg("启用用户失败");
        }
    }

    @RequestMapping(value = "/delByIds/{ids}", method = RequestMethod.DELETE)
    @ApiOperation(value = "批量通过ids删除")
    public Result<Object> delAllByIds(@PathVariable String[] ids) {
        try {
            ScUser currUser = securityUtil.getCurrUser();
            for (String id : ids) {
                if(DEFAULT_USER_ROOT_ID.equals(Long.valueOf(id))){
                    return new ResultUtil<Object>().setErrorMsg("默认用户禁止删除");
                }

                if(currUser.getId().toString().equals(id)){
                    return new ResultUtil<Object>().setErrorMsg("当前用户禁止删除");
                }

                ScUser u = userService.getById(id);
                //删除相关缓存
                redisTemplate.delete("user::" + u.getUsername());
                redisTemplate.delete("userRole::" + u.getId());
                redisTemplate.delete("userRole::depIds:" + u.getId());
                redisTemplate.delete("permission::userMenuList:" + u.getId());
                String oldToken = redisTemplate.opsForValue().get(SecurityConstant.USER_TOKEN + u.getUsername());
                if(StrUtil.isNotBlank(oldToken)){
                    redisTemplate.delete(SecurityConstant.TOKEN_PRE + oldToken);
                }
                // TODO: 2020/7/28 获取的都有问题有时间在改
                Set<String> keys = redisObjectOperation.keys("department::*");
                redisTemplate.delete(keys);
                userService.removeById(id);
                //删除关联角色
                userRoleService.remove(new QueryWrapper<ScUserRole>().lambda().eq(ScUserRole::getUserId,id));
                // 删除关联部门负责人
                departmentHeaderService.remove(new QueryWrapper<ScDepartmentHeader>().lambda().eq(ScDepartmentHeader::getUserId,id));


            }
            return new ResultUtil<Object>().setSuccessMsg("批量通过id删除数据成功");
        } catch (Exception e) {
            log.error("删除用户失败", e.getMessage(), e);
            return new ResultUtil<Object>().setErrorMsg("删除用户失败");
        }

    }

    @RequestMapping(value = "/importData", method = RequestMethod.POST)
    @ApiOperation(value = "导入用户数据")
    public Result<Object> importData(@RequestBody List<ScUser> users) {

        List<Integer> errors = new ArrayList<>();
        List<String> reasons = new ArrayList<>();
        Map<String, ScDepartment> departmentMap = new HashMap<>();
        departmentService.list().forEach(department -> {
            departmentMap.put(department.getTitle(), department);
        });
        int count = 0;
        for (ScUser u : users) {
            count++;
            // 验证用户名密码不为空
            if (StrUtil.isBlank(u.getUsername()) || StrUtil.isBlank(u.getPassword())) {
                errors.add(count);
                reasons.add("用户名或密码为空");
                continue;
            }
            // 验证用户名唯一
            if (userService.findByUsername(u.getUsername()) != null) {
                errors.add(count);
                reasons.add("用户名已存在");
                continue;
            }

            //删除缓存
            /*redisTemplate.delete("user::" + u.getUsername());

            String s = jmessageUtils.registerUsers(u.getId(), u.getPassword(), u.getUsername(), u.getAvatar());
            if (null != s && !"".equals(s)) {
                u.setJmessageName(s);
            } else {
                return new ResultUtil<Object>().setErrorMsg("添加失败");
            }*/
            // 加密密码
            u.setPassword(DigestUtils.md5DigestAsHex(u.getPassword().getBytes()));
            u.setPassUpdateTime(LocalDateTime.now());
            // 获取部门id
            if(StrUtil.isNotBlank(u.getDepartmentTitle())){
                if(departmentMap.containsKey(u.getDepartmentTitle())) {
                    u.setOrganizationId(departmentMap.get(u.getDepartmentTitle()).getId());
                } else {
                    reasons.add("部门不存在");
                }
            }
            // 验证部门id正确性
            if (u.getOrganizationId() != null) {
                try {
                    ScDepartment d = departmentService.getById(u.getOrganizationId());
                    log.info(d.toString());
                } catch (Exception e) {
                    errors.add(count);
                    reasons.add("部门id不存在");
                    continue;
                }
            }
            if (u.getStatus() == null) {
                u.setStatus(CommonConstant.USER_STATUS_NORMAL);
            }
            //todo
            // 分配默认角色
            Long[] roleStrArray = new Long[0];
            if (u.getDefaultRole() != null && u.getDefaultRole() == 1) {
                List<ScRole> roleList = roleService.list(new QueryWrapper<ScRole>().lambda().eq(ScRole::getDefaultRole,true));
                roleStrArray = new Long[roleList.size()];
                roleList.stream().map(ScRole::getId).collect(Collectors.toList()).toArray(roleStrArray);
            }
            // 保存数据

            try {
                userService.regist(u,roleStrArray);
            } catch (Exception e) {
                return new ResultUtil<Object>().setErrorMsg(e.getMessage());
            }
        }
        int successCount = users.size() - errors.size();
        String successMessage = "全部导入成功，共计 " + successCount + " 条数据";
        String failMessage = "导入成功 " + successCount + " 条，失败 " + errors.size() + " 条数据。<br>" +
                "第 " + errors.toString() + " 行数据导入出错，错误原因分别为：<br>" + reasons.toString();
        String message = "";
        if (errors.size() == 0) {
            message = successMessage;
        } else {
            message = failMessage;
        }
        return new ResultUtil<Object>().setSuccessMsg(message);
    }

    @RequestMapping(value = "/getVerifier", method = RequestMethod.GET)
    @ApiOperation(value = "获取可选复核用户列表")
    public Result<List<ScUser>> getVerifier() {

        ScUser u = securityUtil.getCurrUser();
        /*if(u.getOrganizationId() == null || u.getOrganizationId().equals(DEPARTMENT_ROOT_ID)){
            return new ResultUtil<List<ScUser>>()
                    .setData(userService.list(new QueryWrapper<ScUser>().lambda()
                            .eq(ScUser::getOrganizationId, DEPARTMENT_ROOT_ID)
                            .notIn(ScUser::getId, new ArrayList<Long>(){{add(u.getId());}})));
        }
        ScDepartment currDepartment = departmentService.getById(u.getOrganizationId());
        if(currDepartment == null){
            return new ResultUtil<List<ScUser>>().setErrorMsg("无法找到当前用户所属部门");
        }
        if(currDepartment.getParentId().equals(DEPARTMENT_ROOT_ID)){
            return new ResultUtil<List<ScUser>>()
                    .setData(userService.list(new QueryWrapper<ScUser>().lambda()
                            .eq(ScUser::getOrganizationId, currDepartment.getId())
                            .notIn(ScUser::getId, new ArrayList<Long>(){{add(u.getId());}})));
        }
        ScDepartment d = departmentService.getById(currDepartment.getParentId());
        List<ScUser> list = userService.list(new QueryWrapper<ScUser>().lambda()
                .eq(ScUser::getOrganizationId, d.getId()));*/
        List<ScUser> list = userService.list(new QueryWrapper<ScUser>().lambda().ne(ScUser::getId, u.getId()));
        return new ResultUtil<List<ScUser>>().setData(list);
    }

    @RequestMapping(value = "/verify", method = RequestMethod.POST)
    @ApiOperation(value = "复核")
    public Result<Object> verify(Long userId, String password) {
        ScUser verifier = userService.getById(userId);
        if (!new BCryptPasswordEncoder().matches(password, verifier.getPassword())) {
            return new ResultUtil<Object>().setErrorMsg("密码不正确");
        }
        return new ResultUtil<Object>().setSuccessMsg("核验成功");
    }


    @RequestMapping(value = "/getByDepartmentId", method = RequestMethod.GET)
    @ApiOperation(value = "根据部门id获取用户列表")
    public Result<List<ScUser>> getByCondition(@RequestParam Long departmentId, @RequestParam(defaultValue = "false", required = false) boolean cascade) {
        List<ScUser> list = new LinkedList<>();
        if (cascade) {

            if (DEPARTMENT_ROOT_ID.equals(departmentId)) {
                return getByCondition();
            }

            Set<ScUser> userSet = new HashSet<>();
            List<ScDepartment> departments = new LinkedList<>(findDepartmentByParentId(departmentId));
            departments.add(departmentService.getById(departmentId));
            departments.forEach(department -> {
                userSet.addAll(findUserByDepartment(department.getId()));
            });
            if(userSet.contains(null)){
                userSet.remove(null);
            }
            list.addAll(userSet);
        } else {
            list.addAll(findUserByDepartment(departmentId));
        }
        return new ResultUtil<List<ScUser>>().setData(list);
    }

    @RequestMapping(value = "/unlock",method = RequestMethod.POST)
    @ApiOperation(value = "解锁验证密码")
    public Result<Object> unLock(@RequestParam String password){

        ScUser u = securityUtil.getCurrUser();
        if(!new BCryptPasswordEncoder().matches(password, u.getPassword())){
            return new ResultUtil<Object>().setErrorMsg("密码不正确");
        }
        return new ResultUtil<Object>().setData(null);
    }

    private Set<ScDepartment> findDepartmentByParentId(Long parentId) {
        Set<ScDepartment> departmentSet = new HashSet<>();
        departmentSet.addAll(departmentService.findByParentIdOrderBySortOrder(parentId, false));
        departmentSet.forEach(department -> {
            departmentSet.addAll(findDepartmentByParentId(department.getId()));
        });
        return departmentSet;
    }
    private Set<ScUser> findUserByDepartment(Long departmentId) {
        Set<ScUser> set = new HashSet<>();
        set.addAll(userService.list(new QueryWrapper<ScUser>().lambda().eq(ScUser::getOrganizationId,departmentId)));

        set.forEach(u -> {
            u.setPassword(null);
            //记录用户是否为部门负责人
            Integer type = departmentHeaderService.getHeaderTypeByUserId(u.getId());
            u.setHeaderTypeKey(type);
            u.setHeaderTypeName(UserHeaderTypeEnum.getNameByKey(type));
            //隐藏隐私字段
            /*UserPrivacyUtils.hideUserPrivacy(u);*/
        });
        return set;
    }

    /*@RequestMapping(value = "/getByCondition", method = RequestMethod.GET)
    @ApiOperation(value = "多条件分页获取用户列表")
    public Result<org.springframework.data.domain.Page<ScUser>> getByCondition(@ModelAttribute("user") ScUser user,
                                                                             @ModelAttribute SearchVo searchVo,
                                                                             @ModelAttribute PageVo pageVo) {

        org.springframework.data.domain.Page<ScUser> page = userService.findByCondition(user, searchVo, PageUtil.initPage(pageVo));
        for (ScUser u : page.getContent()) {
            // 关联部门
            if (u.getOrganizationId() != null) {
                ScDepartment department = departmentService.getById(u.getOrganizationId());
                u.setDepartmentTitle(department.getTitle());
            }

            //记录用户是否为部门负责人
            Integer type = departmentHeaderService.getHeaderTypeByUserId(user.getId());
            user.setHeaderTypeKey(type);
            user.setHeaderTypeName(UserHeaderTypeEnum.getNameByKey(type));

            // 关联角色
            List<ScRole> list = userRoleService.findByUserId(u.getId());
            u.setRoles(list);
            // 清除持久上下文环境 避免后面语句导致持久化
            *//*entityManager.clear();*//*
            u.setPassword(null);
            //隐藏隐私字段
            *//*UserPrivacyUtils.hideUserPrivacy(u);*//*
        }
        return new ResultUtil<org.springframework.data.domain.Page<User>>().setData(page);
    }*/

}
