package com.qmth.sop.business.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.service.impl.ServiceImpl;
import com.qmth.boot.api.exception.ApiException;
import com.qmth.boot.core.enums.Platform;
import com.qmth.sop.business.bean.auth.AuthBean;
import com.qmth.sop.business.bean.auth.ExpireTimeBean;
import com.qmth.sop.business.bean.dto.*;
import com.qmth.sop.business.bean.result.*;
import com.qmth.sop.business.cache.CommonCacheService;
import com.qmth.sop.business.entity.*;
import com.qmth.sop.business.mapper.SysUserMapper;
import com.qmth.sop.business.service.*;
import com.qmth.sop.business.sync.RtzfApiUtils;
import com.qmth.sop.business.sync.been.rtzf.RtzfResult;
import com.qmth.sop.business.sync.been.rtzf.RtzfUserInfo;
import com.qmth.sop.business.util.AuthUtil;
import com.qmth.sop.common.contant.SpringContextHolder;
import com.qmth.sop.common.contant.SystemConstant;
import com.qmth.sop.common.enums.*;
import com.qmth.sop.common.util.IpUtil;
import com.qmth.sop.common.util.ResultUtil;
import com.qmth.sop.common.util.ServletUtil;
import com.qmth.sop.common.util.SessionUtil;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author wangliang
 * @since 2023-07-17
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Resource
    CommonCacheService commonCacheService;

    @Resource
    TBSessionService tbSessionService;

    @Resource
    SysRoleService sysRoleService;

    @Resource
    SysUserRoleService sysUserRoleService;

    @Resource
    TBUserArchivesService tbUserArchivesService;

    @Resource
    RtzfApiUtils rtzfApiUtils;

    @Override
    public LoginResult login(String password, SysUser sysUser, AppSourceEnum appSource) throws NoSuchAlgorithmException {
        //停用
        if (!sysUser.getEnable()) {
            throw ExceptionResultEnum.USER_ENABLE.exception();
        }
        Platform platform = ServletUtil.getRequestPlatform();
        String deviceId = ServletUtil.getRequestDeviceId();
        //添加用户鉴权缓存
        AuthBean authBean = commonCacheService.userAuthCache(sysUser.getId());
        Optional.ofNullable(authBean).orElseThrow(ExceptionResultEnum.ROLE_ENABLE_AUTHORIZATION::exception);

        List<SysRole> sysRoleList = authBean.getRoleList().stream().filter(s -> s.getType() == RoleTypeEnum.EFFECT_ENGINEER || s.getType() == RoleTypeEnum.ASSISTANT_ENGINEER).collect(Collectors.toList());
        if (appSource == AppSourceEnum.WX_APP && CollectionUtils.isEmpty(sysRoleList)) {
            throw ExceptionResultEnum.WX_APP_LOGIN_ERROR.exception();
        }
        //生成token
        String token = SystemConstant.getNanoId();
        //添加用户会话缓存
        Set<String> roleNamesSet = new LinkedHashSet<>(), roleTypes = new HashSet<>();
        for (SysRole s : authBean.getRoleList()) {
            roleNamesSet.add(s.getName());
            if (Objects.nonNull(s.getType())) {
                roleTypes.add(s.getType().name());
            }
        }
        List<String> roleNames = new ArrayList<>(roleNamesSet);
        Collections.sort(roleNames);

        String sessionId = SessionUtil.digest(sysUser.getId(), Math.abs(roleNames.toString().hashCode()), platform.name());
        ExpireTimeBean expireTime = AuthUtil.getExpireTime(platform);
        TBSession tbSession = new TBSession(sessionId, String.valueOf(sysUser.getId()), roleNames.toString(),
                platform.name(), platform.name(), deviceId, IpUtil.getRemoteIp(), token,
                expireTime.getDate().getTime(), appSource);
        tbSessionService.saveOrUpdate(tbSession);
        commonCacheService.setUserSession(sessionId, tbSession);

        LoginResult loginResult = new LoginResult(sysUser, sessionId, token, roleTypes.size() > 0 ? roleTypes : roleNamesSet, appSource, SystemConstant.VERSION_VALUE);
        // 添加档案信息
        if (UserSourceEnum.ARCHIVES.equals(sysUser.getSource())) {
            TBUserArchives tbUserArchives = tbUserArchivesService.findByUserId(sysUser.getId());
            loginResult.setUserArchivesCode(tbUserArchives.getCode());
            loginResult.setMobileNumber(tbUserArchives.getMobileNumber());
        }

        loginResult.setOrgInfo(Objects.nonNull(authBean.getOrg()) ? loginResult.new OrgNativeBean(authBean.getOrg()) : null);
        return loginResult;
    }

    /**
     * 删除用户信息
     *
     * @param userId
     * @param all
     */
    @Override
    public Boolean removeUserInfo(Long userId, boolean all) throws NoSuchAlgorithmException {
        AuthBean authBean = commonCacheService.userAuthCache(userId);
        Optional.ofNullable(authBean).orElseThrow(ExceptionResultEnum.NOT_LOGIN::exception);
        if (all) {
            for (Platform p : Platform.values()) {
                Set<String> roleNamesSet = authBean.getRoleList().stream().map(s -> s.getName()).collect(Collectors.toSet());
                List<String> roleNames = new ArrayList<>(roleNamesSet);
                Collections.sort(roleNames);
                String sessionId = SessionUtil.digest(userId, Math.abs(roleNames.toString().hashCode()), p.name());
                tbSessionService.removeById(sessionId);
                commonCacheService.deleteUserSession(sessionId);
            }
        } else {
            Set<String> roleNamesSet = authBean.getRoleList().stream().map(s -> s.getName()).collect(Collectors.toSet());
            List<String> roleNames = new ArrayList<>(roleNamesSet);
            Collections.sort(roleNames);
            String sessionId = SessionUtil.digest(userId, Math.abs(roleNames.toString().hashCode()), Platform.WEB.name());
            tbSessionService.removeById(sessionId);
            commonCacheService.deleteUserSession(sessionId);
        }
        commonCacheService.removeUserCache(userId);
        commonCacheService.removeUserAuthCache(userId);
        commonCacheService.removeUserMenuCache(userId);
        commonCacheService.removeUserRolePrivilegeCache(userId);
        return true;
    }

    /**
     * 批量删除用户信息
     *
     * @param userIds
     * @param all
     */
    @Override
    public void removeUserInfoBatch(List<Long> userIds, boolean all) {
        if (!CollectionUtils.isEmpty(userIds)) {
            new Thread(() -> {
                if (all) {
                    Set<String> sessionIdSet = new HashSet<>(Platform.values().length * userIds.size());
                    int min = 0;
                    int max = SystemConstant.IN_SIZE_MAX, size = userIds.size();
                    if (max >= size) {
                        max = size;
                    }
                    while (max <= size) {
                        List<UserRoleNameResult> userRoleNameResultList = this.selectRoleNames(userIds.subList(min, max));
                        for (UserRoleNameResult userRoleNameResult : userRoleNameResultList) {
                            List<String> roleNames = Arrays.asList(userRoleNameResult.getRoleNames().split(","));
                            Collections.sort(roleNames);
                            for (Platform p : Platform.values()) {
                                String sessionId = null;
                                try {
                                    sessionId = SessionUtil.digest(userRoleNameResult.getUserId(), Math.abs(roleNames.toString().hashCode()), p.name());
                                } catch (NoSuchAlgorithmException e) {
                                    e.printStackTrace();
                                }
                                sessionIdSet.add(sessionId);
                            }
                        }
                        if (max == size) {
                            break;
                        }
                        min = max;
                        max += SystemConstant.IN_SIZE_MAX;
                        if (max >= size) {
                            max = size;
                        }
                    }
                    tbSessionService.removeByIds(sessionIdSet);
                    for (String s : sessionIdSet) {
                        commonCacheService.deleteUserSession(s);
                    }
                } else {
                    TBSession tbSession = (TBSession) ServletUtil.getRequestSession();
                    tbSessionService.removeById(tbSession.getId());
                    commonCacheService.deleteUserSession(tbSession.getId());
                }
                for (Long l : userIds) {
                    commonCacheService.removeUserCache(l);
                    commonCacheService.removeUserAuthCache(l);
                    commonCacheService.removeUserMenuCache(l);
                    commonCacheService.removeUserRolePrivilegeCache(l);
                }
            }).start();
        }
    }

    /**
     * 根据机构id查询用户
     *
     * @param orgId
     * @return
     */
    @Override
    public List<SysUserResult> findSysUserResultList(Long orgId) {
        return this.baseMapper.findSysUserResultList(orgId);
    }


    /**
     * 强行过期用户手机号验证码（过期时间改为验证码发送时间）
     *
     * @param userId       用户id
     * @param mobileNumber 用户手机号
     */
    @Override
    @Transactional
    public void expiredVerifyCode(Long userId, String mobileNumber) {
        SysConfig sysConfig = commonCacheService.addSysConfigCache(SystemConstant.SYS_CODE_ENABLE);
        Optional.ofNullable(sysConfig).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("未启用短信验证码"));
        Boolean enable = Boolean.valueOf(sysConfig.getConfigValue());
        if (enable) {
            int count = this.baseMapper.updateVerifyCodeExpiredTime(userId, mobileNumber);
            if (count != 1) {
                throw ExceptionResultEnum.ERROR.exception("验证码过期失败");
            }
        }
    }

    /**
     * 校验短信验证码
     *
     * @param userId       用户id
     * @param mobileNumber 用户手机号
     * @param code         验证码
     */
    @Override
    public void checkSmsCode(Long userId, String mobileNumber, String code) {
        SysConfig sysConfig = commonCacheService.addSysConfigCache(SystemConstant.SYS_CODE_ENABLE);
        Optional.ofNullable(sysConfig).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("未启用短信验证码"));
        Boolean enable = Boolean.valueOf(sysConfig.getConfigValue());
        if (enable) {
            SysConfig sysConfigNormal = commonCacheService.addSysConfigCache(SystemConstant.SMS_NORMAL_CODE);
            Optional.ofNullable(sysConfigNormal).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("未配置万能短信验证码"));
            if (!Objects.equals(sysConfigNormal.getConfigValue(), code)) {
                List<VerifyCodeCheckDto> verifyCodeCheckDtoList = this.baseMapper.findVerifyCodeByUser(userId, mobileNumber);
                if (verifyCodeCheckDtoList.size() < 1) {
                    throw ExceptionResultEnum.ERROR.exception("验证码错误");
                }
                VerifyCodeCheckDto accessControl = verifyCodeCheckDtoList.get(0);
                if (Objects.isNull(accessControl) || !Objects.equals(accessControl.getVerifyCode(), code)) {
                    throw ExceptionResultEnum.ERROR.exception("验证码错误");
                }

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

    /**
     * 查询用户
     *
     * @param iPage
     * @param userInfo
     * @param orgId
     * @param roleId
     * @param enable
     * @return
     */
    @Override
    public IPage<UserDto> query(IPage<Map> iPage, String userInfo, Long orgId, Long roleId, Boolean enable) {
        IPage<UserDto> userDtoIPage = this.baseMapper.query(iPage, userInfo, orgId, roleId, enable);
        if (Objects.nonNull(userDtoIPage) && !CollectionUtils.isEmpty(userDtoIPage.getRecords())) {
            userDtoIPage.getRecords().forEach(m -> {
                //角色
                m.setRoles(sysRoleService.listRolesByUserId(Long.valueOf(m.getId())));
            });
        }
        return userDtoIPage;
    }

    /**
     * 根据用户来源查找用户并返回动态表单数据
     *
     * @param userSourceEnum
     * @return
     */
    @Override
    public List<FormWidgetDto> queryUser(UserSourceEnum userSourceEnum) {
        return this.baseMapper.queryUser(Objects.nonNull(userSourceEnum) ? userSourceEnum.name() : null, Objects.nonNull(userSourceEnum) ? userSourceEnum.getRoleIdList() : null);
    }

    /**
     * 新增/修改用户
     *
     * @param sysUser
     * @param requestUser
     * @return
     */
    @Override
    @Transactional
    public Boolean saveUser(SysUser sysUser, SysUser requestUser) {
        SysUserService sysUserService = SpringContextHolder.getBean(SysUserService.class);
        try {
            requestUser = Objects.isNull(requestUser) ? (SysUser) ServletUtil.getRequestUser() : requestUser;
            if (Objects.isNull(sysUser.getId())) {//新增用户
                sysUser.insertInfo(requestUser.getId());
                sysUser.setPasswordInfo(sysUser.getMobileNumber());
                sysUser.setRtzfSyncStatus(RtzfSyncStatusEnum.NEED_SYNC);
                sysUserService.save(sysUser);
                sysUserRoleService.addUserRolePrivilege(sysUser, sysUser.getRoleIds());
            } else {//修改用户
                SysUser dbUser = this.getById(sysUser.getId());
                Optional.ofNullable(dbUser).orElseThrow(ExceptionResultEnum.USER_NO_EXISTS::exception);
                List<SysUserRole> sysUserRoleList = commonCacheService.userRolePrivilegeCache(sysUser.getId());
                List<Long> userRolesList = Arrays.asList(sysUser.getRoleIds());
                Set<Long> dbUserRolesList = sysUserRoleList.stream().map(SysUserRole::getRoleId).collect(Collectors.toSet());
                int count = (int) dbUserRolesList.stream().filter(s -> !userRolesList.contains(s)).count();
                UpdateWrapper<SysUser> userUpdateWrapper = new UpdateWrapper<>();
                userUpdateWrapper.lambda()
                        .eq(SysUser::getId, sysUser.getId())
                        .set(SysUser::getLoginName, sysUser.getLoginName())
                        .set(SysUser::getRealName, sysUser.getRealName())
                        .set(SysUser::getCode, sysUser.getCode())
                        .set(SysUser::getMobileNumber, sysUser.getMobileNumber())
                        .set(SysUser::getGender, sysUser.getGender())
                        .set(SysUser::getOrgId, sysUser.getOrgId())
                        .set(SysUser::getUpdateId, requestUser.getId())
                        .set(SysUser::getUpdateTime, System.currentTimeMillis());

                RtzfSyncStatusEnum rtzfSyncStatus = dbUser.getRtzfSyncStatus();
                if (RtzfSyncStatusEnum.ALREADY_SYNC.equals(rtzfSyncStatus)) {
                    dbUser.setRtzfSyncStatus(RtzfSyncStatusEnum.NEED_UPDATE);
                    userUpdateWrapper.lambda().set(SysUser::getRtzfSyncStatus, RtzfSyncStatusEnum.NEED_UPDATE);
                }

                sysUserService.update(userUpdateWrapper);
                //如果修改了角色，需要重新登录
                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());
                    sysUserRoleService.addUserRolePrivilege(sysUser, sysUser.getRoleIds());
                    sysUserService.removeUserInfo(sysUser.getId(), true);
                } else if (Objects.nonNull(dbUser.getOrgId()) && !dbUser.getOrgId().equals(sysUser.getOrgId())) {
                    sysUserService.removeUserInfo(sysUser.getId(), true);
                }
                //如果修改了机构或手机号，需更新用户缓存
                if (Objects.nonNull(dbUser.getOrgId()) && (dbUser.getOrgId().longValue() != sysUser.getOrgId().longValue()
                        || !Objects.equals(dbUser.getMobileNumber(), sysUser.getMobileNumber()))) {
                    commonCacheService.updateUserCache(sysUser.getId());
                    commonCacheService.updateUserAuthCache(sysUser.getId());
                }
                //修改登录名需重新登录
                if (Objects.nonNull(dbUser.getLoginName()) && Objects.nonNull(sysUser.getLoginName()) && !Objects.equals(dbUser.getLoginName(), sysUser.getLoginName())) {
                    sysUserService.removeUserInfo(sysUser.getId(), true);
                }
            }
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
            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, ((ApiException) e).getCode(), e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        }
        return true;
    }

    /**
     * 启用/禁用用户
     *
     * @param sysUser
     * @return
     */
    @Override
    @Transactional
    public Boolean enable(SysUser sysUser) throws NoSuchAlgorithmException {
        Optional.ofNullable(sysUser).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("参数不能为空"));
        Optional.ofNullable(sysUser.getId()).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("id不能为空"));
        Optional.ofNullable(sysUser.getEnable()).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("启用/禁用不能为空"));

        SysUser sysUserDb = this.getById(sysUser.getId());
        Optional.ofNullable(sysUserDb).orElseThrow(ExceptionResultEnum.USER_NO_EXISTS::exception);

        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        UpdateWrapper<SysUser> userUpdateWrapper = new UpdateWrapper<>();
        userUpdateWrapper.lambda().set(SysUser::getEnable, sysUser.getEnable())
                .eq(SysUser::getId, sysUser.getId())
                .set(SysUser::getUpdateId, requestUser.getId())
                .set(SysUser::getUpdateTime, System.currentTimeMillis());

        RtzfSyncStatusEnum rtzfSyncStatus = sysUserDb.getRtzfSyncStatus();
        if (RtzfSyncStatusEnum.ALREADY_SYNC.equals(rtzfSyncStatus)) {
            userUpdateWrapper.lambda().set(SysUser::getRtzfSyncStatus, RtzfSyncStatusEnum.NEED_UPDATE);
        }
        boolean success = this.update(userUpdateWrapper);

        if (success) {
            commonCacheService.updateUserCache(sysUser.getId());
            //如果状态为禁用，需要踢下线重新登录
            if (!sysUser.getEnable()) {
                this.removeUserInfo(sysUser.getId(), true);
            }
        }
        return success;
    }

    @Override
    public List<SysUser> listEnable() {
        return this.list(new QueryWrapper<SysUser>().lambda().eq(SysUser::getEnable, true));
    }

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

    /**
     * 修改用户密码
     *
     * @param sysUser
     * @return
     * @throws NoSuchAlgorithmException
     */
    @Override
    @Transactional
    public Boolean updatePassword(SysUser sysUser) throws NoSuchAlgorithmException {
        Optional.ofNullable(sysUser).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("参数不能为空"));
        Optional.ofNullable(sysUser.getId()).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("id不能为空"));
        Optional.ofNullable(sysUser.getNewPassword()).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("新密码不能为空"));

        SysUser sysUserDb = this.getById(sysUser.getId());
        Optional.ofNullable(sysUserDb).orElseThrow(ExceptionResultEnum.USER_NO_EXISTS::exception);

        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        UpdateWrapper<SysUser> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().set(SysUser::getPassword, sysUser.getNewPassword())
                .eq(SysUser::getId, sysUser.getId())
                .set(SysUser::getUpdateId, requestUser.getId())
                .set(SysUser::getUpdateTime, System.currentTimeMillis());

        RtzfSyncStatusEnum rtzfSyncStatus = sysUserDb.getRtzfSyncStatus();
        if (RtzfSyncStatusEnum.ALREADY_SYNC.equals(rtzfSyncStatus)) {
            updateWrapper.lambda().set(SysUser::getRtzfSyncStatus, RtzfSyncStatusEnum.NEED_UPDATE);
        }

        boolean success = this.update(updateWrapper);
        if (success) {
            commonCacheService.updateUserCache(sysUser.getId());
            //修改密码后，需要踢下线重新登录
            this.removeUserInfo(sysUser.getId(), true);
        }
        return success;
    }

    /**
     * 初始化用户密码
     *
     * @param sysUser
     * @return
     * @throws NoSuchAlgorithmException
     */
    @Override
    @Transactional
    public Boolean initPassword(SysUser sysUser) throws NoSuchAlgorithmException {
        Optional.ofNullable(sysUser).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("参数不能为空"));
        Optional.ofNullable(sysUser.getId()).orElseThrow(() -> ExceptionResultEnum.ERROR.exception("id不能为空"));

        SysUser sysUserDb = this.getById(sysUser.getId());
        RtzfSyncStatusEnum rtzfSyncStatus = sysUserDb.getRtzfSyncStatus();
        if (RtzfSyncStatusEnum.ALREADY_SYNC.equals(rtzfSyncStatus)) {
            sysUserDb.setRtzfSyncStatus(RtzfSyncStatusEnum.NEED_UPDATE);
        }
        Optional.ofNullable(sysUserDb).orElseThrow(() -> ExceptionResultEnum.USER_NO_EXISTS.exception());

        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        sysUserDb.setPasswordInfo(sysUserDb.getMobileNumber());
        sysUserDb.updateInfo(requestUser.getId());
        boolean success = this.saveOrUpdate(sysUserDb);
        if (success) {
            commonCacheService.updateUserCache(sysUser.getId());
            //修改密码后，需要踢下线重新登录
            this.removeUserInfo(sysUser.getId(), true);
        }
        return success;
    }

    /**
     * 获取工作台待办
     *
     * @param iPage
     * @param userId
     * @param type
     * @param serviceId
     * @param customName
     * @param flowTaskTypeEnum
     * @param crmNo
     * @return
     */
    @Override
    public IPage<WorkTaskResult> getFlowTaskList(IPage<Map> iPage, Long userId, TFCustomTypeEnum type, Long serviceId, String customName, FlowTaskTypeEnum flowTaskTypeEnum, String crmNo) {
        return this.baseMapper.getFlowTaskList(iPage, userId, Objects.nonNull(type) ? type.name() : null, serviceId, customName, Objects.nonNull(flowTaskTypeEnum) ? flowTaskTypeEnum.name() : null, crmNo);
    }

    /**
     * 获取用户待办计数
     *
     * @param userId
     * @param type
     * @param serviceId
     * @param customName
     * @param flowTaskTypeEnum
     * @param crmNo
     * @return
     */
    @Override
    public int getFlowTaskListCount(Long userId, TFCustomTypeEnum type, Long serviceId, String customName, FlowTaskTypeEnum flowTaskTypeEnum, String crmNo) {
        return this.baseMapper.getFlowTaskListCount(userId, Objects.nonNull(type) ? type.name() : null, serviceId, customName, Objects.nonNull(flowTaskTypeEnum) ? flowTaskTypeEnum.name() : null, crmNo);
    }

    @Override
    public List<SysUserBriefResult> findUserListByRoleType(RoleTypeEnum roleType) {
        return this.baseMapper.findByRoleType(roleType);
    }

    @Override
    public DataPermissionDto buildUserDataPermission(Long userId) {
        if (userId == null || userId == 0) {
            throw ExceptionResultEnum.ERROR.exception("无法获取当前登录人id");
        }
        SysUser sysUser = this.getById(userId);
        if (Objects.isNull(sysUser)) {
            throw ExceptionResultEnum.ERROR.exception("缺少用户信息");
        }

        List<SysRole> sysRoleList = sysUserRoleService.listRoleByUserId(userId);
        List<RoleTypeEnum> roleTypeList = sysRoleList.stream().map(SysRole::getType).distinct().collect(Collectors.toList());
        DataPermissionDto dto = new DataPermissionDto();
        dto.setRequestUserId(userId);
        dto.setHasAdmin(roleTypeList.contains(RoleTypeEnum.ADMIN));
        dto.setHasPmo(roleTypeList.contains(RoleTypeEnum.PMO));
        dto.setHasBusiness(roleTypeList.contains(RoleTypeEnum.BUSSINESS));
        dto.setHasRegionManager(roleTypeList.contains(RoleTypeEnum.REGION_MANAGER));
        dto.setHasRegionCoordinator(roleTypeList.contains(RoleTypeEnum.REGION_COORDINATOR));
        dto.setHasEffectEngineer(roleTypeList.contains(RoleTypeEnum.EFFECT_ENGINEER));
        dto.setHasAssistantEngineer(roleTypeList.contains(RoleTypeEnum.ASSISTANT_ENGINEER));
        dto.setHasQA(roleTypeList.contains(RoleTypeEnum.QA));
        dto.setHasCustom(roleTypeList.contains(RoleTypeEnum.CUSTOM));
        dto.setHasAccountManager(roleTypeList.contains(RoleTypeEnum.ACCOUNT_MANAGER));
        dto.setHasThirdPmo(roleTypeList.contains(RoleTypeEnum.THIRD_PMO));
        dto.setHasDeviceDelivery(roleTypeList.contains(RoleTypeEnum.DEVICE_DELIVERY));
        if (dto.getHasThirdPmo() || dto.getHasDeviceDelivery()) {
            Long supplierId = sysUser.getSupplierId();
            if (supplierId == null || supplierId == 0) {
                throw ExceptionResultEnum.ERROR.exception(
                        String.format("包含[%s]或[%s]角色的用户,请先联系管理员在用户管理中绑定该用户所管辖的供应商.", RoleTypeEnum.THIRD_PMO.getDesc(),
                                RoleTypeEnum.DEVICE_DELIVERY.getDesc()));
            }
            dto.setSupplierId(supplierId);
        }
        return dto;
    }

    /**
     * 根据用户id查找用户名(机构)
     *
     * @param userIds
     * @return
     */
    @Override
    public List<OrgUserNameDto> findOrgUserName(List<Long> userIds) {
        return this.baseMapper.findOrgUserName(userIds);
    }

    @Override
    public String findUserCompanyName(Long userId) {
        String companyName = "";
        SysUser sysUser = this.getById(userId);
        UserSourceEnum userSource = sysUser.getSource();
        switch (userSource) {
            case SYSTEM:
                companyName = "启明泰和";
                break;
            case ARCHIVES:
                UserArchivesResult userArchivesResult = tbUserArchivesService.findUserArchivesByArchivesIdORUserId(null, userId);
                if (Objects.nonNull(userArchivesResult)) {
                    companyName = userArchivesResult.getSupplierName();
                }
                break;
        }
        return companyName;
    }

    @Transactional
    @Override
    public RtzfResult rtzfUpdateUser(SysUser requestUser, SysUser willUpdateUser) {
        Long id = willUpdateUser.getId();
        RtzfUserInfo rtzfUserInfo = new RtzfUserInfo();
        rtzfUserInfo.setUserName(String.valueOf(id));
        rtzfUserInfo.setRealName(willUpdateUser.getRealName());

        String companyName = this.findUserCompanyName(id);
        if (companyName != null && companyName.length() > 0) {
            rtzfUserInfo.setCompanyName(companyName);
        }
        rtzfUserInfo.setPhoneNo(willUpdateUser.getMobileNumber());
        // TODO: 2023/11/27 密码要解密再加密
        String password = willUpdateUser.getPassword();
        rtzfUserInfo.setPassword(password);
        rtzfUserInfo.setVerifyPassword(password);
        GenderEnum gender = willUpdateUser.getGender();
        rtzfUserInfo.setSex(GenderEnum.MAN.equals(gender) ? 1 : 0);
        rtzfUserInfo.setWorkNo(String.valueOf(id));
        rtzfUserInfo.setState(0);

        // 0 为启用，1 为禁用
        Boolean enable = willUpdateUser.getEnable();
        rtzfUserInfo.setWorkState(enable ? 0 : 1);
        List<Long> roleIdList = sysRoleService.listRolesByUserId(id)
                .stream()
                .map(RoleDto::getId)
                .collect(Collectors.toList());
        if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(roleIdList)) {
            rtzfUserInfo.setRoleIds(roleIdList);
        }
        RtzfResult rtzfResult = rtzfApiUtils.updateUser(requestUser, rtzfUserInfo);
        if (Objects.nonNull(rtzfResult) && "0".equals(rtzfResult.getCode())) {
            willUpdateUser.setRtzfSyncStatus(RtzfSyncStatusEnum.ALREADY_SYNC);
            this.updateById(willUpdateUser);
        }
        return rtzfResult;
    }
}
