package com.sckw.auth.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.sckw.auth.model.vo.req.ForgetPasswordReqVo;
import com.sckw.auth.model.vo.req.LoginBase;
import com.sckw.auth.model.vo.req.RoleChangeVo;
import com.sckw.auth.model.vo.res.LoginResVo;
import com.sckw.auth.model.vo.res.LoginResVo1;
import com.sckw.auth.service.IAuthService;
import com.sckw.auth.util.AsyncFactory;
import com.sckw.core.common.enums.enums.DictEnum;
import com.sckw.core.exception.SystemException;
import com.sckw.core.model.constant.Global;
import com.sckw.core.model.constant.NumberConstant;
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.constant.HttpStatus;
import com.sckw.core.web.context.LoginUserHolder;
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.redis.utils.RedissonUtils;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.RemoteUserService;
import com.sckw.system.api.model.dto.req.ForgetPasswordReqDto;
import com.sckw.system.api.model.dto.req.UserLoginReqDto;
import com.sckw.system.api.model.dto.res.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.redisson.api.RSet;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @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, timeout = 8000)
    private RemoteSystemService systemService;

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

    @Override
    public HttpResult login(LoginBase loginBase) {
        if (StringUtils.isNotBlank(loginBase.getCaptcha())) {
            loginBase.setLoginMethod(LoginMethodEnum.SMS.getValue());
        }

        /*参数校验*/
        HttpResult result = checkParams(loginBase);
        if (result.getCode() != HttpStatus.SUCCESS_CODE) {
            return result;
        }

        /*运营端/企业端登录(PC/APP)*/
        if (loginBase.getSystemType() == SystemTypeEnum.MANAGE.getCode()
                || loginBase.getSystemType() == SystemTypeEnum.COMPANY.getCode()) {
           // KwsUserResDto kwsUserResDto = systemService.queryByAccount(loginBase.getAccount());
            return this.commonAuth(loginBase);
        }

        /*司机端*/
        if (loginBase.getSystemType() == SystemTypeEnum.DRIVER.getCode()) {
            KwsUserResDto kwsUserResDto = systemService.queryByAccount(loginBase.getAccount());
            if (Objects.nonNull(kwsUserResDto)) {
                loginBase.setSystemType(loginBase.getSystemType());
                return this.commonAppAuth(loginBase);
            }
            return this.driverAuth(loginBase);
        }

        return HttpResult.error(HttpStatus.PARAMETERS_MISSING_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);
    }

    /**
     * @param loginBase {}
     * @desc 司机账号登陆
     * @author zk
     * @date 2023/7/26
     **/
    public HttpResult driverAuth(LoginBase loginBase) {
        /*查询用户信息**/
        RDriverDetailVo driver = fleetService.findDriverDetai(loginBase.getAccount());
        /*信息校验**/
        if (driver == null) {
            return HttpResult.error(HttpStatus.QUERY_FAIL_CODE, "账号不存在，请检查并重新输入！");
        }
        boolean bool = PasswordUtils.validatePassword(loginBase.getAccount() + loginBase.getPassword(), driver.getPassword(), driver.getSalt());
        if (loginBase.getLoginMethod() == LoginMethodEnum.ORDINARY.getValue() && !bool) {
            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 AsyncProcess(loginBase, null, driver, enterprise, remoteUserService));

        /*生成refreshToken（记住密码时）**/
        String refreshToken = null;
        if (Boolean.TRUE.equals(loginBase.getRememberMe())) {
            refreshToken = generateRefreshToken(loginBase, driver.getId());
        }

        /*数据组装**/
        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);
        List<LoginResVo1.TabBarItem> tabBar = buildAppTabBar(loginRes,loginBase, null,1,loginRes.getEntTypes());
        if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(tabBar)) {
            loginRes.setTabBar(tabBar);
        }
        applyAppModulePermissions(loginRes, loginBase, null);
        loginRes.setRefreshToken(refreshToken);
        return HttpResult.ok(loginRes);
    }

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

        /*信息校验**/
        if (user == null) {
            return HttpResult.error(HttpStatus.QUERY_FAIL_CODE, "账号不存在，请检查并重新输入！");
        }
        boolean bool = PasswordUtils.validatePassword(loginBase.getAccount() + loginBase.getPassword(), user.getPassword(), user.getSalt());
        if (loginBase.getLoginMethod() == LoginMethodEnum.ORDINARY.getValue() && !bool) {
            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()) {
            if (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 AsyncProcess(loginBase, user, null, enterprise, remoteUserService));
        new AsyncProcess(loginBase, user, null, enterprise, remoteUserService).run();

        /*生成refreshToken（记住密码时）**/
        String refreshToken = null;
        if (Boolean.TRUE.equals(loginBase.getRememberMe())) {
            refreshToken = generateRefreshToken(loginBase, user.getId());
        }

        /*数据组装**/

        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.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.setRefreshToken(refreshToken);
        loginRes.setDeptId(user.getDeptId());
        loginRes.setRoleId(user.getRoleId());
        loginRes.setDriverId(user.getDriverId());
        loginRes.setRoleName(user.getRoleName());
        loginRes.setRoleList(user.getRoleInfoDto());
        List<LoginResVo1.TabBarItem> tabBar = buildAppTabBar(loginRes,loginBase, user.getRoleName(),0,loginRes.getEntTypes());
        if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(tabBar)) {
            loginRes.setTabBar(tabBar);
        }
        applyAppModulePermissions(loginRes, loginBase, user.getRoleName());
        if (user.getSystemType().equals(SystemTypeEnum.MANAGE.getCode())) {
            loginRes.setValid(true);
        } else {
            loginRes.setValid(!Objects.isNull(enterprise) && enterprise.getValid());
        }

        return HttpResult.ok(loginRes);
    }

    public HttpResult commonAppAuth(LoginBase loginBase) {
        /*查询用户信息**/
        KwsUserResDto user = systemService.queryUserDetails(loginBase.getAccount(), SystemTypeEnum.COMPANY.getCode());

        /*信息校验**/
        if (user == null) {
            return HttpResult.error(HttpStatus.QUERY_FAIL_CODE, "账号不存在，请检查并重新输入！");
        }
        boolean bool = PasswordUtils.validatePassword(loginBase.getAccount() + loginBase.getPassword(), user.getPassword(), user.getSalt());
        if (loginBase.getLoginMethod() == LoginMethodEnum.ORDINARY.getValue() && !bool) {
            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 (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 AsyncProcess(loginBase, user, null, enterprise, remoteUserService));
        new AsyncProcess(loginBase, user, null, enterprise, remoteUserService).run();

        /*生成refreshToken（记住密码时）**/
        String refreshToken = null;
        if (Boolean.TRUE.equals(loginBase.getRememberMe())) {
            refreshToken = generateRefreshToken(loginBase, user.getId());
        }

        /*数据组装**/

        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.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.setRefreshToken(refreshToken);
        loginRes.setDeptId(user.getDeptId());
        loginRes.setRoleId(user.getRoleId());
        loginRes.setRoleName(user.getRoleName());
        loginRes.setRoleList(user.getRoleInfoDto());
        List<LoginResVo1.TabBarItem> tabBar = buildAppTabBar(loginRes,loginBase, user.getRoleName(),0,loginRes.getEntTypes());
        if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(tabBar)) {
            loginRes.setTabBar(tabBar);

        }
        applyAppModulePermissions(loginRes, loginBase, user.getRoleName());
        if (user.getSystemType().equals(SystemTypeEnum.MANAGE.getCode())) {
            loginRes.setValid(true);
        } else {
            loginRes.setValid(!Objects.isNull(enterprise) && enterprise.getValid());
        }

        return HttpResult.ok(loginRes);
    }


    /**
     * @param params 登录参数
     * @return 返回结构
     * @desc 登录参数校验
     * @author zk
     * @date 2020/6/14 18:14
     **/
    public HttpResult checkParams(LoginBase params) {
        if (StringUtils.isBlank(params.getSystemType())) {
            return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, "应用服务类型不能为空！");
        }
        if (StringUtils.isBlank(params.getClientType())) {
            return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, "客户端类型不能为空！");
        }
//        if (StringUtils.isBlank(params.getAccessSpecial()) && params.getSystemType() != SystemTypeEnum.MANAGE.getCode()) {
//            return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, "平台标识不能为空！");
//        }
        if (StringUtils.isBlank(params.getAccount())) {
            return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, "请输入您的账号!");
        }
        if (params.getLoginMethod() == LoginMethodEnum.ORDINARY.getValue() && StringUtils.isBlank(params.getPassword())) {
            return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, "请输入您的密码!");
        }

        if (params.getLoginMethod() == LoginMethodEnum.SMS.getValue() && !RegularUtils.matchs(RegularUtils.PHONE_REG, params.getAccount())) {
            return HttpResult.error(HttpStatus.PARAMETERS_PATTERN_ERROR_CODE, "手机号格式不正确,请检查并重新输入！");
        }
        if (params.getLoginMethod() == LoginMethodEnum.SMS.getValue() && StringUtils.isBlank(params.getCaptcha())) {
            return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, "请输入您的验证码！");
        }
        String key = StringUtils.format(RedisConstant.MESSAGE_SMS_VERIFY_CODE_VALUE_KEY, DictEnum.SMS_LOGIN.getValue(), params.getAccount());

        RedissonUtils.putString(key, params.getCaptcha(), RedisConstant.SMS_VERIFY_CODE_VALID_TIME);
        String smsCaptcha = RedissonUtils.getString(key);
        if (params.getLoginMethod() == LoginMethodEnum.SMS.getValue() && StringUtils.isBlank(smsCaptcha)) {
            return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, "验证码已过期,请重新获取！");
        }
        if (params.getLoginMethod() == LoginMethodEnum.SMS.getValue() && StringUtils.isBlank(smsCaptcha)) {
            return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, "验证码已过期,请重新获取！");
        }
        if (params.getLoginMethod() == LoginMethodEnum.SMS.getValue() && !smsCaptcha.equals(params.getCaptcha())) {
            return HttpResult.error(HttpStatus.UN_LOGIN_CODE, "验证码不正确,请检查并重新输入!");
        }

        return HttpResult.ok();
    }

    /**
     * @param loginBase  登录参数
     * @param enterprise 企业信息
     * @return 返回校验结果
     * @desc 专场标识码校验
     * @author zk
     * @date 2023/12/14
     **/
    public HttpResult checkSpecial(LoginBase loginBase, EntCacheResDto enterprise) {
        /*校验*/
        //运营端不做校验
        if (loginBase.getSystemType() == SystemTypeEnum.MANAGE.getCode()) {
            return HttpResult.ok();
        }
        //平台专场集
        List<SpecialResVo> specialResVos = systemService.querySpecial();
        //企业所属专场
        String special = enterprise != null ? enterprise.getSpecial() : null;
        //用户当前使用平台
        String accessSpecial = loginBase.getAccessSpecial();
        //校验是否存在专场数据
        if (CollectionUtils.isEmpty(specialResVos)) {
            return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, "系统平台标识码缺失，请联系平台系统管理员确认！");
        }

        //校验Hearder中标识码是否属于系统平台标识码
        boolean bool = false;
        SpecialResVo currentSpecialRes = null;
        SpecialResVo mainSpecialRes = null;
        for (SpecialResVo specialResVo : specialResVos) {
            bool = specialResVo.getCode().equals(accessSpecial) || bool;
            currentSpecialRes = specialResVo.getCode().equals(accessSpecial) ? specialResVo : currentSpecialRes;
            mainSpecialRes = specialResVo.getIsMain() == NumberConstant.ONE ? specialResVo : mainSpecialRes;
        }
        if (!bool) {
            return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, "系统平台标识码不正确，请联系平台系统管理员确认！");
        }

        //校验专场状态
        if (currentSpecialRes != null && currentSpecialRes.getStatus() == Global.YES) {
            return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, "您当前使用的平台暂停使用，如有疑问请联系平台系统管理员确认！");
        }

        //司机端可以登陆所有平台，只对任务数据做隔离
        if (loginBase.getSystemType() == SystemTypeEnum.DRIVER.getCode()) {
            return HttpResult.ok();
        }

        //校验企业非专场时，Hearder中标识码是否为主平台标识码
        if (StringUtils.isBlank(special)) {
            if (currentSpecialRes != null && currentSpecialRes.getIsMain() != NumberConstant.ONE) {
                String msg = "请进入" + mainSpecialRes.getName() + "，平台网站为" + mainSpecialRes.getWebsite() + "，如有疑问请联系平台系统管理员确认！";
                return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, msg);
            }
        } else {
            List<String> specials = Arrays.asList(special.split(Global.COMMA));
            if (!specials.contains(accessSpecial)) {
                StringBuilder msg = new StringBuilder();
//                msg.append("请进入");
                for (String e : specials) {
                    specialResVos.stream().filter(ee -> {
                        return e.equals(ee.getCode());
                    }).map(ee -> "请进入" + ee.getName() + "，平台网站为" + ee.getWebsite() + "，").forEach(msg::append);
                }
                msg.append("如有疑问请联系平台系统管理员确认！");
                return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, msg.toString());
            }

        }
        return HttpResult.ok();
    }

    /**
     * @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());
        LoginBase loginBase = new LoginBase();
        loginBase.setClientType(clientType);
        applyAppModulePermissions(loginRes, loginBase, user.getRoleName());
        if (user.getSystemType().equals(SystemTypeEnum.MANAGE.getCode())) {
            loginRes.setValid(true);
        } else {
            loginRes.setValid(!Objects.isNull(enterprise) && enterprise.getValid());
        }
        return loginRes;
    }

    @Override
    public HttpResult changeRole(RoleChangeVo reqVo) {
        KwsUserResDto user = systemService.queryUserDetails(LoginUserHolder.getAccount(), LoginUserHolder.getSystemType());

        /*信息校验**/
        if (user == null) {
            return HttpResult.error(HttpStatus.QUERY_FAIL_CODE, "账号不存在，请检查并重新输入！");
        }

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

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

        UserService userService = new UserService(reqVo, user, enterprise, remoteUserService);
        userService.run();
        return HttpResult.ok("切换成功，请刷新菜单");
    }

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

    /**
     * @param loginBase 登录参数
     * @param userId    用户ID
     * @desc 生成refreshToken（记住密码时使用，支持多设备）
     * @author assistant
     * @date 2026/1/14
     **/
    private String generateRefreshToken(LoginBase loginBase, Long userId) {
        String account = loginBase.getAccount();
        String clientType = loginBase.getClientType();
        Integer systemType = loginBase.getSystemType();
        String deviceId = loginBase.getDeviceId();
        Map<String, Object> info = new HashMap<>(Global.NUMERICAL_SIXTEEN);
        info.put("userId", userId);
        info.put("account", account);
        info.put("clientType", clientType);
        info.put("systemType", systemType);
        info.put("deviceId", deviceId);
        info.put("type", "refresh");
        String key = Global.getFullRefreshTokenKey(clientType, userId, deviceId);
        String refreshToken = EncryUtil.encryV1(Global.PRI_KEY, JSON.toJSONString(info));
        RedissonUtils.putString(key, refreshToken, Global.REFRESH_TOKEN_EXPIRE);
        return refreshToken;
    }

    @Override
    public HttpResult refreshToken(String refreshToken, String clientType, Integer systemType, String deviceId) {
        log.info("刷新token，refreshToken：{}，clientType：{}，systemType：{}，deviceId：{}", refreshToken, clientType, systemType, deviceId);
        
        // 验证refreshToken参数
        HttpResult validateResult = validateRefreshTokenParam(refreshToken);
        if (validateResult != null) {
            return validateResult;
        }
        
        // 解析refreshToken
        Map<String, Object> tokenInfoMap = parseRefreshToken(refreshToken);
        if (tokenInfoMap == null) {
            return HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, "刷新令牌无效！");
        }
        
        // 验证refreshToken是否有效
        HttpResult verifyResult = verifyRefreshToken(tokenInfoMap, refreshToken);
        if (verifyResult != null) {
            return verifyResult;
        }
        
        // 构建LoginBase对象
        LoginBase loginBase = buildLoginBaseFromTokenInfo(tokenInfoMap);
        
        // 根据系统类型处理刷新逻辑
        Integer tokenSystemType = Integer.valueOf(tokenInfoMap.get("systemType").toString());
        if (Objects.equals(tokenSystemType, SystemTypeEnum.DRIVER.getCode())) {
            return handleDriverRefresh(loginBase, tokenInfoMap);
        } else {
            return handleCommonRefresh(loginBase, tokenInfoMap);
        }
    }
    
    @Override
    public HttpResult switchAccount(String targetRefreshToken, String clientType, Integer systemType, String deviceId) {
        log.info("切换账号，targetRefreshToken：{}，clientType：{}，systemType：{}，deviceId：{}", targetRefreshToken, clientType, systemType, deviceId);
        
        // 验证targetRefreshToken参数
        HttpResult validateResult = validateRefreshTokenParam(targetRefreshToken);
        if (validateResult != null) {
            return validateResult;
        }
        
        // 解析目标账号的refreshToken
        Map<String, Object> targetTokenInfoMap = parseRefreshToken(targetRefreshToken);
        if (targetTokenInfoMap == null) {
            return HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, "目标账号的刷新令牌无效！");
        }
        
        // 验证目标账号的refreshToken是否有效
        HttpResult verifyResult = verifyRefreshToken(targetTokenInfoMap, targetRefreshToken);
        if (verifyResult != null) {
            return HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, "目标账号的刷新令牌已过期或无效！");
        }
        
        // 清除当前登录用户的token缓存（如果存在）
        // todo - 可以考虑只清除当前设备的token缓存，保留其他设备的登录状态 清除缓存这块产品说暂时先不要，以后单独登录在加
       // clearCurrentUserToken(clientType, deviceId);
        
        // 构建LoginBase对象（使用新的deviceId）
        LoginBase loginBase = buildLoginBaseFromTokenInfo(targetTokenInfoMap);
        // 如果传入了新的deviceId，则使用新的deviceId
        if (StringUtils.isNotBlank(deviceId)) {
            loginBase.setDeviceId(deviceId);
        }
        
        // 根据系统类型处理切换逻辑
        Integer targetSystemType = Integer.valueOf(targetTokenInfoMap.get("systemType").toString());
        if (Objects.equals(SystemTypeEnum.DRIVER.getCode(), targetSystemType)) {
            return handleDriverRefresh(loginBase, targetTokenInfoMap);
        } else {
            return handleCommonRefresh(loginBase, targetTokenInfoMap);
        }
    }
    
    /**
     * 清除当前登录用户的token缓存
     */
    private void clearCurrentUserToken(String clientType, String deviceId) {
        try {
            LoginUserInfo currentUser = LoginUserHolder.get();
            if (currentUser != null && currentUser.getId() != null) {
                // 清除当前用户的token
                String tokenKey = Global.getFullUserTokenKey(clientType, currentUser.getId());
                RedissonUtils.delete(tokenKey);
                
                // 清除当前用户的登录信息缓存
                String loginKey = Global.getFullUserLoginKey(currentUser.getSystemType(), currentUser.getId());
                RedissonUtils.delete(loginKey);
                
                log.info("已清除当前用户token缓存，userId：{}", currentUser.getId());
            }
        } catch (Exception e) {
            log.warn("清除当前用户token缓存失败", e);
        }
    }
    
    /**
     * 验证refreshToken参数
     */
    private HttpResult validateRefreshTokenParam(String refreshToken) {
        if (StringUtils.isBlank(refreshToken)) {
            return HttpResult.error(HttpStatus.PARAMETERS_MISSING_CODE, "刷新令牌不能为空！");
        }
        return null;
    }
    
    /**
     * 解析refreshToken
     */
    private Map<String, Object> parseRefreshToken(String refreshToken) {
        String tokenInfo;
        try {
            tokenInfo = EncryUtil.descry(Global.PRI_KEY, refreshToken);
            return JSON.parseObject(tokenInfo, Map.class);
        } catch (Exception e) {
            log.error("解析refreshToken失败", e);
            return null;
        }
    }
    
    /**
     * 验证refreshToken是否有效
     */
    private HttpResult verifyRefreshToken(Map<String, Object> tokenInfoMap, String refreshToken) {
        Long userId = Long.valueOf(tokenInfoMap.get("userId").toString());
        String tokenClientType = tokenInfoMap.get("clientType").toString();
        String tokenDeviceId = tokenInfoMap.get("deviceId") != null ? tokenInfoMap.get("deviceId").toString() : null;
        
        String key = Global.getFullRefreshTokenKey(tokenClientType, userId, tokenDeviceId);
        String storedRefreshToken = RedissonUtils.getString(key);
        if (StringUtils.isBlank(storedRefreshToken) || !storedRefreshToken.equals(refreshToken)) {
            return HttpResult.error(HttpStatus.TOKEN_INVALID_CODE, "刷新令牌已过期或无效，请重新登录！");
        }
        return null;
    }
    
    /**
     * 从token信息构建LoginBase对象
     */
    private LoginBase buildLoginBaseFromTokenInfo(Map<String, Object> tokenInfoMap) {
        String account = tokenInfoMap.get("account").toString();
        String tokenClientType = tokenInfoMap.get("clientType").toString();
        Integer tokenSystemType = Integer.valueOf(tokenInfoMap.get("systemType").toString());
        String tokenDeviceId = tokenInfoMap.get("deviceId") != null ? tokenInfoMap.get("deviceId").toString() : null;
        
        LoginBase loginBase = new LoginBase();
        loginBase.setAccount(account);
        loginBase.setClientType(tokenClientType);
        loginBase.setSystemType(tokenSystemType);
        loginBase.setDeviceId(tokenDeviceId);
        loginBase.setRememberMe(true);
        
        return loginBase;
    }
    
    /**
     * 处理司机端token刷新
     */
    private HttpResult handleDriverRefresh(LoginBase loginBase, Map<String, Object> tokenInfoMap) {
        String account = tokenInfoMap.get("account").toString();
        String tokenClientType = tokenInfoMap.get("clientType").toString();
        Integer tokenSystemType = Integer.valueOf(tokenInfoMap.get("systemType").toString());
        
        // 查询司机信息
        RDriverDetailVo driver = fleetService.findDriverDetai(account);
        if (driver == null) {
            return HttpResult.error(HttpStatus.QUERY_FAIL_CODE, "账号不存在！");
        }
        if (driver.getStatus() == Global.YES) {
            return HttpResult.error(HttpStatus.CODE_10301, "您的账号已冻结！");
        }

        EntCacheResDto enterprise = systemService.queryEntDetails(driver.getEntId());

        // 生成新token
        String newToken = generateToken(loginBase, driver.getId());
        // 生成新的refreshToken
        String newRefreshToken = generateRefreshToken(loginBase, driver.getId());

        // 更新缓存
        new AsyncProcess(loginBase, null, driver, enterprise, remoteUserService).run();

        // 构建返回结果
        LoginResVo1 loginRes = buildDriverLoginRes(loginBase,driver, enterprise, tokenClientType, tokenSystemType, newToken, newRefreshToken);
        return HttpResult.ok(loginRes);
    }
    
    /**
     * 处理运营端/企业端token刷新
     */
    private HttpResult handleCommonRefresh(LoginBase loginBase, Map<String, Object> tokenInfoMap) {
        String account = tokenInfoMap.get("account").toString();
        String tokenClientType = tokenInfoMap.get("clientType").toString();
        Integer tokenSystemType = Integer.valueOf(tokenInfoMap.get("systemType").toString());
        
        // 查询用户信息
        KwsUserResDto user = systemService.queryUserDetails(account, tokenSystemType);
        if (user == null) {
            return HttpResult.error(HttpStatus.QUERY_FAIL_CODE, "账号不存在！");
        }
        if (user.getStatus() == Global.YES) {
            return HttpResult.error(HttpStatus.CODE_10301, "您的账号已冻结！");
        }

        EntCacheResDto enterprise = systemService.queryEntDetails(user.getEntId());
        if (tokenSystemType == SystemTypeEnum.COMPANY.getCode()) {
            if (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 newToken = generateToken(loginBase, user.getId());
        String newRefreshToken = generateRefreshToken(loginBase, user.getId());

        // 更新缓存
        new AsyncProcess(loginBase, user, null, enterprise, remoteUserService).run();

        // 构建返回结果
        LoginResVo1 loginRes = buildCommonLoginRes(loginBase,user, enterprise, tokenClientType, tokenSystemType, newToken, newRefreshToken);
        return HttpResult.ok(loginRes);
    }
    
    /**
     * 构建司机端登录返回结果
     */
    private LoginResVo1 buildDriverLoginRes(LoginBase loginBase,RDriverDetailVo driver, EntCacheResDto enterprise,
                                            String tokenClientType, Integer tokenSystemType, 
                                            String newToken, String newRefreshToken) {
        LoginResVo1 loginRes = new LoginResVo1();
        loginRes.setId(driver.getId());
        loginRes.setName(driver.getName());
        loginRes.setAccount(driver.getPhone());
        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(tokenClientType);
        loginRes.setSystemType(tokenSystemType);
        loginRes.setToken(newToken);
        loginRes.setRefreshToken(newRefreshToken);
        loginRes.setDriverId(driver.getId());
        List<LoginResVo1.TabBarItem> tabBar = buildAppTabBar(loginRes,loginBase, null,1,loginRes.getEntTypes());
        if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(tabBar)) {
            loginRes.setTabBar(tabBar);
        }
        applyAppModulePermissions(loginRes, loginBase, null);
        return loginRes;
    }
    
    /**
     * 构建运营端/企业端登录返回结果
     */
    private LoginResVo1 buildCommonLoginRes(LoginBase loginBase,KwsUserResDto user, EntCacheResDto enterprise,
                                           String tokenClientType, Integer tokenSystemType, 
                                           String newToken, String newRefreshToken) {
        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.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(tokenClientType);
        loginRes.setSystemType(user.getSystemType());
        loginRes.setToken(newToken);
        loginRes.setRefreshToken(newRefreshToken);
        loginRes.setDeptId(user.getDeptId());
        loginRes.setRoleId(user.getRoleId());
        loginRes.setDriverId(user.getDriverId());
        loginRes.setRoleName(user.getRoleName());
        loginRes.setRoleList(user.getRoleInfoDto());
        List<LoginResVo1.TabBarItem> tabBar = buildAppTabBar(loginRes,loginBase, user.getRoleName(),1,loginRes.getEntTypes());
        if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(tabBar)) {
            loginRes.setTabBar(tabBar);
        }
        applyAppModulePermissions(loginRes, loginBase, user.getRoleName());
        if (user.getSystemType().equals(SystemTypeEnum.MANAGE.getCode())) {
            loginRes.setValid(true);
        } else {
            loginRes.setValid(!Objects.isNull(enterprise) && enterprise.getValid());
        }
        return loginRes;
    }

    private boolean isAppLogin(LoginBase loginBase) {
        String clientType = loginBase.getClientType();
        return Objects.equals(clientType, ClientTypeEnum.app.getValue())
                || Objects.equals(clientType, ClientTypeEnum.ios.getValue())
                || Objects.equals(clientType, ClientTypeEnum.android.getValue())
                || Objects.equals(clientType, ClientTypeEnum.mobile.getValue());
    }

    private void applyAppModulePermissions(LoginResVo1 loginRes, LoginBase loginBase, String roleName) {
        roleName = loginRes.getRoleName();
        loginRes.setShowOrderStatisticsModule(Boolean.FALSE);
        loginRes.setShowSalesStatisticsModule(Boolean.FALSE);
        loginRes.setShowWalletModule(Boolean.FALSE);
        loginRes.setShowAddressModule(Boolean.FALSE);
        loginRes.setWalletModuleItems(Collections.emptyList());
        if (!isAppLogin(loginBase) || StringUtils.isBlank(roleName)) {
            return;
        }
        boolean isSeller = containsAnyRole(roleName, "销售","供应商管理员");
        boolean isFinance = containsAnyRole(roleName, "财务");
        boolean isPurchase = containsAnyRole(roleName, "采购", "买家","采购商管理员");
        if (isSeller) {
            loginRes.setShowOrderStatisticsModule(Boolean.TRUE);
            loginRes.setShowSalesStatisticsModule(Boolean.TRUE);
            return;
        }
        if (isFinance) {
            loginRes.setShowOrderStatisticsModule(Boolean.TRUE);
            loginRes.setShowWalletModule(Boolean.TRUE);
            loginRes.setWalletModuleItems(Arrays.asList("PENDING_PERFORMANCE_BALANCE", "PENDING_FREIGHT"));
            return;
        }
        if (isPurchase) {
            loginRes.setShowOrderStatisticsModule(Boolean.TRUE);
            loginRes.setShowWalletModule(Boolean.TRUE);
            loginRes.setShowAddressModule(Boolean.TRUE);
            loginRes.setWalletModuleItems(Arrays.asList("PREPAY_BALANCE", "PENDING_FREIGHT"));
        }
    }

    private boolean containsAnyRole(String roleName, String... roleKeywords) {
        if (StringUtils.isBlank(roleName) || roleKeywords == null) {
            return false;
        }
        for (String roleKeyword : roleKeywords) {
            if (StringUtils.isNotBlank(roleKeyword) && roleName.contains(roleKeyword)) {
                return true;
            }
        }
        return false;
    }

    private List<LoginResVo1.TabBarItem> buildAppTabBar(LoginResVo1 loginRes,LoginBase loginBase, String roleName,int flag,  String entTypeNames) {
       log.info("当前用户角色：{}, 企业类型：{}", roleName, entTypeNames);
        if (!isAppLogin(loginBase)) {
            return List.of();
        }
        if (containsAnyRole(roleName, "采购")) {
            return buildBuyerTabBar();
        }
        boolean isDoorKeeper = StringUtils.isNotBlank(roleName) && roleName.contains("门卫");
        boolean isForkliftDriver = StringUtils.isNotBlank(roleName) && roleName.contains("铲车司机");
        boolean isBuyer = StringUtils.isNotBlank(roleName) && roleName.contains("买家");
        boolean isSeller = StringUtils.isNotBlank(roleName) && roleName.contains("销售");
        boolean isDriver = StringUtils.isNotBlank(roleName) && roleName.contains("司机");
        boolean isLogistics = StringUtils.isNotBlank(roleName) && roleName.contains("物流");
        boolean isFinance = StringUtils.isNotBlank(roleName) && roleName.contains("财务");
        //企业属性 （1供应商，2采购商，34PL物流，43PL物流）
        boolean isSupplierAdmin = StringUtils.isNotBlank(roleName) && roleName.contains("系统管理员") && org.apache.commons.lang3.StringUtils.equals(entTypeNames, "1")  ;
        boolean isLogisticsAdmin = StringUtils.isNotBlank(roleName) && roleName.contains("系统管理员") && org.apache.commons.lang3.StringUtils.equals(entTypeNames, "3");
        boolean isPurchaseAdmin = StringUtils.isNotBlank(roleName) && roleName.contains("系统管理员") && org.apache.commons.lang3.StringUtils.equals(entTypeNames, "2");

        if (isDoorKeeper) {
            return buildDoorKeeperTabBar();
        }
        if (isForkliftDriver) {
            return buildForkliftDriverTabBar();
        }
        if (isBuyer) {
            return buildBuyerTabBar();
        }
        if (isSeller ||isFinance) {
            return buildSellerTabBar();
        }
        if (isDriver){
            return buildDefaultDriverTabBar();
        }
        if (isLogistics){
            return buildLogisticsTabBar();
        }
        if (isSupplierAdmin){
            loginRes.setRoleName("供应商管理员");
            return buildSupplierAdminTabBar();
        }
        if (isLogisticsAdmin){
            loginRes.setRoleName("物流商管理员");
            return buildLogisticsAdminTabBar();
        }
        if (isPurchaseAdmin){
            log.info("用户角色包含系统管理员且企业属性为采购商，返回采购管理员TabBar");
            loginRes.setRoleName("采购商管理员");
            return buildPurchaseAdminTabBar();}
        return List.of();
    }

    private List<LoginResVo1.TabBarItem> buildPurchaseAdminTabBar() {
        List<LoginResVo1.TabBarItem> items = new ArrayList<>();
        items.add(buildTabBarItem(
                "商城",
                "/static/tabbar/mall_select.png",
                "/static/tabbar/mall.png",
                "/pages/mall/index"
        ));
        items.add(buildTabBarItem(
                "贸易订单",
                "/static/tabbar/trade_select.png",
                "/static/tabbar/trade.png",
                "/pages/tradeOrder/index"
        ));
        items.add(buildTabBarItem(
                "物流订单",
                "/static/tabbar/logOrder_select.png",
                "/static/tabbar/logOrder.png",
                "/pages/logistics/order/index"
        ));
        items.add(buildTabBarItem(
                "物流运单",
                "/static/tabbar/waybill_select.png",
                "/static/tabbar/waybill.png",
                "/pages/logistics/waybill/index"
        ));
        items.add(buildTabBarItem(
                "个人中心",
                "/static/tabbar/my_select.png",
                "/static/tabbar/my.png",
                "/pages/myCenter/index"
        ));
        return items;
    }

    private List<LoginResVo1.TabBarItem> buildLogisticsAdminTabBar() {
        List<LoginResVo1.TabBarItem> items = new ArrayList<>();

        items.add(buildTabBarItem(
                "物流订单",
                "/static/tabbar/logOrder_select.png",
                "/static/tabbar/logOrder.png",
                "/pages/logistics/order/index"
        ));
        items.add(buildTabBarItem(
                "物流运单",
                "/static/tabbar/waybill_select.png",
                "/static/tabbar/waybill.png",
                "/pages/logistics/waybill/index"
        ));
        items.add(buildTabBarItem(
                "个人中心",
                "/static/tabbar/my_select.png",
                "/static/tabbar/my.png",
                "/pages/myCenter/index"
        ));
        return items;
    }

    private List<LoginResVo1.TabBarItem> buildSupplierAdminTabBar() {
        List<LoginResVo1.TabBarItem> items = new ArrayList<>();
        items.add(buildTabBarItem(
                "贸易订单",
                "/static/tabbar/trade_select.png",
                "/static/tabbar/trade.png",
                "/pages/tradeOrder/index"
        ));
        items.add(buildTabBarItem(
                "物流订单",
                "/static/tabbar/logOrder_select.png",
                "/static/tabbar/logOrder.png",
                "/pages/logistics/order/index"
        ));
        items.add(buildTabBarItem(
                "物流运单",
                "/static/tabbar/waybill_select.png",
                "/static/tabbar/waybill.png",
                "/pages/logistics/waybill/index"
        ));
        items.add(buildTabBarItem(
                "个人中心",
                "/static/tabbar/my_select.png",
                "/static/tabbar/my.png",
                "/pages/myCenter/index"
        ));
        return items;

    }

    private List<LoginResVo1.TabBarItem> buildSellerTabBar() {
        List<LoginResVo1.TabBarItem> items = new ArrayList<>();
        items.add(buildTabBarItem(
                "贸易订单",
                "/static/tabbar/trade_select.png",
                "/static/tabbar/trade.png",
                "/pages/tradeOrder/index"
        ));
        items.add(buildTabBarItem(
                "物流订单",
                "/static/tabbar/logOrder_select.png",
                "/static/tabbar/logOrder.png",
                "/pages/logistics/order/index"
        ));
        items.add(buildTabBarItem(
                "物流运单",
                "/static/tabbar/waybill_select.png",
                "/static/tabbar/waybill.png",
                "/pages/logistics/waybill/index"
        ));
        items.add(buildTabBarItem(
                "个人中心",
                "/static/tabbar/my_select.png",
                "/static/tabbar/my.png",
                "/pages/myCenter/index"
        ));
        return items;
    }

    private List<LoginResVo1.TabBarItem> buildLogisticsTabBar() {
        List<LoginResVo1.TabBarItem> items = new ArrayList<>();

        items.add(buildTabBarItem(
                "物流订单",
                "/static/tabbar/logOrder_select.png",
                "/static/tabbar/logOrder.png",
                "/pages/logistics/order/index"
        ));
        items.add(buildTabBarItem(
                "物流运单",
                "/static/tabbar/waybill_select.png",
                "/static/tabbar/waybill.png",
                "/pages/logistics/waybill/index"
        ));
        items.add(buildTabBarItem(
                "个人中心",
                "/static/tabbar/my_select.png",
                "/static/tabbar/my.png",
                "/pages/myCenter/index"
        ));
        return items;
    }

    private List<LoginResVo1.TabBarItem> buildBuyerTabBar() {
        List<LoginResVo1.TabBarItem> items = new ArrayList<>();
        items.add(buildTabBarItem(
                "商城",
                "/static/tabbar/mall_select.png",
                "/static/tabbar/mall.png",
                "/pages/mall/index"
        ));
        items.add(buildTabBarItem(
                "贸易订单",
                "/static/tabbar/trade_select.png",
                "/static/tabbar/trade.png",
                "/pages/tradeOrder/index"
        ));
        items.add(buildTabBarItem(
                "物流订单",
                "/static/tabbar/logOrder_select.png",
                "/static/tabbar/logOrder.png",
                "/pages/logistics/order/index"
        ));
        items.add(buildTabBarItem(
                "物流运单",
                "/static/tabbar/waybill_select.png",
                "/static/tabbar/waybill.png",
                "/pages/logistics/waybill/index"
        ));
        items.add(buildTabBarItem(
                "个人中心",
                "/static/tabbar/my_select.png",
                "/static/tabbar/my.png",
                "/pages/myCenter/index"
        ));
        return items;
    }

    private List<LoginResVo1.TabBarItem> buildDoorKeeperTabBar() {
        List<LoginResVo1.TabBarItem> items = new ArrayList<>();
        items.add(buildTabBarItem(
                "往来车辆",
                "/static/tabbar/car_select.png",
                "/static/tabbar/car.png",
                "/pages/doorkeeper/index"
        ));
        items.add(buildTabBarItem(
                "个人中心",
                "/static/tabbar/my_select.png",
                "/static/tabbar/my.png",
                "/pages/myCenter/index"
        ));
        return items;
    }

    private List<LoginResVo1.TabBarItem> buildForkliftDriverTabBar() {
        List<LoginResVo1.TabBarItem> items = new ArrayList<>();
        items.add(buildTabBarItem(
                "任务",
                "/static/tabbar/task_select.png",
                "/static/tabbar/task.png",
                "/pages/forklift/index"
        ));
        items.add(buildTabBarItem(
                "个人中心",
                "/static/tabbar/my_select.png",
                "/static/tabbar/my.png",
                "/pages/myCenter/index"
        ));
        return items;
    }

    private List<LoginResVo1.TabBarItem> buildDefaultDriverTabBar() {
        List<LoginResVo1.TabBarItem> items = new ArrayList<>();
        items.add(buildTabBarItem(
                "任务",
                "/static/tabbar/task_select.png",
                "/static/tabbar/task.png",
                "/pages/index/index"
        ));
        items.add(buildTabBarItem(
                "管理",
                "/static/tabbar/manage_select.png",
                "/static/tabbar/manage.png",
                "/pages/manage/index"
        ));
        return items;
    }

    private LoginResVo1.TabBarItem buildTabBarItem(String text, String iconPath, String notSelectedIconPath, String pagePath) {
        LoginResVo1.TabBarItem item = new LoginResVo1.TabBarItem();
        item.setText(text);
        item.setIconPath(iconPath);
        item.setNotSelectedIconPath(notSelectedIconPath);
        item.setPagePath(pagePath);
        item.setCount(0);
        return item;
    }

    static class AsyncProcess implements Runnable {
        private final LoginBase loginBase;

        private final KwsUserResDto user;

        private final RDriverDetailVo driver;

        private final EntCacheResDto enterprise;

        private final RemoteUserService remoteUserService;

        public AsyncProcess(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());
            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.setUseRoleId(user.getRoleId());
            loginUserInfo.setUseEntId(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());
                }
            }
            //客户经理  存储相关联企业id
            customerManager(loginUserInfo, user, loginBase);
            saveEntList(loginUserInfo, user, loginBase);
            String key = Global.getFullUserLoginKey(loginUserInfo.getSystemType(), loginUserInfo.getId());
            RedissonUtils.putString(key, JSON.toJSONString(loginUserInfo), Global.APP_TOKEN_EXPIRE);
            //存缓存请求地址
            saveMenusToCache(user);
        }

        private void customerManager(LoginUserInfo loginUserInfo, KwsUserResDto user, LoginBase loginBase) {
            if (SystemTypeEnum.MANAGE.getCode().equals(loginBase.getSystemType())) {
                List<Long> enterpriseIds = new ArrayList<>();
                if (user.getIsMain().equals(Global.YES)) {
                    //获取所有企业id
                    List<Long> enterpriseIdList = remoteUserService.findAllEnterprise();
                    if (Objects.nonNull(enterpriseIdList) && enterpriseIdList.size() > 0) {
                        enterpriseIds.addAll(enterpriseIdList);
                    }
                    //获取所有运营端账号关联的企业(客户经理关联的企业)
                    List<Long> userIds = remoteUserService.selectUserBySystemType(SystemTypeEnum.MANAGE.getCode());
                    /**带有数据权限*/
                    List<Long> enterpriseListByIds = remoteUserService.findEnterpriseListByIds(userIds);
                    if (Objects.nonNull(enterpriseListByIds) && enterpriseListByIds.size() > 0) {
                        enterpriseIds.addAll(enterpriseListByIds);
                    }
                    //无数据权限，运营账号(客户经理关联)关联的企业即可
//                    enterpriseIds = remoteUserService.findEnterpriseListByUserIds(userIds);
                } else {
                    List<Long> serviceEnterpriseIds = remoteUserService.findEnterpriseIds(user.getId());
                    if (Objects.nonNull(serviceEnterpriseIds) && serviceEnterpriseIds.size() > 0) {
                        enterpriseIds.addAll(serviceEnterpriseIds);
                    }
                }
                if (enterpriseIds.size() > 0) {
                    enterpriseIds = enterpriseIds.stream().distinct().collect(Collectors.toList());
                    String key = Global.getCustomerManagerUserLoginKey(loginUserInfo.getSystemType(), loginUserInfo.getId());
                    RSet<Object> set = RedissonUtils.getSet(key);
                    if (CollectionUtils.isNotEmpty(set)) {
                        RedissonUtils.delete(key);
                    }
                    RedissonUtils.putSet(key, enterpriseIds);
                    loginUserInfo.setAuthEntIdList(enterpriseIds);
                }
            }
        }

        private void saveEntList(LoginUserInfo loginUserInfo, KwsUserResDto user, LoginBase loginBase) {
            List<Long> childEntList = remoteUserService.findChildEntList(loginUserInfo.getEntId());
            if (CollUtil.isNotEmpty(childEntList)) {
                loginUserInfo.setChildEntList(childEntList);
            }
        }

        /**
         * @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);
        }
    }
}
