package com.css.txw.sso.service.oauth2;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.css.ggzc.framework.common.util.gy.GyUtils;
import com.css.txw.sso.constants.SsoApiConstants;
import com.css.txw.sso.constants.SsoConstants;
import com.css.txw.sso.mapper.oauth2.OAuth2AccessTokenMapper;
import com.css.txw.sso.mapper.oauth2.OAuth2RefreshTokenMapper;
import com.css.txw.sso.pojo.domain.oauth2.OAuth2AccessTokenDO;
import com.css.txw.sso.pojo.domain.oauth2.OAuth2ClientDO;
import com.css.txw.sso.pojo.domain.oauth2.OAuth2CodeDO;
import com.css.txw.sso.pojo.domain.oauth2.OAuth2RefreshTokenDO;
import com.css.txw.sso.pojo.dto.session.AccessTokenInfo;
import com.css.txw.sso.pojo.dto.session.SessionInfo;
import com.css.txw.sso.service.yhxx.YhxxService;
import com.css.txw.sso.util.OAuth2AccessTokenRedisDAO;
import com.css.ggzc.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.css.ggzc.framework.common.util.date.DateUtils;
import com.css.ggzc.framework.common.util.object.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.css.ggzc.framework.common.exception.util.ServiceExceptionUtil.exception0;
import static com.css.ggzc.framework.common.util.collection.CollectionUtils.convertSet;


/**
 * OAuth2.0 Token Service 实现类
 */
@Service
public class OAuth2TokenServiceImpl implements OAuth2TokenService {

    @Resource
    private OAuth2AccessTokenMapper oauth2AccessTokenMapper;
    @Resource
    private OAuth2RefreshTokenMapper oauth2RefreshTokenMapper;

    @Resource
    private OAuth2AccessTokenRedisDAO oauth2AccessTokenRedisDAO;

    @Resource
    private OAuth2ClientService oauth2ClientService;

    @Resource
    private YhxxService yhxxService;

    @Override
    @Transactional
    public OAuth2AccessTokenDO createAccessToken(String userId, String clientId, List<String> scopes) {
        OAuth2ClientDO clientDO = oauth2ClientService.validOAuthClientFromCache(clientId);
        SessionInfo sessionInfo = new SessionInfo();
        if (!SsoConstants.CLIENT_DEFAULT.equals(clientDO.getClientid())){
            // 创建刷新令牌
            sessionInfo = createOAuth2RefreshToken(userId, clientDO, scopes);
        }else {
            sessionInfo.setCurrentYhuuid(userId);
        }
        // 创建访问令牌
        return createOAuth2AccessToken(sessionInfo, clientDO,null);
    }

    @Override
    public OAuth2AccessTokenDO createAdminAccessToken(String userId, String clientId) {
        OAuth2ClientDO clientDO = oauth2ClientService.validOAuthClientFromCache(clientId);
        final SessionInfo sessionInfo = yhxxService.initAdminInfo(userId);

        OAuth2AccessTokenDO accessTokenDO = new OAuth2AccessTokenDO().setAccessToken(generateAccessToken())
                .setUuid(IdUtil.fastSimpleUUID())
                .setYhUuid(sessionInfo.getCurrentYhuuid())
                .setClientid(clientDO.getClientid())
                .setRefreshToken("")
                .setGqsj(LocalDateTime.now().plusSeconds(Long.parseLong(clientDO.getFwlpyxq())));
        accessTokenDO.setYwqdDm("ZNSB.SSO");
        accessTokenDO.setLrrsfid("ZNSB.SSO");
        accessTokenDO.setXgrsfid("ZNSB.SSO");
        accessTokenDO.setSjcsdq("0000000000");
        accessTokenDO.setSjgsdq("0000000000");
        oauth2AccessTokenMapper.insert(accessTokenDO);

        final AccessTokenInfo accessTokenInfo = new AccessTokenInfo();
        accessTokenInfo.setAccessToken(accessTokenDO.getAccessToken());
        accessTokenInfo.setRefreshToken(accessTokenDO.getRefreshToken());
        accessTokenInfo.setUuid(accessTokenDO.getUuid());
        accessTokenInfo.setYhUuid(accessTokenDO.getYhUuid());
        accessTokenInfo.setQyuuid(accessTokenDO.getQyuuid());
        accessTokenInfo.setGqsj(accessTokenDO.getGqsj());
        accessTokenInfo.setClientid(accessTokenDO.getClientid());
        accessTokenInfo.setSqnr(accessTokenDO.getSqnr());
        accessTokenInfo.setGllp(accessTokenDO.getGllp());
        sessionInfo.setTokenInfo(accessTokenInfo);
        // 记录到 Redis 中
        oauth2AccessTokenRedisDAO.set(sessionInfo);
        return accessTokenDO;

    }

    @Override
    public OAuth2AccessTokenDO createAccessToken(OAuth2CodeDO codeDO, OAuth2ClientDO client) {
        //创建刷新令牌
        final String oAuth2RefreshToken = createOAuth2RefreshToken(codeDO, client);
        //创建访问令牌
        final OAuth2AccessTokenDO accessTokenDO = createOAuth2AccessToken(oAuth2RefreshToken, codeDO, client);
        //更新本系统令牌的关联第三方令牌
        final OAuth2AccessTokenDO tokenDO = oauth2AccessTokenMapper.selectByAccessToken(accessTokenDO.getGllp());
        final String oldGllp = tokenDO.getGllp();
        if (!GyUtils.isNull(oldGllp)){
            oauth2AccessTokenMapper.updateGllp(tokenDO.getUuid(),oldGllp+","+accessTokenDO.getAccessToken());
            tokenDO.setGllp(oldGllp+","+accessTokenDO.getAccessToken());
        }else {
            oauth2AccessTokenMapper.updateGllp(tokenDO.getUuid(),accessTokenDO.getAccessToken());
            tokenDO.setGllp(accessTokenDO.getAccessToken());
        }

        oauth2AccessTokenRedisDAO.updateAccessTokenInfo(tokenDO);

        return accessTokenDO;
    }

    @Override
    public OAuth2AccessTokenDO refreshAccessToken(String refreshToken, String clientId) {
        OAuth2RefreshTokenDO refreshTokenDO = oauth2RefreshTokenMapper.selectByRefreshToken(refreshToken);
        if (refreshTokenDO == null) {
            throw exception0(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), "无效的刷新令牌");
        }

        // 校验 Client 匹配
        OAuth2ClientDO clientDO = oauth2ClientService.validOAuthClientFromCache(clientId);
        if (ObjectUtil.notEqual(clientId, refreshTokenDO.getClientid())) {
            throw exception0(GlobalErrorCodeConstants.BAD_REQUEST.getCode(), "刷新令牌的客户端编号不正确");
        }

        // 移除相关的访问令牌
        List<OAuth2AccessTokenDO> accessTokenDOs = oauth2AccessTokenMapper.selectListByRefreshToken(refreshToken);
        if (CollUtil.isNotEmpty(accessTokenDOs)) {
            oauth2AccessTokenMapper.deleteBatchIds(convertSet(accessTokenDOs, OAuth2AccessTokenDO::getUuid));
            oauth2AccessTokenRedisDAO.deleteList(convertSet(accessTokenDOs, OAuth2AccessTokenDO::getAccessToken));
        }

        // 已过期的情况下，删除刷新令牌
        if (DateUtils.isExpired(refreshTokenDO.getGqsj())) {
            oauth2RefreshTokenMapper.deleteById(refreshTokenDO.getUuid());
            throw exception0(GlobalErrorCodeConstants.UNAUTHORIZED.getCode(), "刷新令牌已过期");
        }
        final OAuth2AccessTokenDO oAuth2AccessTokenDO = accessTokenDOs.stream().max(Comparator.comparing(OAuth2AccessTokenDO::getGqsj)).get();
        final OAuth2AccessTokenDO accessTokenDO = createOAuth2AccessToken(refreshTokenDO, clientDO, oAuth2AccessTokenDO.getGllp());

        //更新本系统令牌的关联第三方令牌
        final OAuth2AccessTokenDO tokenDO = oauth2AccessTokenMapper.selectByAccessToken(oAuth2AccessTokenDO.getGllp());
        final List<String> list = Arrays.asList(tokenDO.getGllp().split(","));
        if (!GyUtils.isNull(list)){
            StringJoiner stringJoiner = new StringJoiner(",");
            final List<String> collect = accessTokenDOs.stream().map(OAuth2AccessTokenDO::getAccessToken).collect(Collectors.toList());
            final List<String> collect1 = list.stream().filter(s -> !collect.contains(s)).collect(Collectors.toList());
            if (!GyUtils.isNull(collect1)) {
                collect1.forEach(stringJoiner::add);
            }
            stringJoiner.add(accessTokenDO.getAccessToken());
            oauth2AccessTokenMapper.updateGllp(tokenDO.getUuid(),stringJoiner.toString());
            tokenDO.setGllp(stringJoiner.toString());
        }else {
            oauth2AccessTokenMapper.updateGllp(tokenDO.getUuid(),"");
            tokenDO.setGllp(accessTokenDO.getAccessToken());
        }
        oauth2AccessTokenRedisDAO.updateAccessTokenInfo(tokenDO);

        return accessTokenDO;
    }

    @Override
    public OAuth2AccessTokenDO getAccessToken(String accessToken) {
        final AccessTokenInfo tokenInfo = oauth2AccessTokenRedisDAO.getTokenInfo(accessToken);
        // 优先从 Redis 中获取
        OAuth2AccessTokenDO accessTokenDO;
        if (tokenInfo != null && tokenInfo.getAccessToken()!=null) {
            return BeanUtils.toBean(tokenInfo,OAuth2AccessTokenDO.class);
        }

        // 获取不到，从 MySQL 中获取
        accessTokenDO = oauth2AccessTokenMapper.selectByAccessToken(accessToken);
        // 如果在 MySQL 存在，则往 Redis 中写入
        if (accessTokenDO != null && !DateUtils.isExpired(accessTokenDO.getGqsj())) {
            final AccessTokenInfo accessTokenInfo = new AccessTokenInfo();
            accessTokenInfo.setAccessToken(accessTokenDO.getAccessToken());
            accessTokenInfo.setRefreshToken(accessTokenDO.getRefreshToken());
            accessTokenInfo.setUuid(accessTokenDO.getUuid());
            accessTokenInfo.setYhUuid(accessTokenDO.getYhUuid());
            accessTokenInfo.setQyuuid(accessTokenDO.getQyuuid());
            accessTokenInfo.setGqsj(accessTokenDO.getGqsj());
            accessTokenInfo.setClientid(accessTokenDO.getClientid());
            accessTokenInfo.setSqnr(accessTokenDO.getSqnr());
            accessTokenInfo.setGllp(accessTokenDO.getGllp());
            final SessionInfo sessionInfo = yhxxService.getSessionInfo(accessTokenDO.getQyuuid(), accessTokenDO.getYhUuid());
            oauth2AccessTokenRedisDAO.set(sessionInfo);
        }
        return accessTokenDO;
    }

    @Transactional
    @Override
    public SessionInfo checkAccessToken(String accessToken) {
        OAuth2AccessTokenDO accessTokenDO = getAccessToken(accessToken);
        if (accessTokenDO == null) {
            throw exception0(GlobalErrorCodeConstants.UNAUTHORIZED.getCode(), "访问令牌不存在");
        }
        if (DateUtils.isExpired(accessTokenDO.getGqsj())) {
            throw exception0(GlobalErrorCodeConstants.UNAUTHORIZED.getCode(), "访问令牌已过期");
        }

        if (SsoConstants.CLIENT_DEFAULT.equals(accessTokenDO.getClientid())){
            final long seconds = Duration.between(LocalDateTime.now(), accessTokenDO.getGqsj()).getSeconds();
            if (seconds > 0 && 10 * 60 > seconds){
                OAuth2ClientDO clientDO = oauth2ClientService.validOAuthClientFromCache(accessTokenDO.getClientid());
                final SessionInfo sessionInfo = yhxxService.getSessionInfo(accessTokenDO.getYhUuid(), accessTokenDO.getQyuuid());
                sessionInfo.setQyuuid(accessTokenDO.getQyuuid());
                sessionInfo.setCurrentYhuuid(accessTokenDO.getYhUuid());
                final OAuth2AccessTokenDO newAccessToken = createOAuth2AccessToken(sessionInfo, clientDO,accessTokenDO.getGllp());
                //刷新第三方令牌关联
                if (!GyUtils.isNull(accessTokenDO.getGllp())){
                    final List<String> list = Arrays.asList(accessTokenDO.getGllp().split(","));
                    oauth2AccessTokenMapper.updateGllpByTokens(list,newAccessToken.getAccessToken());
                }
                return oauth2AccessTokenRedisDAO.getSessionInfo(newAccessToken.getAccessToken());
            }
        }else {
            //第三方令牌会话信息取关联令牌
            return oauth2AccessTokenRedisDAO.getSessionInfo(accessTokenDO.getGllp());
        }

        return oauth2AccessTokenRedisDAO.getSessionInfo(accessToken);
    }

    @Override
    public AccessTokenInfo checkThirdPartyToken(String accessToken) {
        OAuth2AccessTokenDO accessTokenDO = getAccessToken(accessToken);
        if (accessTokenDO == null) {
            throw exception0(GlobalErrorCodeConstants.UNAUTHORIZED.getCode(), "访问令牌不存在");
        }
        if (DateUtils.isExpired(accessTokenDO.getGqsj())) {
            throw exception0(GlobalErrorCodeConstants.UNAUTHORIZED.getCode(), "访问令牌已过期");
        }

        return oauth2AccessTokenRedisDAO.getTokenInfo(accessToken);
    }

    @Transactional
    @Override
    public OAuth2AccessTokenDO removeAccessToken(String clientId,String accessToken) {
        // 删除访问令牌
        OAuth2AccessTokenDO accessTokenDO = oauth2AccessTokenMapper.selectByAccessToken(accessToken);
        if (SsoConstants.CLIENT_DEFAULT.equals(clientId)){
            if (accessTokenDO == null) {
                return null;
            }
            final String gllp = accessTokenDO.getGllp();
            if (!GyUtils.isNull(gllp)){
                final List<String> list = Arrays.asList(gllp.split(","));
                final List<OAuth2AccessTokenDO> oAuth2AccessTokenDOS = oauth2AccessTokenMapper.selectRefreshTokenByAccessTokens(list);
                if (!GyUtils.isNull(oAuth2AccessTokenDOS)){
                    final List<String> collect = oAuth2AccessTokenDOS.stream().map(OAuth2AccessTokenDO::getRefreshToken).collect(Collectors.toList());
                    oauth2RefreshTokenMapper.deleteByTokens(collect);
                }
                oauth2AccessTokenMapper.deleteByTokens(list);
                oauth2AccessTokenRedisDAO.deleteList(list);
            }
            oauth2AccessTokenMapper.deleteById(accessTokenDO.getUuid());
            oauth2AccessTokenRedisDAO.delete(accessToken);
            // 删除刷新令牌
            oauth2RefreshTokenMapper.deleteByRefreshToken(accessTokenDO.getRefreshToken());
        }else {
            if (accessTokenDO == null) {
                return null;
            }
            final String gllp = accessTokenDO.getGllp();
            //更新本系统令牌的关联第三方令牌
            final OAuth2AccessTokenDO tokenDO = oauth2AccessTokenMapper.selectByAccessToken(gllp);
            final List<String> list = Arrays.asList(tokenDO.getGllp().split(","));
            final List<String> collect = list.stream().filter(s -> !s.equals(accessTokenDO.getAccessToken())).collect(Collectors.toList());
            if (!GyUtils.isNull(collect)){
                StringJoiner stringJoiner = new StringJoiner(",");
                collect.forEach(stringJoiner::add);
                oauth2AccessTokenMapper.updateGllp(tokenDO.getUuid(),stringJoiner.toString());
                tokenDO.setGllp(stringJoiner.toString());
            }else {
                oauth2AccessTokenMapper.updateGllp(tokenDO.getUuid(),"");
                tokenDO.setGllp("");
            }
            oauth2AccessTokenRedisDAO.updateAccessTokenInfo(tokenDO);

            oauth2AccessTokenMapper.deleteById(accessTokenDO.getUuid());
            oauth2AccessTokenRedisDAO.delete(accessToken);
            // 删除刷新令牌
            oauth2RefreshTokenMapper.deleteByRefreshToken(accessTokenDO.getRefreshToken());
        }

        return accessTokenDO;
    }

    @Override
    public List<OAuth2AccessTokenDO> removeAccessToken(String accessToken) {
        List<OAuth2AccessTokenDO> result = new ArrayList<>();
        OAuth2AccessTokenDO accessTokenDO = oauth2AccessTokenMapper.selectByAccessToken(accessToken);
        if (accessTokenDO == null) {
            return null;
        }
        final String gllp = accessTokenDO.getGllp();
        if (!GyUtils.isNull(gllp)){
            final List<String> list = Arrays.asList(gllp.split(","));
            final List<OAuth2AccessTokenDO> oAuth2AccessTokenDOS = oauth2AccessTokenMapper.selectRefreshTokenByAccessTokens(list);
            result.addAll(oAuth2AccessTokenDOS);
            if (!GyUtils.isNull(oAuth2AccessTokenDOS)){
                final List<String> collect = oAuth2AccessTokenDOS.stream().map(OAuth2AccessTokenDO::getRefreshToken).collect(Collectors.toList());
                oauth2RefreshTokenMapper.deleteByTokens(collect);
            }
            oauth2AccessTokenMapper.deleteByTokens(list);
            oauth2AccessTokenRedisDAO.deleteList(list);
        }
        oauth2AccessTokenMapper.deleteById(accessTokenDO.getUuid());
        oauth2AccessTokenRedisDAO.delete(accessToken);
        // 删除刷新令牌
        oauth2RefreshTokenMapper.deleteByRefreshToken(accessTokenDO.getRefreshToken());

        return result;
    }

    private OAuth2AccessTokenDO createOAuth2AccessToken(SessionInfo sessionInfo, OAuth2ClientDO clientDO, String gllp) {

        String refreshToken = "";
        if (GyUtils.isNull(sessionInfo.getTokenInfo())){
            sessionInfo = yhxxService.initYhxx(sessionInfo.getCurrentYhuuid());
        }else {
            refreshToken = sessionInfo.getTokenInfo().getRefreshToken();
        }
        OAuth2AccessTokenDO accessTokenDO = new OAuth2AccessTokenDO().setAccessToken(generateAccessToken())
                .setUuid(IdUtil.fastSimpleUUID())
                .setYhUuid(sessionInfo.getCurrentYhuuid())
                .setClientid(clientDO.getClientid())
                .setRefreshToken(refreshToken)
                .setGqsj(LocalDateTime.now().plusSeconds(Long.parseLong(clientDO.getFwlpyxq())))
                .setGllp(gllp);
        accessTokenDO.setYwqdDm("SSO");
        accessTokenDO.setLrrsfid("SSO");
        accessTokenDO.setXgrsfid("SSO");
        accessTokenDO.setSjcsdq("0000000000");
        accessTokenDO.setSjgsdq("0000000000");
        oauth2AccessTokenMapper.insert(accessTokenDO);

        final AccessTokenInfo accessTokenInfo = new AccessTokenInfo();
        accessTokenInfo.setAccessToken(accessTokenDO.getAccessToken());
        accessTokenInfo.setRefreshToken(accessTokenDO.getRefreshToken());
        accessTokenInfo.setUuid(accessTokenDO.getUuid());
        accessTokenInfo.setYhUuid(accessTokenDO.getYhUuid());
        accessTokenInfo.setQyuuid(accessTokenDO.getQyuuid());
        accessTokenInfo.setGqsj(accessTokenDO.getGqsj());
        accessTokenInfo.setClientid(accessTokenDO.getClientid());
        accessTokenInfo.setSqnr(accessTokenDO.getSqnr());
        accessTokenInfo.setGllp(accessTokenDO.getGllp());
        sessionInfo.setTokenInfo(accessTokenInfo);
        // 记录到 Redis 中
        oauth2AccessTokenRedisDAO.set(sessionInfo);
        return accessTokenDO;
    }



    private SessionInfo createOAuth2RefreshToken(String userId, OAuth2ClientDO clientDO, List<String> scopes) {
        final SessionInfo sessionInfo = yhxxService.initYhxx(userId);

        OAuth2RefreshTokenDO refreshToken = new OAuth2RefreshTokenDO().setRefreshToken(generateRefreshToken())
                .setUuid(IdUtil.fastSimpleUUID())
                .setYhUuid(userId)
                .setQyuuid(sessionInfo.getQyuuid())
                .setClientid(clientDO.getClientid())
                .setGqsj(LocalDateTime.now().plusSeconds(Long.parseLong(clientDO.getSxlpyxq())));
        refreshToken.setYwqdDm("SSO");
        refreshToken.setLrrsfid("SSO");
        refreshToken.setXgrsfid("SSO");
        refreshToken.setSjcsdq("0000000000");
        refreshToken.setSjgsdq("0000000000");
        oauth2RefreshTokenMapper.insert(refreshToken);

        final AccessTokenInfo accessTokenInfo = new AccessTokenInfo();
        accessTokenInfo.setRefreshToken(refreshToken.getRefreshToken());
        accessTokenInfo.setYhUuid(refreshToken.getYhUuid());
        sessionInfo.setTokenInfo(accessTokenInfo);
        return sessionInfo;
    }

    private String createOAuth2RefreshToken(OAuth2CodeDO codeDO,OAuth2ClientDO client) {
        OAuth2RefreshTokenDO refreshToken = new OAuth2RefreshTokenDO().setRefreshToken(generateRefreshToken())
                .setUuid(IdUtil.fastSimpleUUID())
                .setYhUuid(codeDO.getYhUuid())
                .setClientid(client.getClientid())
                .setGqsj(LocalDateTime.now().plusSeconds(Long.parseLong(client.getSxlpyxq())));
        refreshToken.setYwqdDm("ZNSB.SSO");
        refreshToken.setLrrsfid("ZNSB.SSO");
        refreshToken.setXgrsfid("ZNSB.SSO");
        refreshToken.setSjcsdq("0000000000");
        refreshToken.setSjgsdq("0000000000");
        oauth2RefreshTokenMapper.insert(refreshToken);
        return refreshToken.getRefreshToken();
    }

    private OAuth2AccessTokenDO createOAuth2AccessToken(String refreshToken,OAuth2CodeDO codeDO, OAuth2ClientDO clientDO) {
        OAuth2AccessTokenDO accessTokenDO = new OAuth2AccessTokenDO().setAccessToken(generateAccessToken())
                .setUuid(IdUtil.fastSimpleUUID())
                .setYhUuid(codeDO.getYhUuid())
                .setClientid(clientDO.getClientid())
                .setRefreshToken(refreshToken)
                .setGqsj(LocalDateTime.now().plusSeconds(Long.parseLong(clientDO.getFwlpyxq())))
                .setGllp(codeDO.getAccessToken());
        accessTokenDO.setYwqdDm("ZNSB.SSO");
        accessTokenDO.setLrrsfid("ZNSB.SSO");
        accessTokenDO.setXgrsfid("ZNSB.SSO");
        accessTokenDO.setSjcsdq("0000000000");
        accessTokenDO.setSjgsdq("0000000000");
        oauth2AccessTokenMapper.insert(accessTokenDO);

        final AccessTokenInfo thirdPartyTokenInfo = new AccessTokenInfo();
        thirdPartyTokenInfo.setAccessToken(accessTokenDO.getAccessToken());
        thirdPartyTokenInfo.setRefreshToken(accessTokenDO.getRefreshToken());
        thirdPartyTokenInfo.setUuid(accessTokenDO.getUuid());
        thirdPartyTokenInfo.setGqsj(accessTokenDO.getGqsj());
        thirdPartyTokenInfo.setClientid(accessTokenDO.getClientid());
        thirdPartyTokenInfo.setGllp(codeDO.getAccessToken());

        // 记录到 Redis 中
        oauth2AccessTokenRedisDAO.set(thirdPartyTokenInfo);
        return accessTokenDO;
    }

    private OAuth2AccessTokenDO createOAuth2AccessToken(OAuth2RefreshTokenDO refreshTokenDO, OAuth2ClientDO clientDO,String gllp) {
        OAuth2AccessTokenDO accessTokenDO = new OAuth2AccessTokenDO().setAccessToken(generateAccessToken())
                .setUuid(IdUtil.fastSimpleUUID())
                .setYhUuid(refreshTokenDO.getYhUuid())
                .setClientid(clientDO.getClientid())
                .setRefreshToken(refreshTokenDO.getRefreshToken())
                .setGqsj(LocalDateTime.now().plusSeconds(Long.parseLong(clientDO.getFwlpyxq())))
                .setGllp(gllp);
        accessTokenDO.setYwqdDm("ZNSB.SSO");
        accessTokenDO.setLrrsfid("ZNSB.SSO");
        accessTokenDO.setXgrsfid("ZNSB.SSO");
        accessTokenDO.setSjcsdq("0000000000");
        accessTokenDO.setSjgsdq("0000000000");
        oauth2AccessTokenMapper.insert(accessTokenDO);

        final AccessTokenInfo thirdPartyTokenInfo = new AccessTokenInfo();
        thirdPartyTokenInfo.setAccessToken(accessTokenDO.getAccessToken());
        thirdPartyTokenInfo.setRefreshToken(accessTokenDO.getRefreshToken());
        thirdPartyTokenInfo.setUuid(accessTokenDO.getUuid());
        thirdPartyTokenInfo.setGqsj(accessTokenDO.getGqsj());
        thirdPartyTokenInfo.setClientid(accessTokenDO.getClientid());
        thirdPartyTokenInfo.setGllp(gllp);

        // 记录到 Redis 中
        oauth2AccessTokenRedisDAO.set(thirdPartyTokenInfo);
        return accessTokenDO;
    }

    private static String generateAccessToken() {
        return IdUtil.fastSimpleUUID();
    }

    private static String generateRefreshToken() {
        return IdUtil.fastSimpleUUID();
    }

}
