package com.sckw.auth.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.sckw.auth.model.vo.req.*;
import com.sckw.auth.model.vo.res.DeptInfoResVo;
import com.sckw.auth.model.vo.res.EntInfoResVo;
import com.sckw.auth.model.vo.res.LoginResVo;
import com.sckw.auth.model.vo.res.LoginResVo1;
import com.sckw.auth.util.AsyncFactory;
import com.sckw.core.common.enums.enums.DictEnum;
import com.sckw.core.model.enums.ClientTypeEnum;
import com.sckw.core.model.enums.LoginMethodEnum;
import com.sckw.core.model.enums.SystemTypeEnum;
import com.sckw.core.utils.*;
import com.sckw.core.web.context.LoginUserHolder;
import com.sckw.core.web.model.EntCertificateInfo;
import com.sckw.core.web.model.LoginEntInfo;
import com.sckw.core.web.model.LoginUserInfo;
import com.sckw.core.web.response.HttpResult;
import com.sckw.fleet.api.RemoteFleetService;
import com.sckw.fleet.api.model.vo.RDriverDetailVo;
import com.sckw.redis.constant.RedisConstant;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.model.dto.req.*;
import com.sckw.system.api.model.dto.res.KwsRoleResDto;
import com.sckw.core.exception.SystemException;
import com.sckw.core.model.constant.Global;
import com.sckw.core.web.constant.HttpStatus;
import com.sckw.redis.utils.RedissonUtils;
import com.sckw.system.api.model.dto.res.*;
import com.sckw.auth.service.IAuthService;
import com.sckw.system.api.RemoteUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @desc: 用户权限实现类
 * @author: czh
 * @date: 2023/6/19
 */
@Slf4j
@Service
public class AuthServiceImpl implements IAuthService {

    @DubboReference(version = "1.0.0", group = "design", check = false)
    private RemoteUserService remoteUserService;

    @DubboReference(version = "1.0.0", group = "design", check = false)
    private RemoteSystemService systemService;

    @DubboReference(version = "1.0.0", group = "design", check = false)
    private RemoteFleetService fleetService;

    @Override
    public LoginResVo login(LoginReqVo reqDto) {
//        /*1、根据账号密码或者手机号校验码登录, 手机号后面处理*/
//        KwsUserResDto kwsUser = checkLogin(reqDto);
//        LoginResVo loginResVo = new LoginResVo();
//        loginResVo.setClientType(reqDto.getClientType());
//        BeanUtils.copyProperties(kwsUser, loginResVo);
//
//        //平台管理员直接过了
//        if (kwsUser.getIsMain() == Global.YES && kwsUser.getSystemType().equals(SystemTypeEnum.MANAGE.getCode())) {
//            afterProcessor(loginResVo);
//            return loginResVo;
//        }
//        /*2、登录成功，查询角色信息*/
//        Long userId = kwsUser.getId();
//        List<KwsRoleResDto> kwsRoleResDtos = remoteUserService.queryRoleInfoByUserId(userId);
//        loginResVo.setRoleInfo(kwsRoleResDtos);
//
//
//        /*3、查询用户机构*/
//        List<KwsUserDeptResDto> kwsUserDeptResDtos = remoteUserService.queryUserDeptByUserId(userId);
//        if (CollectionUtils.isEmpty(kwsUserDeptResDtos)) {
//            throw new SystemException(HttpStatus.QUERY_FAIL_CODE, HttpStatus.USER_DEPT_NOT_EXISTS);
//        }
//
//        List<Long> deptIds = kwsUserDeptResDtos.stream().map(KwsUserDeptResDto::getDeptId).toList();
//        List<KwsDeptResDto> kwsDepts = remoteUserService.queryDeptByIds(deptIds);
//        if (CollectionUtils.isEmpty(kwsDepts)) {
//            //数据不全，直接返回
//            afterProcessor(loginResVo);
//            return loginResVo;
//        }
//
//        /*3、查企业*/
//        //目前一个人只能归属于一个企业，所以这里取第一个就行
//        Long entId = kwsDepts.get(0).getEntId();
//        KwsEnterpriseResDto kwsEnterpriseResDto = remoteUserService.queryEnterpriseById(entId);
//        if (Objects.isNull(kwsEnterpriseResDto)) {
//            //只要查出了机构，这个if其实不会进的，做保险起见还是加上判空
//            afterProcessor(loginResVo);
//            return loginResVo;
//        }
//
//        EntInfoResVo entInfoResVo = new EntInfoResVo();
//        BeanUtils.copyProperties(kwsEnterpriseResDto, entInfoResVo);
//        entInfoResVo.setDeptInfo(BeanUtils.copyToList(kwsDepts, DeptInfoResVo.class));
//
//        //查企业类型
//        List<EntTypeResDto> entTypeResDtos = remoteUserService.queryEntTypeById(entId);
//        if (CollectionUtils.isNotEmpty(entTypeResDtos)) {
//            entInfoResVo.setEntTypes(String.join(Global.COMMA, entTypeResDtos.stream().map(EntTypeResDto::getType).map(String::valueOf).distinct().toList()));
//        }
//        loginResVo.setEntInfo(entInfoResVo);
//
//        /* 4、查资质*/
//        List<EntCertificateResDto> entCertificateResDtoList = remoteUserService.queryCertificateByEntId(entId);
//        entInfoResVo.setCertificateInfo(entCertificateResDtoList);
//
//        //企业资质有效性判断  1、当前资质没过期，且状态是已认证  2、只要有认证过一次就算有效  参数判断
//        String checkType = String.valueOf(Global.NUMERICAL_TWO);
//        if (checkType.equals(Global.NUMERICAL_ONE)) {
//            for (EntCertificateResDto entCertificateResDto : entCertificateResDtoList) {
//                Date expireTime = entCertificateResDto.getExpireTime();
//                entInfoResVo.setValid(DateUtil.compare(new Date(), expireTime) <= 0);
//            }
//        } else {
//            List<EntCheckTrackResDto> entCheckTrackResDtoList = remoteUserService.checkTrackByEntId(entId);
//            if (CollectionUtils.isEmpty(entCheckTrackResDtoList)) {
//                entInfoResVo.setValid(false);
//                afterProcessor(loginResVo);
//                return loginResVo;
//            }
//            entInfoResVo.setValid(entCheckTrackResDtoList.stream().anyMatch(item -> item.getStatus() == Global.NO));
//        }
//
//        /*5、生成token，一些信息存redis*/
//        afterProcessor(loginResVo);
//        return loginResVo;
        return null;
    }

    private KwsUserResDto checkLogin(LoginReqVo reqDto) {
        List<KwsUserResDto> kwsUsers = remoteUserService.checkUserBase(reqDto.getAccount(), reqDto.getSystemType());
        KwsUserResDto kwsUser = kwsUsers.get(0);
        //密码校验、验证码
        if (StringUtils.isNotBlank(reqDto.getPassword())) {
            remoteUserService.checkPassword(reqDto.getPassword(), kwsUser.getPassword());
        } else {
            String key = Global.USER_LOGIN_CAPTCHA + reqDto.getSystemType() + Global.COLON + kwsUser.getAccount();
//            String captcha = RedissonUtils.getString(key);
//            if (StringUtils.isBlank(captcha) || StringUtils.isBlank(reqDto.getCaptcha()) || !reqDto.getCaptcha().equals(captcha)) {
//                throw new SystemException(HttpStatus.PARAMETERS_MISSING_CODE, HttpStatus.CAPCHA_ERROR);
//            }
//            RedissonUtils.delete(key);
        }
        return kwsUser;
    }

    /**
     * @param loginResVo 登录的返参
     * @desc: 生成token，存redis
     * @author: czh
     * @date: 2023/6/12
     */
    private void afterProcessor(LoginResVo loginResVo) {
        try {
            //设置token
            loginResVo.setToken(EncryUtil.encry(Global.PRI_KEY, String.valueOf(loginResVo.getId())));

            //异步存redis
            AsyncFactory.execute(new AsyncProcess(loginResVo, remoteUserService));
        } catch (Exception e) {
            throw new SystemException(HttpStatus.GLOBAL_EXCEPTION_CODE, HttpStatus.GLOBAL_EXCEPTION_MESSAGE);
        }
    }

    @Override
    @Transactional(rollbackFor = {})
    public void register(RegisterReqVo reqVo) {
        /*校验验证码*/
        String key = StringUtils.format(RedisConstant.MESSAGE_SMS_VERIFY_CODE_VALUE_KEY, DictEnum.SMS_REGISTER.getValue(), reqVo.getPhone());
        String sms = RedissonUtils.getString(key);
        if (!reqVo.getCaptcha().equals(sms)) {
            throw new SystemException(HttpStatus.CODE_10301, HttpStatus.CAPTCHA_ERROR);
        }
        RegisterReqDto registerReqDto = new RegisterReqDto();
        BeanUtils.copyProperties(reqVo, registerReqDto);
        remoteUserService.register(registerReqDto);
        RedissonUtils.delete(key);
    }


    @Override
    public void forgetPassword(ForgetPasswordReqVo reqDto) {
        ForgetPasswordReqDto forgetPasswordReqDto = new ForgetPasswordReqDto();
        BeanUtils.copyProperties(reqDto, forgetPasswordReqDto);
        remoteUserService.forgetPassword(forgetPasswordReqDto);
    }

    @Override
    public void resetPassword(Long id) {
        remoteUserService.resetPassword(id);
    }

    static class AsyncProcess implements Runnable {

        private final LoginResVo loginResVo;

        private final RemoteUserService remoteUserService;

        public AsyncProcess(LoginResVo loginResVo, RemoteUserService remoteUserService) {
            this.loginResVo = loginResVo;
            this.remoteUserService = remoteUserService;
        }

        @Override
        public void run() {
            //存基础信息
            SaveBaseToCache(loginResVo);

            //存菜单权限
            SaveToCache(loginResVo);

            //存登录记录信息
            SaveLoginInfo(loginResVo);
        }


        /**
         * @param loginResVo 返参
         * @desc: 存基础信息
         * @author: czh
         * @date: 2023/6/28
         */
        private void SaveBaseToCache(LoginResVo loginResVo) {
            //存用户登录信息
            saveUserLoginInfo();

            EntInfoResVo entInfo = loginResVo.getEntInfo();
            if (Objects.isNull(entInfo)) {
                return;
            }
            //单独存用户企业
//            RedissonUtils.putString(Global.getFullUserEntKey(loginResVo.getSystemType(), loginResVo.getId()), JSON.toJSONString(entInfo), Global.PC_TOKEN_EXPIRE);

            //存企业信息
            saveEntLoginInfo(entInfo);
        }

        /**
         * @param entInfo 企业信息
         * @desc: 存企业信息
         * @author: czh
         * @date: 2023/7/3
         */
        private void saveEntLoginInfo(EntInfoResVo entInfo) {
            LoginEntInfo loginEntInfo = new LoginEntInfo();
            BeanUtils.copyProperties(entInfo, loginEntInfo);
            loginEntInfo.setCertificateInfo(BeanUtils.copyToList(entInfo.getCertificateInfo(), EntCertificateInfo.class));
            RedissonUtils.putString(Global.REDIS_ENTERPRISE_PREFIX + entInfo.getId(), JSON.toJSONString(loginEntInfo), Global.PC_TOKEN_EXPIRE);
        }

        /**
         * @desc: 存用户登录信息
         * @author: czh
         * @date: 2023/6/29
         */
        private void saveUserLoginInfo() {
            //存用户登录信息
            LoginUserInfo loginUserInfo = new LoginUserInfo();
            loginUserInfo.setId(loginResVo.getId());
            loginUserInfo.setSystemType(loginResVo.getSystemType());
            loginUserInfo.setAccount(loginResVo.getAccount());
            loginUserInfo.setUserName(loginResVo.getName());
            loginUserInfo.setPhone(loginResVo.getPhone());
            loginUserInfo.setIsMain(loginResVo.getIsMain());
            loginUserInfo.setStatus(loginResVo.getStatus());
            loginUserInfo.setClientType(loginResVo.getClientType());
            EntInfoResVo entInfo = loginResVo.getEntInfo();
            if (!Objects.isNull(entInfo)) {
                loginUserInfo.setEntId(entInfo.getId());
                loginUserInfo.setEntName(entInfo.getFirmName());
                List<DeptInfoResVo> deptInfo = entInfo.getDeptInfo();
                if (!CollectionUtils.isEmpty(deptInfo)) {
                    loginUserInfo.setDeptIds(String.join(",", deptInfo.stream().map(item -> String.valueOf(item.getId())).toList()));
                }
            }
            RedissonUtils.putString(Global.getFullUserLoginKey(loginResVo.getSystemType(), loginResVo.getId(), loginResVo.getClientType()), JSON.toJSONString(loginUserInfo), Global.PC_TOKEN_EXPIRE);

        }

        /**
         * @param loginResVo 登录返参
         * @desc: 存缓存
         * @author: czh
         * @date: 2023/6/28
         */
        private void SaveToCache(LoginResVo loginResVo) {
            //存权限菜单
            long id = loginResVo.getId();
            List<UserAccessMenuInfoResDto> userAccessMenuInfo = remoteUserService.queryUserAccessMenu(id);
            if (CollectionUtils.isEmpty(userAccessMenuInfo)) {
                RedissonUtils.delete(Global.REDIS_SYS_MENU_PREFIX + loginResVo.getClientType() + Global.COLON + id);
                log.error("未查询到用户{}的菜单权限", id);
                return;
            }

            List<String> menus = new ArrayList<>();
            for (UserAccessMenuInfoResDto userAccessMenuInfoResDto : userAccessMenuInfo) {
                String links = userAccessMenuInfoResDto.getLinks();
                if (StringUtils.isNotBlank(links)) {
                    menus.addAll(Arrays.asList(userAccessMenuInfoResDto.getLinks().split(",")));
                }
            }
            RedissonUtils.putSet(Global.REDIS_SYS_MENU_PREFIX + loginResVo.getClientType() + Global.COLON + id, menus);
        }

        /**
         * @param loginResVo 登录返参
         * @desc: 存登录记录信息
         * @author: czh
         * @date: 2023/6/28
         */
        private void SaveLoginInfo(LoginResVo loginResVo) {
            long userId = loginResVo.getId();
            UserLoginReqDto currentDayLogin = remoteUserService.currentDayLogin(userId);
            UserLoginReqDto userLoginReqDto = new UserLoginReqDto();
            userLoginReqDto.setPid(Objects.isNull(currentDayLogin) ? "" : String.valueOf(currentDayLogin.getId()));
            userLoginReqDto.setIp("");
            userLoginReqDto.setUserAgent("");
            userLoginReqDto.setUserId(loginResVo.getId());
            userLoginReqDto.setToken(loginResVo.getToken());
            userLoginReqDto.setValidTime("");
            userLoginReqDto.setFirst(Objects.isNull(currentDayLogin) ? Global.YES : Global.NO);
            userLoginReqDto.setLock(Global.NO);
            userLoginReqDto.setType(Global.NO);
            userLoginReqDto.setSource(loginResVo.getClientType());
            remoteUserService.saveUserLogin(userLoginReqDto);
        }

    }

    /**-------------------------------------------------------------------------------------------------------------->**/
    /**
     * @param loginBase {}
     * @desc 司机账号登陆
     * @author zk
     * @date 2023/7/26
     **/
    @Override
    public HttpResult driverAuth(LoginBase loginBase) {
        /**查询用户信息**/
        RDriverDetailVo driver = fleetService.findDriverDetai(loginBase.getAccount());
        /**信息校验**/
        if (driver == null) {
            return HttpResult.error(HttpStatus.QUERY_FAIL_CODE, "账号不存在，请检查并重新输入！");
        }
        if (loginBase.getLoginMethod() == LoginMethodEnum.ORDINARY.getValue()
                && !PasswordUtils.validatePassword(loginBase.getPassword(), driver.getPassword())) {
            return HttpResult.error(HttpStatus.CODE_10301, "密码不正确，请检查并重新输入！");
        }
        if (driver.getStatus() == Global.YES) {
            return HttpResult.error(HttpStatus.CODE_10301, "您的账号已冻结，如需帮助，请致电平台客服！");
        }
        //企业信息
        EntCacheResDto enterprise = systemService.queryEntDetails(driver.getEntId());

        /**生成token**/
        String token = generateToken(loginBase, driver.getId());
        if (StringUtils.isBlank(token)) {
            return HttpResult.error(HttpStatus.CODE_10301, "生成密钥失败，请联系系统管理员！");
        }

        /**缓存信息**/
        AsyncFactory.execute(new AsyncProcess1(loginBase, null, driver, enterprise, remoteUserService));

        /**数据组装**/
        LoginResVo1 loginRes = new LoginResVo1();
        loginRes.setId(driver.getId());
        loginRes.setName(driver.getName());
        loginRes.setAccount(loginBase.getAccount());
        loginRes.setPhone(driver.getPhone());
        loginRes.setStatus(driver.getStatus());
        loginRes.setEntId(driver.getEntId());
        loginRes.setFirmName(enterprise != null ? enterprise.getFirmName() : null);
        loginRes.setApproval(enterprise != null ? enterprise.getApproval() : null);
        loginRes.setEntTypeNames(enterprise != null ? enterprise.getEntTypeNames() : null);
        loginRes.setClientType(loginBase.getClientType());
        loginRes.setSystemType(loginBase.getSystemType());
        loginRes.setToken(token);
        return HttpResult.ok(loginRes);
    }

    /**
     * @param loginBase {}
     * @desc 运营/企业账号登陆
     * @author zk
     * @date 2023/7/26
     **/
    @Override
    public HttpResult commonAuth(LoginBase loginBase) {
        /**查询用户信息**/
        KwsUserResDto user = systemService.queryUserDetails(loginBase.getAccount(), loginBase.getSystemType());

        /**信息校验**/
        if (user == null) {
            return HttpResult.error(HttpStatus.QUERY_FAIL_CODE, "账号不存在，请检查并重新输入！");
        }
        if (loginBase.getLoginMethod() == LoginMethodEnum.ORDINARY.getValue()
                && !PasswordUtils.validatePassword(loginBase.getPassword(), user.getPassword())) {
            return HttpResult.error(HttpStatus.CODE_10301, "密码不正确，请检查并重新输入！");
        }

        if (loginBase.getLoginMethod() == LoginMethodEnum.SMS.getValue()) {
            String key = StringUtils.format(RedisConstant.MESSAGE_SMS_VERIFY_CODE_VALUE_KEY, DictEnum.SMS_LOGIN.getValue(), loginBase.getAccount());
            String sms = RedissonUtils.getString(key);
            if (!loginBase.getCaptcha().equals(sms)) {
                throw new SystemException(HttpStatus.CODE_10301, HttpStatus.CAPTCHA_ERROR);
            }
        }

        if (user.getStatus() == Global.YES) {
            return HttpResult.error(HttpStatus.CODE_10301, "您的账号已冻结，如需帮助，请致电平台客服！");
        }

        //企业信息
        EntCacheResDto enterprise = systemService.queryEntDetails(user.getEntId());
        if (loginBase.getSystemType() == SystemTypeEnum.COMPANY.getCode() && enterprise == null) {
            return HttpResult.error(HttpStatus.QUERY_FAIL_CODE, "账号没有归属企业，请检查并重新输入！");
        }
        if (enterprise != null && enterprise.getStatus() == Global.YES) {
            return HttpResult.error(HttpStatus.QUERY_FAIL_CODE, "企业已冻结，如需帮助，请致电平台客服！");
        }

        /**生成token**/
        String token = generateToken(loginBase, user.getId());
        if (StringUtils.isBlank(token)) {
            return HttpResult.error(HttpStatus.CODE_10301, "生成密钥失败，请联系系统管理员！");
        }

        /**缓存信息**/
        AsyncFactory.execute(new AsyncProcess1(loginBase, user, null, enterprise, remoteUserService));

        /**数据组装**/
        LoginResVo1 loginRes = new LoginResVo1();
        loginRes.setId(user.getId());
        loginRes.setName(user.getName());
        loginRes.setAccount(user.getAccount());
        loginRes.setPhone(user.getPhone());
        loginRes.setPhoto(user.getPhoto());
        loginRes.setIsMain(user.getIsMain());
        loginRes.setStatus(user.getStatus());
        loginRes.setRoleName(user.getRoleName());
        loginRes.setDeptName(user.getDeptName());
        loginRes.setClientId(user.getClientId());
        loginRes.setEntId(user.getEntId());
        loginRes.setFirmName(enterprise != null ? enterprise.getFirmName() : null);
        loginRes.setApproval(enterprise != null ? enterprise.getApproval() : null);
        loginRes.setEntTypes(enterprise != null ? enterprise.getEntTypes() : null);
        loginRes.setEntTypeNames(enterprise != null ? enterprise.getEntTypeNames() : null);
        loginRes.setClientType(loginBase.getClientType());
        loginRes.setSystemType(user.getSystemType());
        loginRes.setToken(token);
        loginRes.setDeptId(user.getDeptId());
        loginRes.setRoleId(user.getRoleId());
        if (user.getSystemType().equals(SystemTypeEnum.MANAGE.getCode())) {
            loginRes.setValid(true);
        } else {
            loginRes.setValid(!Objects.isNull(enterprise) && enterprise.getValid());
        }

        return HttpResult.ok(loginRes);
    }


    /**
     * @return LoginResVo1
     * @desc: 根据token获取登录信息
     * @author: czh
     * @date: 2023/9/27
     */
    @Override
    public LoginResVo1 getLoginResByToken(String clientType, String token) {
        KwsUserResDto user = systemService.queryUserDetails(LoginUserHolder.getAccount(), LoginUserHolder.getSystemType());
        if (Objects.isNull(user)) {
            return null;
        }
        EntCacheResDto enterprise = systemService.queryEntDetails(user.getEntId());
        LoginResVo1 loginRes = new LoginResVo1();
        loginRes.setId(user.getId());
        loginRes.setName(user.getName());
        loginRes.setAccount(user.getAccount());
        loginRes.setPhone(user.getPhone());
        loginRes.setPhoto(user.getPhoto());
        loginRes.setIsMain(user.getIsMain());
        loginRes.setStatus(user.getStatus());
        loginRes.setRoleName(user.getRoleName());
        loginRes.setDeptName(user.getDeptName());
        loginRes.setClientId(user.getClientId());
        loginRes.setEntId(user.getEntId());
        loginRes.setFirmName(enterprise != null ? enterprise.getFirmName() : null);
        loginRes.setApproval(enterprise != null ? enterprise.getApproval() : null);
        loginRes.setEntTypes(enterprise != null ? enterprise.getEntTypes() : null);
        loginRes.setEntTypeNames(enterprise != null ? enterprise.getEntTypeNames() : null);
        loginRes.setSystemType(user.getSystemType());
        loginRes.setClientType(clientType);
        loginRes.setToken(token);
        loginRes.setDeptId(user.getDeptId());
        loginRes.setRoleId(user.getRoleId());
        if (user.getSystemType().equals(SystemTypeEnum.MANAGE.getCode())) {
            loginRes.setValid(true);
        } else {
            loginRes.setValid(!Objects.isNull(enterprise) && enterprise.getValid());
        }
        return loginRes;
    }

    /**
     * @param loginBase {}
     * @param userId 用户ID
     * @desc 生成token
     * @author zk
     * @date 2023/8/18
     **/
    private String generateToken(LoginBase loginBase, Long userId) {
        Map<String, Object> info = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        info.put("userId", userId);
        info.put("account", loginBase.getAccount());
        info.put("clientType", loginBase.getClientType());
        info.put("systemType", loginBase.getSystemType());
//        info.put("timestamp", System.currentTimeMillis());
        String key = Global.getFullUserTokenKey(loginBase.getClientType(), userId);
        String token = EncryUtil.encryV1(Global.PRI_KEY, JSON.toJSONString(info));
        int expireTime = ClientTypeEnum.expireTime(loginBase.getClientType());
        RedissonUtils.putString(key, token, expireTime);
        return token;
    }

    static class AsyncProcess1 implements Runnable {
        private final LoginBase loginBase;

        private final KwsUserResDto user;

        private final RDriverDetailVo driver;

        private final EntCacheResDto enterprise;

        private final RemoteUserService remoteUserService;

        public AsyncProcess1(LoginBase loginBase, KwsUserResDto user, RDriverDetailVo driver, EntCacheResDto enterprise ,
                             RemoteUserService remoteUserService) {
            this.loginBase = loginBase;
            this.user = user;
            this.driver = driver;
            this.enterprise = enterprise;
            this.remoteUserService = remoteUserService;
        }

        @Override
        public void run() {
            //司机信息
            SaveDriverToCache(loginBase, driver);

            //用户信息
            SaveUserToCache(loginBase, user);

            //企业信息
            SaveEntToCache(enterprise);
        }

        /**
         * @param ent 企业信息
         * @desc: 缓存存企业信息
         * @author: czh
         * @date: 2023/7/3
         */
        private void SaveEntToCache(EntCacheResDto ent) {
            if (ent == null) {
                return;
            }
            String key = Global.getFullUserEntKey(ent.getId());
            RedissonUtils.putString(key, JSON.toJSONString(ent), Global.APP_TOKEN_EXPIRE);
        }

        /**
         * @param loginBase 登录信息
         * @param driver 司机信息
         * @desc: 缓存司机信息
         * @author: czh
         * @date: 2023/7/3
         */
        private void SaveDriverToCache(LoginBase loginBase, RDriverDetailVo driver) {
            if (driver == null) {
                return;
            }
            //存用户登录信息
            LoginUserInfo loginUserInfo = new LoginUserInfo();
            loginUserInfo.setId(driver.getId());
            loginUserInfo.setSystemType(SystemTypeEnum.DRIVER.getCode());
            loginUserInfo.setAccount(driver.getPhone());
            loginUserInfo.setUserName(driver.getName());
            loginUserInfo.setPhone(driver.getPhone());
            loginUserInfo.setStatus(driver.getStatus());
            loginUserInfo.setEntId(enterprise != null ? enterprise.getId() : null);
            loginUserInfo.setEntName(enterprise != null ? enterprise.getFirmName() : null);
            loginUserInfo.setClientType(loginBase.getClientType());
            int expireTime = ClientTypeEnum.expireTime(loginBase.getClientType());
            String key = Global.getFullUserLoginKey(loginUserInfo.getSystemType(), loginUserInfo.getId());
            RedissonUtils.putString(key, JSON.toJSONString(loginUserInfo), Global.APP_TOKEN_EXPIRE);
        }

        /**
         * @param loginBase 登录信息
         * @param user 用户信息
         * @desc: 缓存用户信息
         * @author: czh
         * @date: 2023/7/3
         */
        private void SaveUserToCache(LoginBase loginBase, KwsUserResDto user) {
            if (user == null) {
                return;
            }
            //存用户登录信息
            LoginUserInfo loginUserInfo = new LoginUserInfo();
            loginUserInfo.setId(user.getId());
            loginUserInfo.setSystemType(loginBase.getSystemType());
            loginUserInfo.setClientType(loginBase.getClientType());
            loginUserInfo.setAccount(user.getPhone());
            loginUserInfo.setUserName(user.getName());
            loginUserInfo.setPhone(user.getPhone());
            loginUserInfo.setStatus(user.getStatus());
            loginUserInfo.setIsMain(user.getIsMain());
            loginUserInfo.setEntId(user.getEntId());
            loginUserInfo.setEntName(enterprise != null ? enterprise.getFirmName() : null);

            //普通用户需要填充数据权限
            if (user.getIsMain().equals(Global.NO)) {
                loginUserInfo.setAuthUserIdList(remoteUserService.queryAuthUserList(user.getId()));
            } else {
                List<FindEntUserResDto> entUser = remoteUserService.findEntUser(user.getEntId());
                if (CollectionUtils.isNotEmpty(entUser)) {
                    loginUserInfo.setAuthUserIdList(entUser.stream().map(FindEntUserResDto::getUserId).distinct().toList());
                }
            }

            int expireTime = ClientTypeEnum.expireTime(loginBase.getClientType());
            String key = Global.getFullUserLoginKey(loginUserInfo.getSystemType(), loginUserInfo.getId());
            RedissonUtils.putString(key, JSON.toJSONString(loginUserInfo), Global.APP_TOKEN_EXPIRE);

            //存缓存请求地址
            SaveMenusToCache(user);
        }

        /**
         * @param loginResVo 登录返参
         * @desc: 存缓存请求地址
         * @author: czh
         * @date: 2023/6/28
         */
        private void SaveMenusToCache(KwsUserResDto loginResVo) {
            //存权限菜单
            long id = loginResVo.getId();
            List<UserAccessMenuInfoResDto> userAccessMenuInfo = remoteUserService.queryUserAccessMenu(id);
            if (CollectionUtils.isEmpty(userAccessMenuInfo)) {
                RedissonUtils.delete(Global.REDIS_SYS_MENU_PREFIX + loginResVo.getSystemType() + Global.COLON + id);
                log.error("未查询到用户{}的菜单权限", id);
                return;
            }

            List<String> menus = new ArrayList<>();
            for (UserAccessMenuInfoResDto userAccessMenuInfoResDto : userAccessMenuInfo) {
                String links = userAccessMenuInfoResDto.getLinks();
                if (StringUtils.isNotBlank(links)) {
                    menus.addAll(Arrays.asList(userAccessMenuInfoResDto.getLinks().split(",")));
                }
            }
            RedissonUtils.putSet(Global.REDIS_SYS_MENU_PREFIX + id, menus);
        }

        /**
         * @param loginResVo 登录返参
         * @desc: 存登录记录信息
         * @author: czh
         * @date: 2023/6/28
         */
        private void SaveLoginInfo(LoginResVo loginResVo) {
            long userId = loginResVo.getId();
            UserLoginReqDto currentDayLogin = remoteUserService.currentDayLogin(userId);
            UserLoginReqDto userLoginReqDto = new UserLoginReqDto();
            userLoginReqDto.setPid(Objects.isNull(currentDayLogin) ? "" : String.valueOf(currentDayLogin.getId()));
            userLoginReqDto.setIp("");
            userLoginReqDto.setUserAgent("");
            userLoginReqDto.setUserId(loginResVo.getId());
            userLoginReqDto.setToken(loginResVo.getToken());
            userLoginReqDto.setValidTime("");
            userLoginReqDto.setFirst(Objects.isNull(currentDayLogin) ? Global.YES : Global.NO);
            userLoginReqDto.setLock(Global.NO);
            userLoginReqDto.setType(Global.NO);
            userLoginReqDto.setSource(loginResVo.getClientType());
            remoteUserService.saveUserLogin(userLoginReqDto);
        }

    }
}
