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

import com.alibaba.fastjson.JSON;
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.base.BaseEntity;
import com.qmth.teachcloud.common.bean.auth.AuthBean;
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.VerifyCodeCheckDto;
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.UserPushParam;
import com.qmth.teachcloud.common.bean.params.UserSaveParams;
import com.qmth.teachcloud.common.bean.params.UserSaveReportParams;
import com.qmth.teachcloud.common.bean.result.*;
import com.qmth.teachcloud.common.config.DictionaryConfig;
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.*;
import com.qmth.teachcloud.common.enums.userPush.SpecialPrivilegeEnum;
import com.qmth.teachcloud.common.enums.userPush.SyncStatusEnum;
import com.qmth.teachcloud.common.mapper.SysUserMapper;
import com.qmth.teachcloud.common.service.*;
import com.qmth.teachcloud.common.sync.CloudMarkingTaskUtils;
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.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;
import java.util.stream.Stream;

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

    @Resource
    private SysRoleService sysRoleService;

    @Resource
    private BasicCourseService basicCourseService;

    @Resource
    private SysConfigService sysConfigService;

    @Resource
    private SysUserRoleService sysUserRoleService;

    @Resource
    private SysRolePrivilegeService sysRolePrivilegeService;

    @Resource
    CommonCacheService commonCacheService;

    @Resource
    private TeachcloudCommonService commonService;

    @Resource
    SysUserMapper sysUserMapper;

    @Resource
    SysOrgService sysOrgService;

    @Resource
    SysUserService sysUserService;

    @Resource
    DictionaryConfig dictionaryConfig;

    @Resource
    BasicSchoolService basicSchoolService;

    @Resource
    TeachcloudCommonService teachcloudCommonService;

    @Resource
    SysPrivilegeService sysPrivilegeService;

    @Resource
    PushUserErrorService pushUserErrorService;

    @Resource
    PushUserTrackService pushUserTrackService;

    @Resource
    CloudMarkingTaskUtils stmmsUtils;

    @Resource
    SysRoleGroupMemberService sysRoleGroupMemberService;

    @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) throws IllegalAccessException {
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        Long oldId = userSaveParams.getId();
        Set<Long> dbRoleIdSet = new HashSet<>();
        Set<Long> currentRoleIdSet = new HashSet<>(Arrays.asList(userSaveParams.getRoleIds()));
        if (SystemConstant.longNotNull(oldId)) {
            // 编辑
            dbRoleIdSet = new HashSet<>(sysRoleService.getUserRoles(oldId));
        }
        boolean result = false;
        Long upUserId = saveUserCommon(userSaveParams, null);
        if (SystemConstant.longNotNull(upUserId)) {
            result = true;
            List<PushUserTrack> pushUserTrackList = pushUserTrackService.createPushTrackUser(dbRoleIdSet, currentRoleIdSet, upUserId, this.getById(upUserId).getEnable(), requestUser.getId());
            List<UserPushParam> userPushParamList = pushUserTrackService.analyzeUserPushSpecialPrivilege(pushUserTrackList);
            if (userPushParamList != null && userPushParamList.size() > 0) {
                this.userPushService(userPushParamList, requestUser.getId());
            }
        }
        return result;
    }

    /**
     * 保存用户
     *
     * @param userSaveParams
     * @return
     */
    @Override
    public boolean saveUserReport(UserSaveReportParams userSaveReportParams) {
        Gson gson = new Gson();
        UserSaveParams userSaveParams = gson.fromJson(gson.toJson(userSaveReportParams), UserSaveParams.class);
        saveUserCommon(userSaveParams, null);
        return true;
    }

    @Transactional
    @Override
    public boolean enable(SysUser user) throws NoSuchAlgorithmException, IllegalAccessException {
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        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);
        }
        if (success) {
            this.analyzeUserEnableSpecialPrivilege(user.getId(), user.getEnable(), requestUser.getId());
        }
        return success;
    }

    @Override
    public boolean enableReport(SysUser user) throws NoSuchAlgorithmException {
        UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(SysUser::getEnable, user.getEnable()).eq(SysUser::getId, 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);
    }

    @Transactional
    @Override
    public LoginResult 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("原密码不正确");
        }
        String newPwd = user.getPassword();
        String mobileNumber = user.getMobileNumber();
        String verifyCode = user.getVerifyCode();
        String oldPassword = user.getOldPassword();
        if (SystemConstant.strNotNull(newPwd)) {
            // 参数中存在密码 -》 更新密码
            if (SystemConstant.strNotNull(oldPassword) && oldPassword.equals(newPwd)) {
                throw ExceptionResultEnum.ERROR.exception("新密码和旧密码一致请重新输入");
            }
            sysUser.setPwdCount(sysUser.getPwdCount() == null ? 1 : sysUser.getPwdCount() + 1);
            sysUser.setPwdUpdateTime(System.currentTimeMillis());
            sysUser.setPassword(newPwd);
        }
        if (SystemConstant.strNotNull(mobileNumber)) {
            // 参数中存在手机号 -》 更新手机号
            if (!SystemConstant.strNotNull(verifyCode)) {
                throw ExceptionResultEnum.ERROR.exception("验证码不存在");
            }
            this.checkSmsCode(user.getId(), mobileNumber, verifyCode);
            // 更新电话

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

            sysUser.setMobileNumber(mobileNumber);
        }
        boolean success = this.updateById(sysUser);
        if (!success) {
            throw ExceptionResultEnum.ERROR.exception("用户更新失败");
        }

        //如果原密码和旧密码不一致，且用户已经登陆，需要重新登录
        Object object = ServletUtil.getRequest().getAttribute(SystemConstant.SESSION);
        if (Objects.nonNull(object)) {
            if (SystemConstant.strNotNull(newPwd)) {
                if (!Objects.equals(user.getOldPassword(), sysUser.getPassword())) {
                    commonService.removeUserInfo(sysUser.getId(), false);
                }
            } else if (SystemConstant.strNotNull(mobileNumber)) {
                if (!Objects.equals(mobileNumber, sysUser.getMobileNumber())) {
                    commonService.removeUserInfo(sysUser.getId(), false);
                }
            }
        }
        // 如果不是共用验证码 再过期
        if (Objects.nonNull(verifyCode) && !dictionaryConfig.smsDomain().getSmsNormalCode().equals(verifyCode)) {
            sysUserService.expiredVerifyCode(sysUser.getId(), sysUser.getMobileNumber());
        }

        // 登录
        BasicSchool basicSchool = null;
        String schoolCode = null;
        basicSchool = basicSchoolService.getById(sysUser.getSchoolId());
        if (Objects.isNull(basicSchool)) {
            List<Long> userRoles = sysRoleService.getUserRoles(sysUser.getId());
            List<SysRole> sysRoleList = sysRoleService.list(new QueryWrapper<SysRole>().lambda().in(SysRole::getId, userRoles));
            Set<RoleTypeEnum> roleType = sysRoleList.stream().map(SysRole::getType).collect(Collectors.toSet());
            if (roleType.contains(RoleTypeEnum.ADMIN) || roleType.contains(RoleTypeEnum.CUSTOMER)) {
                schoolCode = SystemConstant.ADMIN_CODE;
            }
        } else {
            schoolCode = basicSchool.getCode();
        }
        if (!schoolCode.equalsIgnoreCase(SystemConstant.ADMIN_CODE)) {
            basicSchool = commonCacheService.schoolCache(schoolCode);
            if (Objects.isNull(basicSchool)) {
                throw ExceptionResultEnum.SCHOOL_NO_DATA.exception();
            }
            if (Objects.nonNull(basicSchool.getEnable()) && !basicSchool.getEnable()) {
                throw ExceptionResultEnum.SCHOOL_ENABLE.exception();
            }
        }
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(SysUser::getLoginName, sysUser.getLoginName());
        if (!schoolCode.equalsIgnoreCase(SystemConstant.ADMIN_CODE)) {
            wrapper.lambda().eq(SysUser::getSchoolId, basicSchool.getId());
        }
        List<SysUser> userList = sysUserService.list(wrapper);
        //用户不存在
        if (Objects.isNull(userList) || userList.size() == 0) {
            throw ExceptionResultEnum.USER_NO_DATA.exception();
        }
        if (schoolCode.equalsIgnoreCase(SystemConstant.ADMIN_CODE)) {
            userList.forEach(o -> {
                AuthBean authBean = teachcloudCommonService.getUserAuth(o.getId());
                if (Objects.nonNull(authBean) && Objects.nonNull(authBean.getRoleList()) && authBean.getRoleList().size() > 0) {
                    if (Objects.nonNull(authBean.getSchool())) {
                        throw ExceptionResultEnum.ERROR.exception("用户无法通过当前页面登录");
                    }
                }
            });
        }
        if (userList.size() > 1) {
            throw ExceptionResultEnum.ERROR.exception("查询的用户有多条");
        }
        if (Objects.nonNull(sysUser.getSchoolId()) && sysUser.getSchoolId().longValue() != basicSchool.getId().longValue()) {
            throw ExceptionResultEnum.ERROR.exception("用户学校不匹配");
        }
        // 校验验证码
        sysUserService.checkSmsCode(sysUser.getId(), sysUser.getMobileNumber(), dictionaryConfig.smsDomain().getSmsNormalCode());

        return teachcloudCommonService.login(sysUser.getPassword(), sysUser, AppSourceEnum.SYSTEM);
    }

    @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("找不到此课程信息");
        }

//        Map<String, List<String>> flowSchoolCodeMap = SystemConstant.getFlowSchoolCodeMap();
//        BasicSchool basicSchool = (BasicSchool) ServletUtil.getRequestSchool();
//        if (flowSchoolCodeMap.get(SystemConstant.JXZYY_FLOW_KEY).contains(basicSchool.getCode())) {
//            List<ApproveUserResult> approveUserResultList = sysUserService.findByJxzyyDirectorApprove(null, FlowApproveNameEnum.TEACHER);
//            if (Objects.nonNull(approveUserResultList) && approveUserResultList.size() > 0) {//说明是实施人员提交
//                List<BlurryUserDto> blurryUserDtoList = new ArrayList<>();
//                for (ApproveUserResult sysUser : approveUserResultList) {
//                    blurryUserDtoList.add(new BlurryUserDto(sysUser.getId(), sysUser.getLoginName(), sysUser.getRealName()));
//                }
//                return blurryUserDtoList;
//            } else {
//                return listUserCommon(basicCourse, schoolId);
//            }
//        } else {
        return listUserCommon(basicCourse, schoolId);
//        }
    }

    /**
     * 查找命题老师公用
     *
     * @param basicCourse
     * @param schoolId
     * @return
     */
    private List<BlurryUserDto> listUserCommon(BasicCourse basicCourse, Long schoolId) {
        int count = this.countByTeachingRoomId(basicCourse.getTeachingRoomId());
        List<SysOrg> sysOrgList = null;
        if (count == 0) {
            sysOrgList = sysOrgService.findByConnectByParentId(basicCourse.getTeachingRoomId(), true, true);
        } else {
            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) {
        Long upUserId = saveUserCommon(userSaveParams, null);
        return SystemConstant.longNotNull(upUserId);
    }

    @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 teacherCode) {
        List<SysUser> tbSchoolTeacherList = this.list(new QueryWrapper<SysUser>().lambda()
                .eq(SysUser::getSchoolId, schoolId)
                .eq(SysUser::getLoginName, teacherCode));
        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 userSaveParams
     * @return 新增或更新的用户id
     */
    @Transactional
    public Long saveUserCommon(UserSaveParams userSaveParams, Long requestUserId) {
        SysUserService sysUserService = SpringContextHolder.getBean(SysUserService.class);
        boolean isSuccess = true;
        Long resultUserId = null;
        try {
            Long schoolId = userSaveParams.getSchoolId();
            if (schoolId == null) {
                schoolId = Objects.nonNull(ServletUtil.getRequestHeaderSchoolIdByNotVaild()) ? Long.valueOf(ServletUtil.getRequestHeaderSchoolIdByNotVaild().toString()) : null;
            }
            if (!SystemConstant.longNotNull(requestUserId)) {
                SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
                requestUserId = requestUser.getId();
            }

            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 + "】重复");
                }
            }
            // 手机号检验
            if (SystemConstant.strNotNull(mobileNumber)) {
                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(requestUserId);
                sysUser.setEnable(true);
                sysUserService.save(sysUser);
                resultUserId = sysUser.getId();
                commonService.addUserRolePrivilege(sysUser, userSaveParams.getRoleIds());
            } else {//修改用户
                resultUserId = sysUser.getId();
                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(userRolesList::contains).count();
                Set<Long> removeRoleIds = dbUserRolesList.stream().filter(s -> !userRolesList.contains(s)).collect(Collectors.toSet());
                SysUser dbUser = sysUserService.getById(sysUser.getId());
                sysUserService.update(new UpdateWrapper<SysUser>().lambda()
                        .eq(SysUser::getId, sysUser.getId())
                        .set(SysUser::getSchoolId, userSaveParams.getSchoolId())
                        .set(SysUser::getLoginName, sysUser.getLoginName())
                        .set(SysUser::getRealName, sysUser.getRealName())
                        .set(SysUser::getCode, sysUser.getCode())
                        .set(SysUser::getMobileNumber, sysUser.getMobileNumber())
                        .set(SysUser::getOrgId, sysUser.getOrgId())
                        .set(SysUser::getEnable, dbUser.getEnable())
                        .set(SysUser::getUpdateId, requestUserId)
                        .set(SysUser::getUpdateTime, System.currentTimeMillis())
                );
                //如果修改了角色，需要重新登录
                if (count == 0 || dbUserRolesList.size() != userRolesList.size()) {
                    QueryWrapper<SysUserRole> sysUserRoleQueryWrapper = new QueryWrapper<>();
                    sysUserRoleQueryWrapper.lambda().eq(SysUserRole::getUserId, sysUser.getId());
                    sysUserRoleService.remove(sysUserRoleQueryWrapper);

                    if (Objects.nonNull(removeRoleIds) && removeRoleIds.size() > 0) {
                        QueryWrapper<SysRoleGroupMember> sysRoleGroupMemberQueryWrapper = new QueryWrapper<>();
                        sysRoleGroupMemberQueryWrapper.lambda().eq(SysRoleGroupMember::getUserId, sysUser.getId())
                                .in(SysRoleGroupMember::getRoleId, removeRoleIds);
                        sysRoleGroupMemberService.remove(sysRoleGroupMemberQueryWrapper);
                    }

                    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(SystemConstant.LOG_ERROR, e);
            isSuccess = false;
            if (e instanceof DuplicateKeyException) {
                String errorColumn = e.getCause().toString();
                String columnStr = errorColumn.substring(errorColumn.lastIndexOf("key") + 3).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 resultUserId;
    }

    /**
     * 临时保存用户不鉴权
     *
     * @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(userRolesList::contains).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().anyMatch(m -> RoleTypeEnum.SCHOOL_ADMIN.equals(m.getType()));
                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(SystemConstant.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    schoolId
     * @param orgIds      orgIds
     * @param filter      filter
     * @param approveName approveName
     * @param realName    realName
     * @return 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);
    }

    @Transactional
    @Override
    public Map<String, Object> executeSysUserImportLogic(List<LinkedMultiValueMap<Integer, Object>> finalList, Map<String, Object> map) {
        SysUser requestUser = (SysUser) map.get(SystemConstant.SYS_USER);
        Long schoolId = requestUser.getSchoolId();
        List<UserPushParam> userPushParamList = 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;
            }
            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);
                LinkedHashSet<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;
                Set<Long> oldRoleIdSet = new HashSet<>();
                if (Objects.nonNull(oldUser)) {
                    oldUserId = oldUser.getId();
                    oldRoleIdSet = new HashSet<>(sysRoleService.getUserRoles(oldUserId));
                }
                String loginName = code;
                if (SystemConstant.longNotNull(oldUserId)) {
                    // 编辑
                    userSaveParams.setId(oldUserId);
                    loginName = oldUser.getLoginName();
                }
                userSaveParams.setOrgId(orgId);
                userSaveParams.setRealName(name);
                userSaveParams.setLoginName(loginName);
                userSaveParams.setRoleIds(roleIdList.toArray(new Long[0]));
                if (SystemConstant.strNotNull(phoneNumber)) {
                    userSaveParams.setMobileNumber(phoneNumber);
                }
                userSaveParams.setCode(code);
                userSaveParams.setSchoolId(schoolId);
                Long upUserId = this.saveUserCommon(userSaveParams, requestUser.getId());
                if (SystemConstant.longNotNull(upUserId)) {

                    Set<Long> currentRoleIdSet = new HashSet<>(Arrays.asList(userSaveParams.getRoleIds()));
                    List<PushUserTrack> pushUserTrackList = pushUserTrackService.createPushTrackUser(oldRoleIdSet, currentRoleIdSet, upUserId, true, requestUser.getId());
                    List<UserPushParam> userPushParamCell = pushUserTrackService.analyzeUserPushSpecialPrivilege(pushUserTrackList);
                    if (userPushParamCell != null && userPushParamCell.size() > 0) {
                        userPushParamList.addAll(userPushParamCell);
                    }
                }
            }
        }
        map.put("userPushParamList", userPushParamList);
//        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();
//        // 保存用户
//        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          courseCode
     * @param orgIds              orgIds
     * @param realName            realName
     * @param flowApproveNameEnum flowApproveNameEnum
     * @return return
     */
    @Override
    public List<ApproveUserResult> findByRootApprove(String courseCode, List<Long> orgIds, String realName, FlowApproveNameEnum flowApproveNameEnum) {
        Long schoolId = SystemConstant.getHeadOrUserSchoolId();
        Set<Long> orgIdsSet = new HashSet<>();
        if (Objects.nonNull(courseCode)) {
            QueryWrapper<BasicCourse> basicCourseQueryWrapper = new QueryWrapper<>();
            basicCourseQueryWrapper.lambda().eq(BasicCourse::getSchoolId, schoolId)
                    .eq(BasicCourse::getCode, courseCode);
            BasicCourse basicCourse = basicCourseService.getOne(basicCourseQueryWrapper);
            Optional.ofNullable(basicCourse).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("课程数据为空"));
            Optional.ofNullable(basicCourse.getTeachingRoomId()).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("课程机构为空"));
            List<SysOrg> sysOrgList = sysOrgService.findByConnectByParentId(basicCourse.getTeachingRoomId(), true, true);
            orgIdsSet.addAll(sysOrgList.stream().map(BaseEntity::getId).collect(Collectors.toSet()));
        } else {
            orgIdsSet.addAll(orgIds);
        }
        return sysUserService.filterFlowPrivilege(schoolId, orgIdsSet, true, flowApproveNameEnum, realName);
    }

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

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

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

    @Override
    public void checkSmsCode(Long userId, String mobileNumber, String code) {
        SysConfig value = sysConfigService.getByKey("sys.code.enable");
        if (Objects.nonNull(value) && value.getConfigValue().equals("true")) {
            if (Objects.isNull(code)) {
                throw ExceptionResultEnum.ERROR.exception("验证码为空");
            }
            if (!dictionaryConfig.smsDomain().getSmsNormalCode().equals(code)) {
                List<VerifyCodeCheckDto> verifyCodeCheckDtoList = this.baseMapper.findVerifyCodeByUser(userId, mobileNumber);
                if (verifyCodeCheckDtoList.size() < 1) {
                    throw ExceptionResultEnum.ERROR.exception("请确认已经发送了验证码");
                }
                VerifyCodeCheckDto accessControl = verifyCodeCheckDtoList.get(0);
                if (accessControl == null || !accessControl.getVerifyCode().equals(code)) {
                    throw ExceptionResultEnum.ERROR.exception("短信验证码错误，请仔细核对后再次输入");
                }

                if (new Date(accessControl.getExpireTime()).before(new Date())) {
                    throw ExceptionResultEnum.ERROR.exception("短信验证码已过期");
                }
            }
        }
    }

    @Transactional
    @Override
    public void expiredVerifyCode(Long userId, String mobileNumber) {
        SysConfig value = sysConfigService.getByKey("sys.code.enable");
        if (Objects.nonNull(value) && value.getConfigValue().equals("true")) {
            int count = this.baseMapper.updateVerifyCodeExpiredTime(userId, mobileNumber);
            if (count != 1) {
                throw ExceptionResultEnum.ERROR.exception("验证码过期失败");
            }
        }
    }


    /**
     * 获取教研室id底下的人数量
     *
     * @param orgId
     * @return
     */
    @Override
    public int countByTeachingRoomId(Long orgId) {
        QueryWrapper<SysUser> sysUserQueryWrapper = new QueryWrapper<>();
        sysUserQueryWrapper.lambda().eq(SysUser::getOrgId, orgId);
        return sysUserService.count(sysUserQueryWrapper);
    }

    @Transactional
    @Override
    public boolean userPushService(List<UserPushParam> userPushParamList, Long requestUserId) throws IllegalAccessException {
        SysUser requestUser = this.getById(requestUserId);
        if (Objects.isNull(requestUser)) {
            log.error("未找到请求用户信息 requestUserId = " + requestUserId);
            throw ExceptionResultEnum.ERROR.exception("未找到请求用户信息");
        }
        boolean result = true;
        for (UserPushParam userPushParam : userPushParamList) {
            boolean syncResult = stmmsUtils.syncUser(userPushParam);
            if (!syncResult) {
                log.warn("-----------------------------用户同步推送失败----------------------------");
                result = false;
                PushUserError pushUserError = new PushUserError();
                pushUserError.setId(SystemConstant.getDbUuid());
                pushUserError.setSchoolId(userPushParam.getSchoolId());
                pushUserError.setUserId(userPushParam.getUserId());
                pushUserError.setAccount(userPushParam.getAccount());
                pushUserError.setName(userPushParam.getName());
                pushUserError.setPassword(userPushParam.getPassword());
                pushUserError.setEnable(userPushParam.getEnable());
                pushUserError.setSubjectCodes(userPushParam.getSubjectCodes());
                pushUserError.setRole(userPushParam.getRole());
                pushUserError.setCreateId(requestUser.getId());
                log.warn(JSON.toJSONString(pushUserError));
                pushUserErrorService.save(pushUserError);
            }
        }
        return result;
    }

    @Transactional
    @Override
    public void autoPushUserErrorData() throws IllegalAccessException {
        List<PushUserError> pushUserErrorList = pushUserErrorService.list();
        Set<Long> userIdSet = pushUserErrorList.stream().map(PushUserError::getUserId).collect(Collectors.toSet());
        if (userIdSet.size() > 0) {
            List<SysUser> sysUserList = this.listByIds(userIdSet);
            // 清空push-user-error表
            pushUserErrorService.remove(new QueryWrapper<PushUserError>().lambda().in(PushUserError::getUserId, userIdSet));
            for (SysUser sysUser : sysUserList) {
                if (!SyncStatusEnum.NEED_PUSH_AGAIN.equals(sysUser.getSyncStatus())) {
                    // 用户同步状态不为需要重新同步的错误数据再同步（防止和需要重新同步类型的数据冲突或因为权限改动导致的反复同步！）
                    Long userId = sysUser.getId();
                    Set<Long> roleIdSet = sysUserRoleService.listRoleByUserId(userId).stream().map(BaseEntity::getId).collect(Collectors.toSet());

                    Long requestUserId = 1L; // 系统管理员
                    List<PushUserTrack> pushUserTrackList = pushUserTrackService.createPushTrackUser(null, roleIdSet, userId, sysUser.getEnable(), requestUserId);
                    List<UserPushParam> userPushParamList = pushUserTrackService.analyzeUserPushSpecialPrivilege(pushUserTrackList);
                    this.userPushService(userPushParamList, requestUserId);
                }
            }
        }
    }

    @Override
    public SpecialPrivilegeEnum findUserSpecialPrivilegeByRoleIdSet(Set<Long> roleIdSet) {
        SpecialPrivilegeEnum result = SpecialPrivilegeEnum.UNIDENTIFIED;
        // 查询该学校特殊权限id
        // 评卷员权限
        SysPrivilege marker = sysPrivilegeService.list(new QueryWrapper<SysPrivilege>().lambda()
                .eq(SysPrivilege::getUrl, SpecialPrivilegeEnum.MARKER.getId())).get(0);
        Long markerId = marker.getId();

        // 科组长权限
        SysPrivilege subjectHeader = sysPrivilegeService.list(new QueryWrapper<SysPrivilege>().lambda()
                .eq(SysPrivilege::getUrl, SpecialPrivilegeEnum.SUBJECT_HEADER.getId())).get(0);
        Long subjectHeaderId = subjectHeader.getId();
        if (roleIdSet.size() > 0) {
            List<SysRolePrivilege> sysRolePrivilegeList = sysRolePrivilegeService.list(new QueryWrapper<SysRolePrivilege>().lambda().in(SysRolePrivilege::getRoleId, roleIdSet));
            Set<Long> priIds = sysRolePrivilegeList.stream().map(SysRolePrivilege::getPrivilegeId).collect(Collectors.toSet());
            if (priIds.size() > 0) {
                if (priIds.contains(markerId) && !priIds.contains(subjectHeaderId)) {
                    // 评卷员权限
                    result = SpecialPrivilegeEnum.MARKER;
                } else if (!priIds.contains(markerId) && priIds.contains(subjectHeaderId)) {
                    // 科组长权限
                    result = SpecialPrivilegeEnum.SUBJECT_HEADER;
                } else if (priIds.contains(markerId) && priIds.contains(subjectHeaderId)) {
                    // 复合权限
                    result = SpecialPrivilegeEnum.COMPOSITE;
                }
            }
        }
        return result;
    }

    @Override
    public SpecialPrivilegeEnum findUserSpecialPrivilegeByUserId(Long userId) {
        Set<Long> roleIdSet = new HashSet<>(sysRoleService.getUserRoles(userId));
        return this.findUserSpecialPrivilegeByRoleIdSet(roleIdSet);
    }

    @Transactional
    @Override
    public SyncCountResult needPushAgainOperate(SysUser requestUser) throws IllegalAccessException {
        int correctCount = 0;
        int totalCount = 0;
        if (Objects.isNull(requestUser)) {
            throw ExceptionResultEnum.ERROR.exception("未找到请求用户");
        }
        Long schoolId = requestUser.getSchoolId();
        Long requestUserId = requestUser.getId();
        // 需要同步的用户
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUser::getSyncStatus, SyncStatusEnum.NEED_PUSH_AGAIN);
        if (SystemConstant.longNotNull(schoolId)) {
            queryWrapper.lambda().eq(SysUser::getSchoolId, schoolId);
        }
        List<SysUser> sysUserList = sysUserService.list(queryWrapper);
        totalCount = sysUserList.size();
        for (SysUser user : sysUserList) {
            Set<Long> roleIdSet = sysUserRoleService.listRoleByUserId(user.getId()).stream().map(BaseEntity::getId).collect(Collectors.toSet());
            List<PushUserTrack> pushUserTrackList = pushUserTrackService.createPushTrackUser(null, roleIdSet, user.getId(), user.getEnable(), requestUserId);
            List<UserPushParam> userPushParamList = pushUserTrackService.analyzeUserPushSpecialPrivilege(pushUserTrackList);

            boolean syncResult = sysUserService.userPushService(userPushParamList, requestUserId);
            if (syncResult) {
                correctCount++;
            }
            UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().set(SysUser::getSyncStatus, null).eq(SysUser::getId, user.getId());
            sysUserService.update(updateWrapper);
        }
        SyncCountResult syncCountResult = new SyncCountResult();
        syncCountResult.setTotalCount(totalCount);
        syncCountResult.setCorrectCount(correctCount);
        return syncCountResult;
    }

    /**
     * 查找用户角色名
     *
     * @param userIds
     * @return
     */
    @Override
    public List<UserRoleNameResult> selectRoleNames(List<Long> userIds) {
        return sysUserMapper.selectRoleNames(userIds);
    }

    /**
     * 根据角色ids查找用户
     *
     * @param roleIds
     * @return
     */
    @Override
    public List<SysUser> findByRoleIds(List<Long> roleIds) {
        return sysUserMapper.findByRoleIds(roleIds);
    }

    /**
     * 根据角色ids查找用户
     *
     * @param roleIds
     * @return
     */
    @Override
    public List<ApproveUserResult> findByRoleIdsForResult(List<Long> roleIds) {
        return sysUserMapper.findByRoleIdsForResult(roleIds);
    }

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

    @Override
    public List<Long> findOrgIdListByUserId(Long userId) {
        List<Long> orgIdList = new ArrayList<>();
        Long orgId = this.getById(userId).getOrgId();
        if (SystemConstant.longNotNull(orgId)) {
            orgIdList.add(orgId);
        }
        return orgIdList.stream().distinct().collect(Collectors.toList());
    }

    @Override
    public boolean isAdminDataAuth(Long userId) {
        boolean result = false;
        List<SysOrg> sysOrgList = sysOrgService.list();
        SysUser user = this.getById(userId);
        if (Objects.isNull(user)) {
            throw ExceptionResultEnum.ERROR.exception("用户不存在");
        }
        Long schoolId = user.getSchoolId();
        if (SystemConstant.longNotNull(schoolId)) {
            List<Long> orgIdList = this.findOrgIdListByUserId(userId);
            if (sysOrgList.stream().anyMatch(e -> orgIdList.contains(e.getId()) && OrgTypeEnum.SCHOOL.equals(e.getType()))) {
                result = true;
            }
        } else {
            result = true;
        }
        return result;
    }

    @Override
    public List<SysUserResult> findSysUserResultList() {
        Long schoolId = SystemConstant.convertIdToLong(String.valueOf(ServletUtil.getRequestHeaderSchoolId()));
        List<SysUser> sysUserDatasource = sysUserService.list(new QueryWrapper<SysUser>().lambda().eq(SysUser::getSchoolId, schoolId));
        List<SysRole> sysRoleDatasource = sysRoleService.list(new QueryWrapper<SysRole>().lambda().eq(SysRole::getSchoolId, schoolId));
        List<SysUserRole> sysUserRoleDatasource = sysUserRoleService.list();

        return sysUserDatasource.stream().flatMap(e -> {
            Set<Long> roleIdSet = sysUserRoleDatasource.stream().filter(ur -> e.getId().equals(ur.getUserId())).map(SysUserRole::getRoleId).collect(Collectors.toSet());
            List<RoleResult> roleResultCellList = new ArrayList<>();
            if (roleIdSet.size() > 0) {
                roleResultCellList = sysRoleDatasource.stream().filter(r -> roleIdSet.contains(r.getId())).flatMap(rr -> {
                    RoleResult roleResult = new RoleResult();
                    roleResult.setRoleId(rr.getId());
                    roleResult.setRoleName(rr.getName());
                    return Stream.of(roleResult);
                }).collect(Collectors.toList());
            }
            SysUserResult sysUserResult = new SysUserResult();
            sysUserResult.setId(e.getId());
            sysUserResult.setLoginName(e.getLoginName());
            sysUserResult.setRealName(e.getRealName());
            sysUserResult.setMobileNumber(e.getMobileNumber());
            sysUserResult.setOrgId(e.getOrgId());
            sysUserResult.setRoleResultList(roleResultCellList);
            return Stream.of(sysUserResult);
        }).collect(Collectors.toList());
    }

    /**
     * 根据roleId和成员姓名获取
     *
     * @param roleId
     * @param name
     * @return
     */
    @Override
    public List<ApproveUserResult> findByRoldIdAndMemberName(Long roleId, String name) {
        return sysUserMapper.findByRoldIdAndMemberName(roleId, name);
    }

    @Override
    public List<SysUser> findBySchoolIdAndCode(Long schoolId, String code) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUser::getSchoolId, schoolId).eq(SysUser::getCode, code);
        return sysUserMapper.selectList(queryWrapper);
    }

    /**
     * 批量处理用户信息帮助类
     *
     * @param userSaveParamsList 用户信息集合
     * @param master             创建人信息
     * @return 处理后的结果
     */
    @Deprecated
    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 + "】重复");
                }
            }
            // 手机号检验
            if (SystemConstant.strNotNull(mobileNumber)) {
                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 LinkedHashSet<Long> analyzeRoleName(Long schoolId, String roleName) {
        LinkedHashSet<Long> roleIdList = new LinkedHashSet<>();
        String[] arr = roleName.split(SystemConstant.COMMA);
        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;
    }

    /**
     * 用户禁用启用特殊权限判断及处理
     *
     * @param userId        用户id
     * @param enable        启用/禁用
     * @param requestUserId 请求人id
     */
    private void analyzeUserEnableSpecialPrivilege(Long userId, boolean enable, Long requestUserId) throws IllegalAccessException {
        SysUser dbUser = sysUserService.getById(userId);
        if (Objects.isNull(dbUser)) {
            throw ExceptionResultEnum.ERROR.exception("未找到系统用户");
        }
        Set<Long> currentRoleIdSet = new HashSet<>(sysRoleService.getUserRoles(userId));
        List<PushUserTrack> pushUserTrackList = pushUserTrackService.createPushTrackUser(null, currentRoleIdSet, userId, enable, requestUserId);
        List<UserPushParam> userPushParamList = pushUserTrackService.analyzeUserPushSpecialPrivilege(pushUserTrackList);
        if (userPushParamList != null && userPushParamList.size() > 0) {
            this.userPushService(userPushParamList, requestUserId);
        }
    }
}
