package com.qmth.teachcloud.common.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.qmth.boot.api.exception.ApiException;
import com.qmth.teachcloud.common.bean.dto.BlurryUserDto;
import com.qmth.teachcloud.common.bean.dto.LoginDto;
import com.qmth.teachcloud.common.bean.dto.UserDto;
import com.qmth.teachcloud.common.bean.dto.excel.DescribeImportDto;
import com.qmth.teachcloud.common.bean.dto.excel.SysUserImportDto;
import com.qmth.teachcloud.common.bean.params.ApproveUserResult;
import com.qmth.teachcloud.common.bean.params.UserSaveParams;
import com.qmth.teachcloud.common.bean.result.UserBatchDisposeResult;
import com.qmth.teachcloud.common.contant.SpringContextHolder;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.*;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.enums.FieldUniqueEnum;
import com.qmth.teachcloud.common.enums.FlowApproveNameEnum;
import com.qmth.teachcloud.common.enums.RoleTypeEnum;
import com.qmth.teachcloud.common.mapper.SysUserMapper;
import com.qmth.teachcloud.common.service.*;
import com.qmth.teachcloud.common.util.Base64Util;
import com.qmth.teachcloud.common.util.ResultUtil;
import com.qmth.teachcloud.common.util.ServletUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;

import javax.annotation.Resource;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author xf
 * @since 2021-03-23
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private BasicCourseService basicCourseService;

    @Autowired
    private SysConfigService sysConfigService;

    @Autowired
    private SysUserRoleService sysUserRoleService;

    @Autowired
    private SysRolePrivilegeService sysRolePrivilegeService;

    @Autowired
    CommonCacheService commonCacheService;

    @Autowired
    private TeachcloudCommonService commonService;

    @Resource
    SysUserMapper sysUserMapper;

    @Resource
    SysOrgService sysOrgService;

    @Resource
    SysUserService sysUserService;

    @Override
    public IPage<UserDto> list(String loginName, String roleId, Boolean enable, String realName, Integer pageNumber, Integer pageSize) {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());

        Page<UserDto> page = new Page<>(pageNumber, pageSize);
        IPage<UserDto> userDtoIPage = this.baseMapper.listPage(page, schoolId, SystemConstant.translateSpecificSign(loginName), roleId, enable, SystemConstant.translateSpecificSign(realName));
        if (userDtoIPage.getRecords().size() > 0) {
            userDtoIPage.getRecords().forEach(m -> {
                //角色
                List<SysRole> roles = sysRoleService.listRolesByUserId(Long.valueOf(m.getId()));
                m.setRoles(roles);

                //课程
                List<BasicCourse> courses = basicCourseService.listCoursesByUserId(Long.valueOf(m.getId()));
                m.setCourses(courses);
            });
        }
        return userDtoIPage;
    }

    @Transactional
    @Override
    public boolean saveUser(UserSaveParams userSaveParams) {
        return saveUserCommon(userSaveParams);
    }

    @Override
    public boolean enable(SysUser user) throws NoSuchAlgorithmException {
        UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(SysUser::getEnable, user.getEnable()).eq(SysUser::getId, user.getId());
        commonCacheService.updateUserCache(user.getId());
        boolean success = this.update(updateWrapper);
        //如果状态为禁用，需要踢下线重新登录
        if (!user.getEnable()) {
            commonService.removeUserInfo(user.getId(), true);
        }
        return success;
    }

    @Override
    public boolean resetPassword(Long id) throws NoSuchAlgorithmException {
        SysConfig sysConfig = sysConfigService.getByKey("sys.user.initPassword");
        String md5Password = Base64Util.encode(StringUtils.isNoneBlank(sysConfig.getConfigValue()) ? sysConfig.getConfigValue().getBytes() : "123456".getBytes());

        SysUser user = this.getById(id);
        String oldPassword = user.getPassword();
        user.setPassword(md5Password);

        //如果原密码和旧密码不一致，需要重新登录
        if (!Objects.equals(user.getPassword(), oldPassword)) {
            commonService.removeUserInfo(user.getId(), false);
        }
        return this.updateById(user);
    }

    @Override
    public boolean updatePassword(SysUser user) throws NoSuchAlgorithmException {
        SysUser sysUser = this.getById(user.getId());
        if (sysUser == null) {
            throw ExceptionResultEnum.ERROR.exception("用户不存在");
        }
        if (!StringUtils.equals(sysUser.getPassword(), user.getOldPassword())) {
            throw ExceptionResultEnum.ERROR.exception("原密码不正确");
        }
        sysUser.setPwdCount(sysUser.getPwdCount() == null ? 1 : sysUser.getPwdCount() + 1);
        sysUser.setPwdUpdateTime(System.currentTimeMillis());
        sysUser.setPassword(user.getPassword());
        boolean success = this.updateById(sysUser);
        //如果原密码和旧密码不一致，需要重新登录
        if (!Objects.equals(user.getOldPassword(), sysUser.getPassword())) {
            commonService.removeUserInfo(sysUser.getId(), false);
        }
        return success;
    }

    @Transactional
    @Override
    public boolean bindRoles(SysUser sysUser) {
        Long[] roleIds = sysUser.getRoleIds();
        if (roleIds.length == 0) {
            throw ExceptionResultEnum.ERROR.exception("请选择角色");
        }

        // 删除
        sysUserRoleService.removeByUserId(sysUser.getId());

        List<SysUserRole> list = new ArrayList<>();
        for (Long roleId : roleIds) {
            List<SysRolePrivilege> rolePrivileges = sysRolePrivilegeService.listByRoleId(roleId);
            for (SysRolePrivilege rolePrivilege : rolePrivileges) {
                SysUserRole userRole = new SysUserRole();
                userRole.setUserId(sysUser.getId());
                userRole.setRoleId(roleId);
                userRole.setPrivilegeId(rolePrivilege.getPrivilegeId());
                list.add(userRole);
            }
        }

//        // 角色里是否有考务老师角色
//        List<SysRole> sysRoles = sysRoleService.list(roleIds, RoleTypeEnum.QUESTION_TEACHER.name());
//        if (sysRoles != null && sysRoles.size() > 0) {
//            Long[] courseIds = sysUser.getCourseIds();
//            if (courseIds.length == 0) {
//                throw ExceptionResultEnum.ERROR.exception("请选择课程");
//            }
//
//            basicUserCourseService.removeByUserId(sysUser.getId());
//            basicUserCourseService.saveBatch(sysUser);
//
//        }
        return sysUserRoleService.saveBatch(list);
    }

    @Override
    public LoginDto getUserRoles(SysUser sysUser) {
        LoginDto loginDto = new LoginDto();
        loginDto.setId(String.valueOf(sysUser.getId()));
        loginDto.setSchoolId(String.valueOf(sysUser.getSchoolId()));
        loginDto.setLoginName(sysUser.getLoginName());
        loginDto.setRealName(sysUser.getRealName());
        loginDto.setOrgId(String.valueOf(sysUser.getOrgId()));
        loginDto.setEnable(sysUser.getEnable());
        loginDto.setPwdUpdateTime(sysUser.getPwdUpdateTime());

        if ("admin".equals(sysUser.getLoginName())) {
            loginDto.setRoles(Arrays.asList("ADMIN"));
        } else {
            List<SysRole> list = sysUserRoleService.listRoleByUserId(sysUser.getId());
            List<String> roles = list.stream().map(m -> m.getType().name()).collect(Collectors.toList());
            loginDto.setRoles(roles);
        }
        return loginDto;
    }

    @Override
    public List<BlurryUserDto> listUser(String courseCode, String param) {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        QueryWrapper<BasicCourse> basicCourseQueryWrapper = new QueryWrapper<>();
        basicCourseQueryWrapper.lambda().eq(BasicCourse::getSchoolId, schoolId)
                .eq(BasicCourse::getCode, courseCode)
                .eq(BasicCourse::getEnable, true);
        BasicCourse basicCourse = basicCourseService.getOne(basicCourseQueryWrapper);
        if (Objects.isNull(basicCourse)) {
            throw ExceptionResultEnum.ERROR.exception("找不到此课程信息");
        }

        List<SysOrg> sysOrgList = sysOrgService.findByConnectByRootOrgId(basicCourse.getTeachingRoomId());
        Set<Long> orgIds = sysOrgList.stream().map(s -> s.getId()).collect(Collectors.toSet());
        List<ApproveUserResult> sysUserList = sysUserService.filterFlowPrivilege(schoolId, orgIds, false, null, null);
        List<BlurryUserDto> blurryUserDtoList = new ArrayList<>();
        for (ApproveUserResult sysUser : sysUserList) {
            blurryUserDtoList.add(new BlurryUserDto(sysUser.getId(), sysUser.getLoginName(), sysUser.getRealName()));
        }
        return blurryUserDtoList;
    }

    @Override
    public List<SysUser> listByOrgId(Long id) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUser::getOrgId, id);
        return this.list(queryWrapper);
    }

    @Transactional
    @Override
    public boolean saveCustomer(UserSaveParams userSaveParams) {
        return saveUserCommon(userSaveParams);
    }

    @Override
    public IPage<UserDto> listCustomer(String realName, Boolean enable, Integer pageNumber, Integer pageSize) {
        Page<UserDto> page = new Page<>(pageNumber, pageSize);
        IPage<UserDto> userDtoIPage = this.baseMapper.listCustomerPage(page, SystemConstant.translateSpecificSign(realName), enable);
        if (userDtoIPage.getRecords().size() > 0) {
            userDtoIPage.getRecords().forEach(m -> {
                //角色
                List<SysRole> roles = sysRoleService.listRolesByUserId(Long.valueOf(m.getId()));
                m.setRoles(roles);

                //课程
                List<BasicCourse> courses = basicCourseService.listCoursesByUserId(Long.valueOf(m.getId()));
                m.setCourses(courses);
            });
        }
        return userDtoIPage;
    }

    @Override
    public SysUser findByForeignKey(Long schoolId, String teacherName) {
        List<SysUser> tbSchoolTeacherList = this.list(new QueryWrapper<SysUser>().lambda()
                .eq(SysUser::getSchoolId, schoolId)
                .eq(SysUser::getRealName, teacherName));
        SysRole sysRole = sysRoleService.getOne(new QueryWrapper<SysRole>().lambda().eq(SysRole::getType, RoleTypeEnum.TEACHER));
//        tbSchoolTeacherList = tbSchoolTeacherList.stream().filter(e -> Arrays.asList(e.getRoleIds()).contains(sysRole.getId())).collect(Collectors.toList());
        if (tbSchoolTeacherList.size() != 1) {
            throw ExceptionResultEnum.ERROR.exception("教师基础数据信息异常");
        }
        return tbSchoolTeacherList.get(0);
    }

    /**
     * 保存用户公用
     *
     * @param userSaveParams
     * @return
     */
    public boolean saveUserCommon(UserSaveParams userSaveParams) {
        SysUserService sysUserService = SpringContextHolder.getBean(SysUserService.class);
        boolean isSuccess = true;
        try {
            Long schoolId = Objects.nonNull(ServletUtil.getRequestHeaderSchoolIdByNotVaild()) ? Long.valueOf(ServletUtil.getRequestHeaderSchoolIdByNotVaild().toString()) : null;
            if (schoolId == null) {
                schoolId = userSaveParams.getSchoolId();
            }
            SysUser requestUser = (SysUser) ServletUtil.getRequestUser();

            String code = userSaveParams.getCode();
            String mobileNumber = userSaveParams.getMobileNumber();
            // 工号检验
            SysUser checkCode = this.getOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getSchoolId, schoolId).eq(SysUser::getEnable, true).eq(SysUser::getCode, code));
            if (Objects.nonNull(checkCode)) {
                if (!checkCode.getId().equals(userSaveParams.getId())) {
                    throw ExceptionResultEnum.ERROR.exception("用户工号【" + code + "】重复");
                }
            }
            // 手机号检验
            SysUser checkMobileNumber = this.getOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getSchoolId, schoolId).eq(SysUser::getEnable, true).eq(SysUser::getMobileNumber, mobileNumber));
            if (Objects.nonNull(checkMobileNumber)) {
                if (!checkMobileNumber.getId().equals(userSaveParams.getId())) {
                    throw ExceptionResultEnum.ERROR.exception("用户手机号【" + mobileNumber + "】重复");
                }
            }

            Gson gson = new Gson();
            userSaveParams.setSchoolId(schoolId);
            SysUser sysUser = gson.fromJson(gson.toJson(userSaveParams), SysUser.class);
            if (Objects.isNull(sysUser.getId())) {//新增用户
                sysUser.insertInfo(requestUser.getId());
                sysUserService.save(sysUser);
                commonService.addUserRolePrivilege(sysUser, userSaveParams.getRoleIds());
            } else {//修改用户
                List<SysUserRole> sysUserRoleList = commonCacheService.userRolePrivilegeCache(sysUser.getId());
                List<Long> userRolesList = Arrays.asList(userSaveParams.getRoleIds());
                Set<Long> dbUserRolesList = sysUserRoleList.stream().map(SysUserRole::getRoleId).collect(Collectors.toSet());
                int count = (int) dbUserRolesList.stream().filter(s -> userRolesList.contains(s)).count();
                SysUser dbUser = sysUserService.getById(sysUser.getId());
                sysUser.updateInfo(requestUser.getId());
                sysUserService.updateById(sysUser);
                //如果修改了角色，需要重新登录
                if (count == 0 || dbUserRolesList.size() != userRolesList.size()) {
                    QueryWrapper<SysUserRole> sysUserRoleQueryWrapper = new QueryWrapper<>();
                    sysUserRoleQueryWrapper.lambda().eq(SysUserRole::getUserId, sysUser.getId());
                    sysUserRoleService.remove(sysUserRoleQueryWrapper);

                    commonCacheService.removeUserRolePrivilegeCache(sysUser.getId());
                    commonService.addUserRolePrivilege(sysUser, userSaveParams.getRoleIds());
                    commonService.removeUserInfo(sysUser.getId(), true);
                }else if (!dbUser.getOrgId().equals(sysUser.getOrgId())){
                    commonService.removeUserInfo(sysUser.getId(), true);
                }
                //如果修改了机构或手机号，需更新用户缓存
                if (Objects.nonNull(dbUser.getOrgId())) {
                    if (dbUser.getOrgId().longValue() != sysUser.getOrgId().longValue()
                            || !Objects.equals(dbUser.getMobileNumber(), sysUser.getMobileNumber())) {
                        commonCacheService.updateUserCache(sysUser.getId());
                        commonCacheService.updateUserAuthCache(sysUser.getId());
                    }
                }
            }
//            //用户科目全量删除全量增加
//            QueryWrapper<BasicUserCourse> basicUserCourseQueryWrapper = new QueryWrapper<>();
//            basicUserCourseQueryWrapper.lambda().eq(BasicUserCourse::getUserId, sysUser.getId());
//            basicUserCourseService.remove(basicUserCourseQueryWrapper);
//
//            List<SysRole> sysRoles = sysRoleService.list(sysUser.getRoleIds(), RoleTypeEnum.QUESTION_TEACHER.name());
//            if (sysRoles != null && sysRoles.size() > 0) {
//                Long[] courseIds = sysUser.getCourseIds();
//                if (courseIds.length == 0) {
//                    throw ExceptionResultEnum.ERROR.exception("请选择课程");
//                }
//                basicUserCourseService.saveBatch(sysUser);
//            }
        } catch (Exception e) {
            log.error("请求出错", e);
            isSuccess = false;
            if (e instanceof DuplicateKeyException) {
                String errorColumn = e.getCause().toString();
                String columnStr = errorColumn.substring(errorColumn.lastIndexOf("key") + 3, errorColumn.length()).replaceAll("'", "");
                throw ExceptionResultEnum.SQL_ERROR.exception("[" + FieldUniqueEnum.convertToTitle(columnStr) + "]数据不允许重复插入");
            } else if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        }
        return isSuccess;
    }


    /**
     * 临时保存用户不鉴权
     *
     * @param userSaveParams 用户参数
     * @return 结果
     */
    @Override
    public boolean saveUserNoAuth(UserSaveParams userSaveParams) {
        SysUserService sysUserService = SpringContextHolder.getBean(SysUserService.class);
        boolean isSuccess = true;
        try {
            Long schoolId = Objects.nonNull(ServletUtil.getRequestHeaderSchoolIdByNotVaild()) ? Long.valueOf(ServletUtil.getRequestHeaderSchoolIdByNotVaild().toString()) : null;
            if (schoolId == null) {
                schoolId = userSaveParams.getSchoolId();
            }
            List<SysUser> requestUserList = this.list(new QueryWrapper<SysUser>().lambda().eq(SysUser::getSchoolId, schoolId).like(SysUser::getLoginName, "admin"));
            if (requestUserList.size() == 0) {
                throw ExceptionResultEnum.ERROR.exception("该学校没有内置的学校管理员");
            }
            SysUser requestUser = requestUserList.get(0);
            Gson gson = new Gson();
            userSaveParams.setSchoolId(schoolId);
            SysUser sysUser = gson.fromJson(gson.toJson(userSaveParams), SysUser.class);
            if (Objects.isNull(sysUser.getId())) {//新增用户
                // 登录名是否唯一
                QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
                if (Objects.isNull(schoolId)) {
                    queryWrapper.lambda().isNull(SysUser::getSchoolId);
                } else {
                    queryWrapper.lambda().eq(SysUser::getSchoolId, schoolId);
                }
                queryWrapper.lambda().eq(SysUser::getLoginName, sysUser.getLoginName());
                SysUser user = sysUserService.getOne(queryWrapper);
                if (user != null) {
                    throw ExceptionResultEnum.ERROR.exception("用户名已存在");
                }

                sysUser.insertInfo(requestUser.getId());
                sysUserService.save(sysUser);
                for (Long roleId : userSaveParams.getRoleIds()) {
                    commonService.addUserRolePrivilege(sysUser, roleId);
                }
            } else {//修改用户
                List<SysUserRole> sysUserRoleList = commonCacheService.userRolePrivilegeCache(sysUser.getId());
                List<Long> userRolesList = Arrays.asList(userSaveParams.getRoleIds());
                Set<Long> dbUserRolesList = sysUserRoleList.stream().map(SysUserRole::getRoleId).collect(Collectors.toSet());
                int count = (int) dbUserRolesList.stream().filter(s -> userRolesList.contains(s)).count();
                SysUser dbUser = sysUserService.getById(sysUser.getId());
                sysUser.updateInfo(requestUser.getId());
                sysUserService.updateById(sysUser);
                List<SysRole> list = sysUserRoleService.listRoleByUserId(sysUser.getId());
                boolean containsQuestionTeacher = list.stream().filter(m -> RoleTypeEnum.SCHOOL_ADMIN.equals(m.getType())).count() > 0;
                if (containsQuestionTeacher || count == 0 || dbUserRolesList.size() != userRolesList.size()) {
                    QueryWrapper<SysUserRole> sysUserRoleQueryWrapper = new QueryWrapper<>();
                    sysUserRoleQueryWrapper.lambda().eq(SysUserRole::getUserId, sysUser.getId());
                    sysUserRoleService.remove(sysUserRoleQueryWrapper);

                    commonCacheService.removeUserRolePrivilegeCache(sysUser.getId());
                    for (Long roleId : userSaveParams.getRoleIds()) {
                        commonService.addUserRolePrivilege(sysUser, roleId);
                    }
                }
                //如果修改了角色，需要重新登录
                if (count == 0 || dbUserRolesList.size() != userRolesList.size()) {
                    commonService.removeUserInfo(sysUser.getId(), true);
                }
                //如果修改了机构或手机号，需更新用户缓存
                if (Objects.nonNull(dbUser.getOrgId())) {
                    if (containsQuestionTeacher || dbUser.getOrgId().longValue() != sysUser.getOrgId().longValue()
                            || !Objects.equals(dbUser.getMobileNumber(), sysUser.getMobileNumber())) {
                        commonCacheService.updateUserCache(sysUser.getId());
                        commonCacheService.updateUserAuthCache(sysUser.getId());
                    }
                }
            }
//            //用户科目全量删除全量增加
//            QueryWrapper<BasicUserCourse> basicUserCourseQueryWrapper = new QueryWrapper<>();
//            basicUserCourseQueryWrapper.lambda().eq(BasicUserCourse::getUserId, sysUser.getId());
//            basicUserCourseService.remove(basicUserCourseQueryWrapper);
//
//            List<SysRole> sysRoles = sysRoleService.list(sysUser.getRoleIds(), RoleTypeEnum.QUESTION_TEACHER.name());
//            if (sysRoles != null && sysRoles.size() > 0) {
//                Long[] courseIds = sysUser.getCourseIds();
//                if (courseIds.length == 0) {
//                    throw ExceptionResultEnum.ERROR.exception("请选择课程");
//                }
//                basicUserCourseService.saveBatch(sysUser);
//            }
        } catch (Exception e) {
            log.error("请求出错", e);
            isSuccess = false;
            if (e instanceof DuplicateKeyException) {
                String errorColumn = e.getCause().toString();
                String columnStr = errorColumn.substring(errorColumn.lastIndexOf("key") + 3, errorColumn.length()).replaceAll("'", "");
                throw ExceptionResultEnum.SQL_ERROR.exception("[" + FieldUniqueEnum.convertToTitle(columnStr) + "]数据不允许重复插入");
            } else if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        }
        return isSuccess;
    }

    /**
     * 过滤拥有审核权限的人
     *
     * @param schoolId
     * @param orgIds
     * @param filter
     * @param approveName
     * @param realName
     * @return
     */
    @Override
    public List<ApproveUserResult> filterFlowPrivilege(Long schoolId, Set<Long> orgIds, Boolean filter, FlowApproveNameEnum approveName, String realName) {
        return sysUserMapper.filterFlowPrivilege(schoolId, orgIds, filter, Objects.nonNull(approveName) ? approveName.getId() : null, realName);
    }

    @Override
    public Map<String, Object> executeSysUserImportLogic(List<LinkedMultiValueMap<Integer, Object>> finalList, Map<String, Object> map) throws NoSuchAlgorithmException {
        SysUser sysUser = (SysUser) map.get(SystemConstant.SYS_USER);
        Long schoolId = sysUser.getSchoolId();
        List<UserSaveParams> userSaveParamsList = new ArrayList<>();
        for (int i = 0; i < finalList.size(); i++) {
            LinkedMultiValueMap<Integer, Object> excelMap = finalList.get(i);
            List<Object> sysUserImportDtoList = excelMap.get(i);
            assert sysUserImportDtoList != null;
            if (sysUserImportDtoList.get(0) instanceof DescribeImportDto) {
                continue;
            }
            map.put("dataCount", sysUserImportDtoList.size());
            for (int y = 0; y < Objects.requireNonNull(sysUserImportDtoList).size(); y++) {
                SysUserImportDto sysUserImportDto = (SysUserImportDto) sysUserImportDtoList.get(y);
                String name = sysUserImportDto.getName();
                String code = sysUserImportDto.getCode();
                String phoneNumber = sysUserImportDto.getPhoneNumber();
                String orgName = sysUserImportDto.getOrgName();
                String roleName = sysUserImportDto.getRoleName();

                UserSaveParams userSaveParams = new UserSaveParams();
                Long orgId = this.analyzeOrgName(schoolId, orgName);
                List<Long> roleIdList = this.analyzeRoleName(schoolId, roleName);

                SysUser oldUser = this.getOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getCode, code).eq(SysUser::getSchoolId, schoolId));
                Long oldUserId = null;
                if (Objects.nonNull(oldUser)) {
                    oldUserId = oldUser.getId();
                }
                if (SystemConstant.longNotNull(oldUserId)) {
                    // 编辑
                    userSaveParams.setId(oldUserId);
                }
                userSaveParams.setOrgId(orgId);
                userSaveParams.setRealName(name);
                userSaveParams.setRoleIds(roleIdList.toArray(new Long[0]));
                userSaveParams.setMobileNumber(phoneNumber);
                userSaveParams.setCode(code);
                userSaveParamsList.add(userSaveParams);
            }
        }
        UserBatchDisposeResult userBatchDisposeResult = this.disposeUserInfoHelp(userSaveParamsList, sysUser);
        List<SysUser> sysUserList = userBatchDisposeResult.getUserList();
        List<SysUserRole> sysUserRoleList = userBatchDisposeResult.getUserRoleList();
        Set<Long> removeUserIdSet = userBatchDisposeResult.getRemoveIdSet();
        Set<Long> updateUserIdSet = userBatchDisposeResult.getUpdateIdSet();
        // TODO: 2021/9/1 可以优化 或者直接批量导入变成单个导入 循环调用 
        // 保存用户
        this.saveOrUpdateBatch(sysUserList);
        // 要更新的用户删除原先的权限
        for (Long id : removeUserIdSet) {
            QueryWrapper<SysUserRole> sysUserRoleQueryWrapper = new QueryWrapper<>();
            sysUserRoleQueryWrapper.lambda().eq(SysUserRole::getUserId, id);
            sysUserRoleService.remove(sysUserRoleQueryWrapper);
            commonCacheService.removeUserRolePrivilegeCache(id);
        }
        // 更新用户角色权限
        sysUserRoleService.saveOrUpdateBatch(sysUserRoleList);
        // 要更新的角色删除缓存
        for (Long id : removeUserIdSet) {
            commonService.removeUserInfo(id, true);
        }
        // 基础数据变更更新缓存
        for (Long id : updateUserIdSet) {
            commonCacheService.updateUserCache(id);
            commonCacheService.updateUserAuthCache(id);
        }
        return map;
    }

    /**
     * 获取命题审批人
     *
     * @param courseCode
     * @param realName
     * @return
     */
    @Override
    public List<ApproveUserResult> findByAssignApprove(String courseCode, String realName) {
        Long schoolId = SystemConstant.getHeadOrUserSchoolId();
        QueryWrapper<BasicCourse> basicCourseQueryWrapper = new QueryWrapper<>();
        basicCourseQueryWrapper.lambda().eq(BasicCourse::getSchoolId, schoolId)
                .eq(BasicCourse::getCode, courseCode)
                .eq(BasicCourse::getEnable, true);
        BasicCourse basicCourse = basicCourseService.getOne(basicCourseQueryWrapper);
        if (Objects.isNull(basicCourse)) {
            throw ExceptionResultEnum.ERROR.exception("找不到此课程信息");
        }
        List<SysOrg> sysOrgList = sysOrgService.findByConnectByRootOrgId(basicCourse.getTeachingRoomId());
        Set<Long> orgIds = sysOrgList.stream().map(s -> s.getId()).collect(Collectors.toSet());
        return sysUserService.filterFlowPrivilege(schoolId, orgIds, false, null, realName);
    }

    /**
     * 获取教研室主任审批人
     *
     * @param courseCode
     * @param realName
     * @return
     */
    @Override
    public List<ApproveUserResult> findByDirectorApprove(String courseCode, String realName) {
        Long schoolId = SystemConstant.getHeadOrUserSchoolId();
        QueryWrapper<BasicCourse> basicCourseQueryWrapper = new QueryWrapper<>();
        basicCourseQueryWrapper.lambda().eq(BasicCourse::getSchoolId, schoolId)
                .eq(BasicCourse::getCode, courseCode);
        BasicCourse basicCourse = basicCourseService.getOne(basicCourseQueryWrapper);

        if (Objects.isNull(basicCourse)) {
            throw ExceptionResultEnum.ERROR.exception("课程数据为空");
        }
        if (Objects.isNull(basicCourse.getTeachingRoomId())) {
            throw ExceptionResultEnum.ERROR.exception("课程机构为空");
        }
        List<SysOrg> sysOrgList = sysOrgService.findByConnectByRootOrgId(basicCourse.getTeachingRoomId());
        Set<Long> orgIds = sysOrgList.stream().map(s -> s.getId()).collect(Collectors.toSet());
        List<ApproveUserResult> approveUserResultList = sysUserService.filterFlowPrivilege(schoolId, orgIds, true, FlowApproveNameEnum.DIRECTOR, realName);
        if (Objects.isNull(approveUserResultList) || approveUserResultList.size() == 0) {
            throw ExceptionResultEnum.ERROR.exception("该课程未配置主任审批人");
        }
        return approveUserResultList;
    }

    /**
     * 获取院长审批人
     *
     * @param orgIds
     * @param realName
     * @return
     */
    @Override
    public List<ApproveUserResult> findByPresidentApprove(List<Long> orgIds, String realName) {
        Long schoolId = SystemConstant.getHeadOrUserSchoolId();
        Set<SysOrg> sysOrgSet = new HashSet<>();
        for (Long l : orgIds) {
            sysOrgSet.addAll(sysOrgService.findByConnectByParentId(l, true));
        }
        Set<Long> orgIdsSet = sysOrgSet.stream().map(s -> s.getId()).collect(Collectors.toSet());
        List<ApproveUserResult> approveUserResultList = sysUserService.filterFlowPrivilege(schoolId, orgIdsSet, true, FlowApproveNameEnum.PRESIDENT, realName);
        if (Objects.isNull(approveUserResultList) || approveUserResultList.size() == 0) {
            throw ExceptionResultEnum.ERROR.exception("未配置院长审批人");
        }
        return approveUserResultList;
    }

    /**
     * 根据id获取
     *
     * @param id
     * @return
     */
    @Override
    public List<ApproveUserResult> findById(Long id) {
        return sysUserMapper.findById(id);
    }

    /**
     * 批量处理用户信息帮助类
     *
     * @param userSaveParamsList 用户信息集合
     * @param master             创建人信息
     * @return 处理后的结果
     */
    private UserBatchDisposeResult disposeUserInfoHelp(List<UserSaveParams> userSaveParamsList, SysUser master) throws NoSuchAlgorithmException {
        Long schoolId = master.getSchoolId();
        List<SysUser> userList = new ArrayList<>();
        List<SysUserRole> sysUserRoleList = new ArrayList<>();
        // 用户角色更新 - 对用户角色权限的各种清除操作
        Set<Long> willRemoveUserPri = new HashSet<>();
        // 用户基础信息更新 - 对用户权限缓存的更新
        Set<Long> willUpdateUserPri = new HashSet<>();
        for (UserSaveParams userSaveParams : userSaveParamsList) {
            String code = userSaveParams.getCode();
            String mobileNumber = userSaveParams.getMobileNumber();
            // 工号检验
            SysUser checkCode = this.getOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getSchoolId, schoolId).eq(SysUser::getEnable, true).eq(SysUser::getCode, code));
            if (Objects.nonNull(checkCode)) {
                if (!checkCode.getId().equals(userSaveParams.getId())) {
                    throw ExceptionResultEnum.ERROR.exception("用户工号【" + code + "】重复");
                }
            }
            // 手机号检验
            SysUser checkMobileNumber = this.getOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getSchoolId, schoolId).eq(SysUser::getEnable, true).eq(SysUser::getMobileNumber, mobileNumber));
            if (Objects.nonNull(checkMobileNumber)) {
                if (!checkMobileNumber.getId().equals(userSaveParams.getId())) {
                    throw ExceptionResultEnum.ERROR.exception("用户手机号【" + mobileNumber + "】重复");
                }
            }

            Gson gson = new Gson();
            userSaveParams.setSchoolId(schoolId);
            SysUser userCell = gson.fromJson(gson.toJson(userSaveParams), SysUser.class);
            if (Objects.isNull(userCell.getId())) {//新增用户
                userCell.insertInfo(master.getId());
                userCell.setLoginName(userCell.getCode());
                userList.add(userCell);
                List<SysUserRole> sysUserRoleCell = commonService.disposeUserPrivilege(userCell, userSaveParams.getRoleIds());
                sysUserRoleList.addAll(sysUserRoleCell);
            } else {//修改用户
                List<SysUserRole> oldRoleList = commonCacheService.userRolePrivilegeCache(userCell.getId());
                List<Long> newRoleList = Arrays.asList(userSaveParams.getRoleIds());
                Set<Long> dbUserRolesList = oldRoleList.stream().map(SysUserRole::getRoleId).collect(Collectors.toSet());
                int count = (int) dbUserRolesList.stream().filter(newRoleList::contains).count();
                SysUser dbUser = this.getById(userCell.getId());
                userCell.updateInfo(master.getId());
                userList.add(userCell);
                //如果修改了角色，需要重新登录
                if (count == 0 || dbUserRolesList.size() != newRoleList.size()) {
                    List<SysUserRole> sysUserRoleCell = commonService.disposeUserPrivilege(userCell, userSaveParams.getRoleIds());
                    sysUserRoleList.addAll(sysUserRoleCell);
                    willRemoveUserPri.add(userCell.getId());
                }else if (!dbUser.getOrgId().equals(userCell.getOrgId())){
                    commonService.removeUserInfo(userCell.getId(), true);
                }
                //如果修改了机构或手机号，需更新用户缓存
                if (Objects.nonNull(dbUser.getOrgId())) {
                    if (dbUser.getOrgId().longValue() != userCell.getOrgId().longValue()
                            || !Objects.equals(dbUser.getMobileNumber(), userCell.getMobileNumber())) {
                        willUpdateUserPri.add(userCell.getId());
                    }
                }
            }
        }
        UserBatchDisposeResult userBatchDisposeResult = new UserBatchDisposeResult();
        userBatchDisposeResult.setUserList(userList);
        userBatchDisposeResult.setUserRoleList(sysUserRoleList);
        userBatchDisposeResult.setRemoveIdSet(willRemoveUserPri);

        userBatchDisposeResult.setUpdateIdSet(willUpdateUserPri);

        return userBatchDisposeResult;
    }

    /**
     * 解析机构名称
     *
     * @param schoolId 学校id
     * @param orgName  结构名称
     * @return 机构id
     */
    private Long analyzeOrgName(Long schoolId, String orgName) {
        SysOrg sysOrg = sysOrgService.getOne(new QueryWrapper<SysOrg>().lambda().eq(SysOrg::getEnable, true).eq(SysOrg::getSchoolId, schoolId).eq(SysOrg::getName, orgName));
        if (Objects.isNull(sysOrg)) {
            throw ExceptionResultEnum.ERROR.exception("系统中不存在excel导入的机构【" + orgName + "】");
        }
        return sysOrg.getId();
    }

    /**
     * 根据角色名称获取角色id集合
     *
     * @param schoolId 学校id
     * @param roleName 角色名称组
     * @return 角色集合
     */
    private List<Long> analyzeRoleName(Long schoolId, String roleName) {
        List<Long> roleIdList = new ArrayList<>();
        String[] arr = roleName.split(",");
        for (String cell : arr) {
            SysRole sysRole = sysRoleService.getOne(new QueryWrapper<SysRole>().lambda()
                    .eq(SysRole::getEnable, true)
                    .eq(SysRole::getName, cell)
                    .eq(SysRole::getSchoolId, schoolId));
            if (Objects.isNull(sysRole)) {
                throw ExceptionResultEnum.ERROR.exception("系统中不存在excel导入的角色【" + cell + "】");
            }
            roleIdList.add(sysRole.getId());
        }
        return roleIdList;
    }
}
