package com.codvision.auth.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.codvision.auth.entity.Org;
import com.codvision.auth.entity.SysRole;
import com.codvision.auth.entity.SysUser;
import com.codvision.auth.entity.UserOrgRole;
import com.codvision.auth.entity.dto.SysOrgQueryDTO;
import com.codvision.auth.entity.dto.SysUserDTO;
import com.codvision.auth.entity.dto.SysUserQueryDTO;
import com.codvision.auth.entity.excel.SysUserExcel;
import com.codvision.auth.entity.vo.OrgVO;
import com.codvision.auth.entity.vo.QuickLoginVO;
import com.codvision.auth.entity.vo.SysUserVO;
import com.codvision.auth.entity.vo.UserOrgRoleVO;
import com.codvision.auth.mapper.OrgMapper;
import com.codvision.auth.mapper.SysRoleMapper;
import com.codvision.auth.mapper.SysUserMapper;
import com.codvision.auth.mapper.UserOrgRoleMapper;
import com.codvision.auth.service.IOrgService;
import com.codvision.auth.service.ISysRoleService;
import com.codvision.auth.service.ISysUserService;
import com.codvision.auth.service.IUserOrgRoleService;
import com.codvision.base.config.excel.AbstractExportClass;
import com.codvision.base.config.excel.ExcelDataReadListener;
import com.codvision.base.entity.ExcelCheck;
import com.codvision.base.entity.ExcelErrorRecord;
import com.codvision.base.entity.SysConfig;
import com.codvision.base.service.ISysConfigService;
import com.codvision.commoncore.exception.BusinessException;
import com.codvision.commoncore.utils.*;
import com.codvision.webcore.bean.QueryPage;
import com.codvision.webcore.service.impl.BaseServiceImpl;
import com.codvision.webcore.util.PageUtil;
import com.google.common.base.Preconditions;
import lombok.SneakyThrows;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.*;

import static com.codvision.auth.support.AuthConst.PWD_CHECK_FLAG;
import static com.codvision.base.support.BaseConst.SLASH_SYMBOL;

/**
 * <p>
 * 系统用户 服务实现类
 * </p>
 *
 * @author lingee
 * @since 2023-11-09
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser, SysUserVO> implements ISysUserService {

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private ISysConfigService sysConfigService;

    @Resource
    private BCryptPasswordEncoder bCryptEncode;

    @Resource
    private IUserOrgRoleService userOrgRoleService;

    @Resource
    private UserOrgRoleMapper userOrgRoleMapper;

    @Resource
    private IOrgService orgService;

    @Resource
    private ISysRoleService sysRoleService;

    @Resource
    private SysRoleMapper sysRoleMapper;

    @Resource
    private OrgMapper orgMapper;

    @Override
    public SysUserVO getDetail(Integer id) {
        SysUserVO vo = new SysUserVO();
        SysUser po = this.getById(id);
        if (null != po) {
            BeanUtil.copyProperties(po, vo);
        }
        return initTarget(vo);
    }

    @Override
    public void batchResetPwd(List<Integer> userIds) {
        SysConfig sysConfig = sysConfigService.getByKey("GLOBAL_DEFAULT_PWD");
        Preconditions.checkArgument(ObjectUtil.isNotEmpty(sysConfig) && StrUtil.isNotBlank(sysConfig.getV()),
                "请于系统配置界面内设置全局默认密码！");

        String pwd = bCryptEncode.encode(sysConfig.getV());
        List<SysUser> sysUserList = new ArrayList<>();
        for (Integer uid : userIds) {
            SysUser sysUser = new SysUser();
            sysUser.setId(uid);
            sysUser.setPassword(pwd);
            sysUserList.add(sysUser);
        }
        this.updateBatchById(sysUserList);
    }

    @Override
    public void activeOrgRole(UserOrgRole userOrgRole, SysUserVO sysUserVO) {
        UserOrgRole isExist = userOrgRoleService.getUserOrgRole(userOrgRole.getUid(), userOrgRole.getOid(), userOrgRole.getRoleId());
        Preconditions.checkArgument(isExist != null, "切换用户组织角色失败，请重试");
        initCurrentActiveUserInfo(sysUserVO, userOrgRole.getOid(), userOrgRole.getRoleId());

        UserOrgRole updateBean = new UserOrgRole();
        updateBean.setUpdateTime(new Date());
        userOrgRoleService.update(updateBean, Wrappers.<UserOrgRole>lambdaUpdate()
                .eq(UserOrgRole::getUid, userOrgRole.getUid())
                .eq(UserOrgRole::getOid, userOrgRole.getOid())
                .eq(UserOrgRole::getRoleId, userOrgRole.getRoleId()));
    }

    @Override
    public SysUserVO getDetailByLoginName(String loginName) {
        SysUserVO vo = getByLoginName(loginName);
        if (ObjectUtil.isEmpty(vo)) {
            return null;
        }
        return initTarget(vo);
    }

    @Override
    public boolean isRenewPwd(String username) {
        // 系统用户密码定期更新提醒开关（ON:启用 OFF:关闭）
        SysConfig config = sysConfigService.getByKey("PWD_UPDATE_REMIND_SWITCH");
        if (config != null && PWD_CHECK_FLAG.equals(config.getV())) {
            SysConfig dayConfig = sysConfigService.getByKey("PWD_UPDATE_REMIND_INTERVAL_DAYS");
            if (dayConfig != null) {
                int intervalDays;
                try {
                    intervalDays = Integer.parseInt(dayConfig.getV());
                } catch (NumberFormatException e) {
                    // 非数据类型（含空值），间隔天数默认设置为30天
                    intervalDays = 30;
                }

                SysUser sysUser = this.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getLoginName, username));
                if (sysUser != null) {
                    Date pwdLastUpdatedTime = sysUser.getPwdLastUpdatedTime();
                    if (ObjectUtil.isNotEmpty(pwdLastUpdatedTime)) {
                        return DateUtil.between(pwdLastUpdatedTime, new Date(), DateUnit.DAY) >= intervalDays;
                    }
                }
            }
        }
        return false;
    }

    @Override
    public String quickLogin(String token, String userInformation) {
        List<SysConfig> configs = sysConfigService.getListByKeys(Arrays.asList("QUICK_LOGIN_PRIVATE_KEY",
                "QUICK_LOGIN_PUBLIC_KEY", "QUICK_LOGIN_APP_ID", "QUICK_LOGIN_APP_KEY", "QUICK_LOGIN_URL"));
        Preconditions.checkArgument(!(CollectionUtils.isEmpty(configs) || configs.size() < 5), "请核查相关配置信息");

        Map<String, String> configMap = new HashMap<>(16);
        for (SysConfig config : configs) {
            Preconditions.checkArgument(StringUtils.isNotBlank(config.getV()), "请核查相关配置信息");
            configMap.put(config.getK(), config.getV());
        }

        String version = "1.0";
        String timestamp = LocalDateTimeUtil.format(LocalDateTimeUtil.now(), DatePattern.PURE_DATETIME_MS_PATTERN);
        String traceId = UUID.randomUUID().toString();
        JSONObject params = new JSONObject();
        params.put("userInformation", userInformation);
        params.put("token", token);
        String data = configMap.get("QUICK_LOGIN_APP_ID") + traceId + timestamp + token + version;
        LySign lySign = LySign.of(SignAlgorithm.SHA256withRSA, configMap.get("QUICK_LOGIN_PRIVATE_KEY"), configMap.get("QUICK_LOGIN_PUBLIC_KEY"), false);
        params.put("sign", lySign.sign(data));
        Map<String, String> headers = new HashMap<>();
        headers.put("interfaceVersion", version);
        headers.put("appId", configMap.get("QUICK_LOGIN_APP_ID"));
        headers.put("traceId", traceId);
        headers.put("timestamp", timestamp);
        headers.put("businessType", "8");
        String response = HttpClientUtils.doPost(configMap.get("QUICK_LOGIN_URL"), headers, params.toString());

        QuickLoginVO quickLoginVO = JSONUtil.toBean(response, QuickLoginVO.class);
        if (!"103000".equals(quickLoginVO.getResultCode())) {
            throw new BusinessException(quickLoginVO.getDesc());
        }

        String appKey = configMap.get("QUICK_LOGIN_APP_KEY");
        if (appKey.length() > 16) {
            appKey = appKey.substring(0, 16);
        } else {
            appKey = StringUtils.rightPad(appKey, 16, "0");
        }

        AesUtil aes = new AesUtil(appKey);
        return new String(aes.decryptBase64(quickLoginVO.getData().getMsisdn()));
    }

    @Override
    public void loginByMobile(String mobile) {
        SysUserVO userVO = this.getByLoginName(mobile);
        if (userVO == null) {
            SysUser sysUser = new SysUser();
            sysUser.setLoginName(mobile);
            sysUser.setName(mobile);
            sysUser.setMobile(mobile);
            this.save(sysUser);

            UserOrgRole userOrgRole = new UserOrgRole();
            userOrgRole.setUid(sysUser.getId());

            Org defaultOrg = orgService.getDefaultOrg();
            Preconditions.checkArgument(defaultOrg != null, "暂无任何组织信息");
            userOrgRole.setOid(defaultOrg.getOid());

            SysRole defaultRole = sysRoleService.getDefaultRole();
            Preconditions.checkArgument(defaultRole != null, "暂无默认角色");
            userOrgRole.setRoleId(defaultRole.getId());
            userOrgRoleMapper.insert(userOrgRole);
        }
    }

    @Override
    public Integer addSysUser(SysUserDTO sysUserDTO) {
        // 获取明文密码
        String password = DecPwdUtil.decryptAes(sysUserDTO.getPassword());
        // 弱密码过滤
        boolean isNotWeak = CheckPwdUtil.checkPasswordRule(sysUserDTO.getLoginName(), password);
        if (!isNotWeak) {
            throw new BusinessException(30001, "密码必须包括大小写字母、数字和特殊符号，长度8-15位且不能与用户名相同！");
        }
        // 检查登陆名是否已存在
        SysUser checkUser = this.getByLoginName(sysUserDTO.getLoginName());
        Preconditions.checkArgument(checkUser == null, "用户名已存在！");

        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserDTO, sysUser);
        // 采用BCrypt算法加密存储入库
        sysUser.setPassword(bCryptEncode.encode(password));
        this.save(sysUser);

        // 设置用户与组织、角色的关系
        if (CollectionUtil.isNotEmpty(sysUserDTO.getUserOrgRoles())) {
            for (UserOrgRole userOrgRole : sysUserDTO.getUserOrgRoles()) {
                Preconditions.checkArgument(!(null == userOrgRole.getRoleId() || null == userOrgRole.getOid()), 30002);
                userOrgRole.setUid(sysUser.getId());
                userOrgRoleMapper.insert(userOrgRole);
            }
        }
        return sysUser.getId();
    }

    @Override
    public SysUserVO getDetailByUid(Integer uid) {
        SysUserVO vo = getDetail(uid);

        UserOrgRoleVO activeOrgRole = userOrgRoleMapper.getLatestInfoDetail(uid);
        if (ObjectUtil.isNotEmpty(activeOrgRole)) {
            activeOrgRole.setRole(sysRoleService.getDetail(activeOrgRole.getRoleId()));
            vo.setActiveOrgRole(activeOrgRole);
            vo.setActiveOid(activeOrgRole.getOid());
            vo.setActiveRoleId(activeOrgRole.getRoleId());
            vo.setActiveRoleCode(activeOrgRole.getRoleCode());
        }

        List<UserOrgRoleVO> userOrgRoles = userOrgRoleMapper.getUserOrgRoleList(uid);
        if (CollectionUtil.isNotEmpty(userOrgRoles)) {
            userOrgRoles.forEach(userOrgRole -> {
                userOrgRole.setRole(sysRoleService.getDetail(userOrgRole.getRoleId()));
            });
            vo.setOrgRoles(userOrgRoles);
        }
        return vo;
    }

    @Override
    public IPage<SysUserVO> findAll(QueryPage<SysUser> queryPage, SysUserQueryDTO queryDTO) {
        IPage<SysUser> page = queryPage.getPage();
        List<SysUserVO> sysUserList = sysUserMapper.findAll(page, queryDTO);
        sysUserList.forEach(sysUserVO -> sysUserVO.setAssociatedInfos(userOrgRoleMapper.getAssociatedInfos(sysUserVO.getId())));
        return PageUtil.convertPage(page, sysUserList);
    }

    @Override
    public List<SysUserVO> listUsers(Map<String, Object> params) {
        List<SysUserVO> sysUserList = sysUserMapper.listUsers(params);
        if (CollectionUtils.isNotEmpty(sysUserList)) {
            sysUserList.forEach(sysUserVO -> sysUserVO.setAssociatedInfos(userOrgRoleMapper.getAssociatedInfos(sysUserVO.getId())));

        }
        return sysUserList;
    }

    @Override
    public void updateUser(SysUserDTO sysUserDTO) {
        SysUser checkSysUser = this.getById(sysUserDTO.getId());
        if (ObjectUtil.isEmpty(checkSysUser)) {
            throw new BusinessException(30001);
        }

        if (StringUtils.isNotBlank(sysUserDTO.getLoginName()) && !sysUserDTO.getLoginName().equals(checkSysUser.getLoginName())) {
            SysUser sysUser = getByLoginName(sysUserDTO.getLoginName());
            Preconditions.checkArgument(sysUser == null, "用户名已存在！");
        }

        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserDTO, sysUser);

        // 判断是否修改密码
        if (checkModifyPwd(sysUserDTO, sysUser)) {
            sysUser.setPwdLastUpdatedTime(new Date());
        }
        // 更新用户信息
        this.updateById(sysUser);

        // 是否修改组织与角色
        if (CollectionUtils.isNotEmpty(sysUserDTO.getUserOrgRoles())) {
            userOrgRoleMapper.delete(Wrappers.<UserOrgRole>lambdaQuery().eq(UserOrgRole::getUid, sysUser.getId()));
            for (UserOrgRole userOrgRole : sysUserDTO.getUserOrgRoles()) {
                Preconditions.checkArgument(!((null == userOrgRole.getRoleId() && null == userOrgRole.getRoleCode())
                        || null == userOrgRole.getOid()), 30002);
                userOrgRole.setUid(sysUser.getId());
                if (StringUtils.isNotBlank(userOrgRole.getRoleCode())) {
                    SysRole sysRole = sysRoleMapper.selectOne(Wrappers.<SysRole>lambdaQuery()
                            .eq(SysRole::getRoleCode, userOrgRole.getRoleCode()).last("limit 1"));
                    Preconditions.checkArgument(sysRole != null, 30001);
                    userOrgRole.setRoleId(sysRole.getId());
                }
                userOrgRoleMapper.insert(userOrgRole);
            }
        }
    }

    @Override
    @SneakyThrows
    public String excelImport(MultipartFile file) {
        // 优先获取组织和角色信息列表，避免数据校验或操作时需要频繁的进行数据库操作
        Map<String, Object> paraMap = new HashMap<>(16);
        SysOrgQueryDTO queryDTO = new SysOrgQueryDTO();
        queryDTO.setIsIgnoreWkt(true);
        List<OrgVO> orgList = orgMapper.findAll(null, queryDTO);
        Preconditions.checkArgument(CollectionUtils.isNotEmpty(orgList), "暂无任何组织信息，请至组织管理添加组织信息");
        List<SysRole> sysRoleList = sysRoleService.list();
        Preconditions.checkArgument(CollectionUtils.isNotEmpty(sysRoleList), "暂无任何角色信息，请至角色管理添加角色信息");

        String reqNo = IdUtil.fastSimpleUUID();
        ISysUserService service = SpringUtil.getBean(ISysUserService.class);
        ExcelDataReadListener<SysUserExcel> listener = new ExcelDataReadListener<SysUserExcel>(cachedDataList -> service.excelSave(cachedDataList, orgList, sysRoleList)) {
            @Override
            protected void validator(SysUserExcel sysUserExcel, ExcelCheck<SysUserExcel> check, AnalysisContext context) {
                checkOne(reqNo, sysUserExcel, check, context.readRowHolder().getRowIndex(), orgList, sysRoleList);
            }
        };
        EasyExcel.read(file.getInputStream(), SysUserExcel.class, listener).sheet().doRead();
        if (listener.isHeadAbnormal()) {
            throw new BusinessException("文件格式错误，请检查导入模板");
        }

        return listener.existErrorData() ? reqNo : null;
    }


    private void checkOne(String reqNo, SysUserExcel sysUserExcel, ExcelCheck<SysUserExcel> check, Integer rowIndex, List<OrgVO> orgList, List<SysRole> sysRoleList) {
        Map<String, Object> fieldsErrorMap = new HashMap<>(16);
        if (StringUtils.isBlank(sysUserExcel.getName())) {
            fieldsErrorMap.put("name", "姓名必填");
        }
        if (StringUtils.isBlank(sysUserExcel.getMobile())) {
            fieldsErrorMap.put("mobile", "联系方式必填");
        } else {
            if (!Validator.isMobile(sysUserExcel.getMobile())) {
                fieldsErrorMap.put("mobile", "联系方式格式错误");
            }
        }

        String orgName = sysUserExcel.getOrgName();
        if (StringUtils.isBlank(orgName)) {
            fieldsErrorMap.put("orgName", "组织名称必填");
        } else {
            if (!(orgName.startsWith(SLASH_SYMBOL) && orgName.endsWith(SLASH_SYMBOL))) {
                fieldsErrorMap.put("orgName", "格式错误");
            } else {
                Optional<OrgVO> optional = orgList.stream().filter(org -> orgName.equals(org.getPath())).findFirst();
                if (!optional.isPresent()) {
                    fieldsErrorMap.put("orgName", "系统内无相关组织信息");
                }
            }
        }

        if (StringUtils.isBlank(sysUserExcel.getRole())) {
            fieldsErrorMap.put("role", "角色名称必填");
        } else {
            Optional<SysRole> optional = sysRoleList.stream().filter(role -> sysUserExcel.getRole().equals(role.getRoleName())).findFirst();
            if (!optional.isPresent()) {
                fieldsErrorMap.put("role", "系统内无相关角色信息");
            }
        }

        if (fieldsErrorMap.isEmpty()) {
            check.getCacheList().add(sysUserExcel);
        } else {
            ExcelErrorRecord record = new ExcelErrorRecord();
            record.setReqNo(reqNo);
            record.setRowIndex(rowIndex);
            record.setOriginalJsonValue(JSONUtil.toJsonStr(sysUserExcel));
            record.setErrorMsgJson(JSONUtil.toJsonStr(fieldsErrorMap));
            record.setTargetObject(sysUserExcel.getClass().getName());
            check.getErrorList().add(record);
        }
    }

    @Override
    public void excelSave(List<SysUserExcel> cachedDataList, List<OrgVO> orgList, List<SysRole> sysRoleList) {
        if (CollectionUtils.isNotEmpty(cachedDataList)) {
            List<UserOrgRole> userOrgRoles = new ArrayList<>();
            for (SysUserExcel sysUserExcel : cachedDataList) {
                SysUser sysUser = this.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getMobile, sysUserExcel.getMobile()));
                if (sysUser == null) {
                    sysUser = new SysUser();
                    sysUser.setLoginName(sysUserExcel.getMobile());
                    sysUser.setPassword(bCryptEncode.encode(sysUserExcel.getMobile()));
                    sysUser.setMobile(sysUserExcel.getMobile());
                    sysUser.setName(sysUserExcel.getName());
                    this.save(sysUser);

                    // 添加用户、组织与角色的关联关系
                    UserOrgRole userOrgRole = new UserOrgRole();
                    userOrgRole.setUid(sysUser.getId());
                    Optional<OrgVO> orgOptional = orgList.stream().filter(org -> sysUserExcel.getOrgName().equals(org.getPath())).findFirst();
                    orgOptional.ifPresent(org -> userOrgRole.setOid(org.getOid()));
                    Optional<SysRole> roleOptional = sysRoleList.stream().filter(role -> sysUserExcel.getRole().equals(role.getRoleName())).findFirst();
                    roleOptional.ifPresent(role -> userOrgRole.setRoleId(role.getId()));
                    userOrgRoles.add(userOrgRole);
                }
            }
            if (CollectionUtil.isNotEmpty(userOrgRoles)) {
                userOrgRoleService.saveBatch(userOrgRoles);
            }
        }
    }

    @Override
    public void excelExport(SysUserQueryDTO queryDTO) {
        new AbstractExportClass<SysUserExcel, SysUser>() {
            @Override
            protected List<SysUserExcel> getList(QueryPage<SysUser> queryPage, Object queryBean) {
                List<SysUserExcel> excelList = new ArrayList<>();
                List<SysUserVO> sysUserVOList = getBaseMapper().findAll(null, (SysUserQueryDTO) queryBean);
                if (CollectionUtils.isNotEmpty(sysUserVOList)) {
                    for (SysUserVO sysUserVO : sysUserVOList) {
                        SysUserExcel sysUserExcel = new SysUserExcel();
                        sysUserExcel.setName(sysUserVO.getName());
                        sysUserExcel.setMobile(sysUserVO.getMobile());
                        sysUserExcel.setOrgName(sysUserVO.getActiveOrgPath());
                        sysUserExcel.setRole(sysUserVO.getActiveRoleName());
                        excelList.add(sysUserExcel);
                    }
                }
                return excelList;
            }
        }.excelUser("用户信息表", queryDTO, SysUserExcel.class);
    }

    @Override
    public SysUserVO getByDingTalkUid(String dingTalkUid) {
        SysUser po = this.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getDingTalkUid, dingTalkUid).last("limit 1"));
        SysUserVO vo = new SysUserVO();
        if (ObjectUtil.isEmpty(po)) {
            return null;
        }
        BeanUtil.copyProperties(po, vo);
        vo.setAssociatedInfos(userOrgRoleMapper.getAssociatedInfos(vo.getId()));
        return initTarget(vo);
    }

    @Override
    public SysUserVO getByZzdId(String zzdId) {
        SysUser po = this.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getZzdId, zzdId).last("limit 1"));
        SysUserVO vo = new SysUserVO();
        if (ObjectUtil.isEmpty(po)) {
            return null;
        }
        BeanUtil.copyProperties(po, vo);
        vo.setAssociatedInfos(userOrgRoleMapper.getAssociatedInfos(vo.getId()));
        return initTarget(vo);
    }

    /**
     * 根据登录名获取用户信息
     *
     * @param loginName 登录名
     * @return 用户信息
     */
    private SysUserVO getByLoginName(String loginName) {
        SysUser po = this.getOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getLoginName, loginName));
        SysUserVO vo = new SysUserVO();
        if (ObjectUtil.isEmpty(po)) {
            return null;
        }
        BeanUtil.copyProperties(po, vo);
        vo.setAssociatedInfos(userOrgRoleMapper.getAssociatedInfos(vo.getId()));
        return vo;
    }

    /**
     * 判断是否修改密码
     *
     * @param sysUserDTO 输入用户信息
     * @param sysUser    已有用户信息
     */
    private boolean checkModifyPwd(SysUserDTO sysUserDTO, SysUser sysUser) {
        if (StringUtils.isNotBlank(sysUserDTO.getOldPwd()) && StringUtils.isNotBlank(sysUserDTO.getNewPwd())) {
            SysUser checkUser = this.getById(sysUserDTO.getId());
            Preconditions.checkArgument(checkUser != null, 30001);

            // 获取明文密码
            String oldPwd = DecPwdUtil.decryptAes(sysUserDTO.getOldPwd());
            Preconditions.checkArgument(bCryptEncode.matches(oldPwd, checkUser.getPassword()), "旧密码验证失败！");
            // 设置新密码
            String newPwd = DecPwdUtil.decryptAes(sysUserDTO.getNewPwd());
            // 弱密码过滤
            boolean isNotWeak = CheckPwdUtil.checkPasswordRule(checkUser.getLoginName(), newPwd);
            if (!isNotWeak) {
                throw new BusinessException(30001, "密码必须包括大小写字母、数字和特殊符号，长度8-15位且不能与用户名相同！");
            }
            sysUser.setPassword(bCryptEncode.encode(newPwd));
            return true;
        }
        return false;
    }

    private SysUserVO initTarget(SysUserVO sysUserVO) {
        if (ObjectUtil.isEmpty(sysUserVO)) {
            return null;
        }

        UserOrgRole userOrgRole = userOrgRoleMapper.getLatestInfo(sysUserVO.getId());
        if (ObjectUtil.isEmpty(userOrgRole)) {
            return null;
        }

        initCurrentActiveUserInfo(sysUserVO, userOrgRole.getOid(), userOrgRole.getRoleId());
        return sysUserVO;
    }

    private void initCurrentActiveUserInfo(SysUserVO sysUserVO, Integer oid, Integer roleId) {
        if (oid == null || roleId == null || sysUserVO == null) {
            return;
        }

        Org org = orgService.getById(oid);
        Preconditions.checkArgument(org != null, "获取组织信息失败！");
        sysUserVO.setActiveOrgName(org.getName());
        sysUserVO.setActiveOid(org.getOid());
        sysUserVO.setActivePoid(org.getPoid());
        sysUserVO.setActiveOrgPath(org.getPath());

        SysRole sysRole = sysRoleService.getById(roleId);
        Preconditions.checkArgument(sysRole != null, "获取角色信息失败！");
        sysUserVO.setActiveRoleId(sysRole.getId());
        sysUserVO.setActiveRoleName(sysRole.getRoleName());
        sysUserVO.setActiveRoleCode(sysRole.getRoleCode());
    }

    @Override
    public List<SysUserVO> getListByIds(List<Integer> uidList) {
        List<SysUserVO> sysUserVOS = new ArrayList<>();
        List<SysUser> sysUsers = getBaseMapper().selectBatchIds(uidList);
        for (SysUser sysUser : sysUsers) {
            SysUserVO sysUserVO = new SysUserVO();
            BeanUtil.copyProperties(sysUser, sysUserVO);
            UserOrgRoleVO activeOrgRole = userOrgRoleMapper.getLatestInfoDetail(sysUser.getId());
            if (activeOrgRole != null) {
                sysUserVO.setActiveOrgRole(activeOrgRole);
            }

            List<UserOrgRoleVO> userOrgRoleList = userOrgRoleMapper.getUserOrgRoleList(sysUser.getId());
            if (CollectionUtils.isNotEmpty(userOrgRoleList)) {
                sysUserVO.setOrgRoles(userOrgRoleList);
            }

            sysUserVOS.add(sysUserVO);
        }

        return sysUserVOS;
    }
}
