package com.cyksj.web.controller.user;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.EnvCommonService;
import com.cyksj.common.annotation.NoSubmit;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.common.snowflake.Sequence;
import com.cyksj.common.util.*;
import com.cyksj.config.WeChatConfig;
import com.cyksj.config.wxlogin.BaseWxOpenPlatConfig;
import com.cyksj.config.wxlogin.WxOpenPlatEnum;
import com.cyksj.config.wxlogin.WxOpenPlatFactory;
import com.cyksj.config.wxlogin.WxOpenPlatYHLXLoginConfig;
import com.cyksj.dto.Result;
import com.cyksj.enums.GatewayResponse;
import com.cyksj.mapper.PhoneCodeMapper;
import com.cyksj.model.dto.*;
import com.cyksj.model.entity.PhoneCode;
import com.cyksj.model.entity.User;
import com.cyksj.model.request.LoginReq;
import com.cyksj.model.response.GoogleLoginRep;
import com.cyksj.model.response.UserAuthLoginResp;
import com.cyksj.model.response.WxGzhQrCodeTicketRep;
import com.cyksj.redis.RedisService;
import com.cyksj.service.authorization.AuthorizationService;
import com.cyksj.service.mail.MailService;
import com.cyksj.service.template.TemplateCommonService;
import com.cyksj.service.user.BadIntentionOpService;
import com.cyksj.service.user.UserCommonService;
import com.cyksj.service.user.UserService;
import com.cyksj.service.wechat.WeChatService;
import com.cyksj.web.util.StpUserUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

/**
 * @author chan
 * @className AuthorizationController
 * @description 授权网关
 * @date 2021/10/08 11:51 上午
 */
@Slf4j
@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
public class AuthorizationController {

    private final static Sequence SEQUENCE = new Sequence(0);

    private final HttpServletRequest request;

    private final AuthorizationService authorizationService;

    private final UserService userService;

    private final UserCommonService userCommonService;

    private final WeChatService weChatService;

    private final WeChatConfig weChatConfig;

    private final RedisService redisService;

    private final BadIntentionOpService badIntentionOpService;

    private final WxOpenPlatYHLXLoginConfig wxOpenPlatYHLXLoginConfig;

    private final EnvCommonService envCommonService;

    private final PhoneCodeMapper phoneCodeMapper;

    private final MailService mailService;

    private final TemplateCommonService templateCommonService;

    @GetMapping(value = "/weChat")
    public void base(String url, String dsCode, Long sharedId, Integer dsType, Long popularizeId, String authType, String callbackType, String callback, String customId, Integer cst, Integer cmt, Boolean cgTj, Boolean isNano, HttpServletResponse response) throws Exception {
        log.info("微信授权转跳. url: {},authType:{}", url, authType);
        if (StrUtil.isBlank(url)) {
            url = "https://nf.video/";
        }

        // 无论是否为老用户 均转跳到授权页面
        // 若授权过 则无需再次授权 直接回调 /user/wechat/redirect
        // 新用户同意授权后 也会回调 /user/wechat/redirect

        Long mappingId = SEQUENCE.nextId();
        redisService.set(mappingId.toString(), url, 60 * 60 * 24L);
        if (StrUtil.isNotBlank(dsCode)) {
            dsCode = dsCode.trim();
        }
        AuthRedirect redirect = new AuthRedirect().setMappingId(mappingId).setSharedId(sharedId).setDsType(dsType).setPid(popularizeId).setDsCode(dsCode)
                .setCd(customId)
                .setCk(callback)
                .setCt(callbackType)
                .setCst(cst)
                .setCgTj(cgTj)
                .setIsNano(isNano)
                .setCmt(cmt);
        String state = Codec.DoBase64.custom().setData(Jsons.toJson(redirect)).encodeAsText();

        response.sendRedirect(authorizationService.createUrl(url, state, authType));

    }


    /**
     * 全量授权
     *
     * @author chan
     * @date 2021-10-11 上午11:57
     */
    @GetMapping(value = "/weChat/baseRedirect")
    public void redirect(String code, String state, HttpServletResponse response) throws Exception {
        String json = Codec.DoBase64.custom().setData(state).decodeAsText();
        AuthRedirect re = Jsons.parseObject(json, AuthRedirect.class);
        AuthToken token = weChatService.getAuthToken(code, weChatConfig.getAppid());

        baseRedirect(token, re, User.RegisterEnv.wx, response);
    }

    /**
     * 静默授权
     *
     * @author chan
     * @date 2021-10-11 上午11:58
     */
    @GetMapping("/weChat/silentRedirect")
    @Transactional(rollbackFor = Throwable.class)
    public void redirectV2(String code, String state, HttpServletResponse response) throws Exception {

        // 转跳参数
        String json = Codec.DoBase64.custom().setData(state).decodeAsText();
        AuthRedirect re = Jsons.parseObject(json, AuthRedirect.class);

        AuthToken token = weChatService.getAuthToken(code, weChatConfig.getAppid());

        //  查询用户期望转跳的url
        String url = redisService.getStr(re.getMappingId().toString());
        String data = Codec.DoBase64.custom().setData(token.getOpenid()).encodeAsText();

        Cookie cookie = new Cookie("openKey", data);
        cookie.setMaxAge(31536000);
        cookie.setPath("/");
        response.addCookie(cookie);

        log.info("微信授权转跳. url: {}", url);
        response.sendRedirect(url);

    }

    /**
     * 全量授权
     *
     * @author chan
     * @date 2021-10-11 上午11:57
     */
    @GetMapping(value = "/weChat/baseRedirect/other")
    public void redirectOther(String code, String state, HttpServletResponse response) throws Exception {
        // 转跳参数
        String json = Codec.DoBase64.custom().setData(state).decodeAsText();
        AuthRedirect re = Jsons.parseObject(json, AuthRedirect.class);


        //  查询用户期望转跳的url
        String url = redisService.getStr(re.getMappingId().toString());
        String requestUrl = request.getRequestURL().toString();
        log.info("非主域名授权请求地址:{}", requestUrl);

        log.info("微信非主域名授权转跳. url: {}", url);
        String path = URLUtil.getPath(weChatConfig.getNotifyDomain());
        response.sendRedirect(URLUtil.getHost(new URL(url)).toString()  + path + "auth/weChat/baseRedirect" + "?code=" + code + "&state=" + state);
    }

    /**
     * 静默授权
     *
     * @author chan
     * @date 2021-10-11 上午11:58
     */
    @GetMapping("/weChat/silentRedirect/other")
    @Transactional(rollbackFor = Throwable.class)
    public void redirectV2Other(String code, String state, HttpServletResponse response) throws Exception {
        // 转跳参数
        String json = Codec.DoBase64.custom().setData(state).decodeAsText();
        AuthRedirect re = Jsons.parseObject(json, AuthRedirect.class);


        //  查询用户期望转跳的url
        String url = redisService.getStr(re.getMappingId().toString());
        String requestUrl = request.getRequestURL().toString();
        log.info("非主域名授权请求地址:{}", requestUrl);

        log.info("微信非主域名授权转跳. url: {}", url);
        String path = URLUtil.getPath(weChatConfig.getNotifyDomain());

        response.sendRedirect(URLUtil.getHost(new URL(url)).toString()  + path + "auth/weChat/silentRedirect" + "?code=" + code + "&state=" + state);
    }


    /**
     * 微信js-sdk 权限验证
     */
    @RequestMapping(value = "/jsTicket", method = RequestMethod.GET)
    public Result<JsSdkTicket> ticket(String appId, String url) throws Exception {
        if (StringUtils.isBlank(url)) {
            throw BusinessRuntimeException.getInstance("请输入授权网址.");
        }
        return GatewayResponse.SUCCESS.newBuilder().toResult(authorizationService.getJsTicket(Optional.ofNullable(appId).orElse(weChatConfig.getAppid()), url));

    }

    //public Result<String> login(String phone, String code){
    //
    //    //
    //    ////保存用户信息
    //    //User user = userService.saveAuth(userinfo);
    //    //
    //    //
    //    ////写回登陆信息
    //    //StpUserUtil.login(user.getId());
    //    //response.addHeader("satoken",StpUserUtil.getTokenValue());
    //    //
    //    //Cookie cookie = new Cookie("satoken",StpUserUtil.getTokenValue());
    //    //cookie.setMaxAge(31536000);
    //    //cookie.setPath("/");
    //    //response.addCookie(cookie);
    //    //JSONObject jsonObject = new JSONObject();
    //    //jsonObject.putOpt("uid",user.getId());
    //    //jsonObject.putOpt("nickName",user.getNickname());
    //    //
    //    //Cookie userInfo = new Cookie("info",Base64.encode(jsonObject.toString()));
    //    //cookie.setMaxAge(31536000);
    //    //cookie.setPath("/");
    //    //response.addCookie(userInfo);
    //    //
    //    //String url = redisService.getStr(re.getMappingId().toString());
    //    //redisService.del(re.getMappingId().toString());
    //    //log.info("微信授权转跳.url: {}",url);
    //    //response.sendRedirect(url);
    //
    //}


    /**
     * 网页微信授权登录
     */
    @GetMapping("/wx/authLogin")
    public Result<String> wxAuthorize(Long sharedId, Integer dsType, Long popularizeId, String dsCode, String type, String callbackType, String callback, String returnUrl, String customId, Integer cmt) throws Exception {
        Long mappingId = SEQUENCE.nextId();
        String loginUrl = Optional.ofNullable(returnUrl).orElse(wxOpenPlatYHLXLoginConfig.getLoginUrl());
        log.info("网页微信授权成功返回地址:{}", loginUrl);
        if (StrUtil.isNotBlank(type)) {
            loginUrl = String.format("https://nf.video/%s/web", type);
        }
        redisService.set(mappingId.toString(), loginUrl, 60 * 60 * 24L);
        if (StrUtil.isNotBlank(dsCode)) {
            dsCode = dsCode.trim();
        }
        AuthRedirect redirect = new AuthRedirect().setMappingId(mappingId).setSharedId(sharedId).setDsType(dsType).setPid(popularizeId).setDsCode(dsCode)
                .setCk(callback)
                .setCt(callbackType)
                .setCd(customId)
                .setCmt(cmt);
        String state = Codec.DoBase64.custom().setData(Jsons.toJson(redirect)).encodeAsText();
        String wxAuthUrl = authorizationService.createWxAuthLoginUrl(state, wxOpenPlatYHLXLoginConfig.getAppId(), wxOpenPlatYHLXLoginConfig.getRedirectUri());
        return GatewayResponse.SUCCESS.newBuilder().toResult(wxAuthUrl);
    }

    /**
     * 微信网页统一授权登录
     */
    @GetMapping("/wx/unified/login")
    @Deprecated
    public Result<String> wxUnifiedLogin(Long sharedId, Integer dsType, Long popularizeId, String dsCode, String type, String callbackType, String callback, String wt, String customId) throws Exception {
        if (StrUtil.isEmpty(wt)) {
            return GatewayResponse.SUCCESS.newBuilder().toResult();
        }
        WxOpenPlatEnum wxOpenPlatEnum = WxOpenPlatEnum.valueOf(wt);
        if (wxOpenPlatEnum == null) {
            return GatewayResponse.SUCCESS.newBuilder().toResult();
        }
        BaseWxOpenPlatConfig wxApp = WxOpenPlatFactory.getWeChatConfigStrategy(wxOpenPlatEnum.getAppId());

        Long mappingId = SEQUENCE.nextId();
        String loginUrl = wxApp.getLoginUrl();
        redisService.set(mappingId.toString(), loginUrl, 60 * 60 * 24L);
        if (StrUtil.isNotBlank(dsCode)) {
            dsCode = dsCode.trim();
        }
        AuthRedirect redirect = new AuthRedirect().setMappingId(mappingId).setSharedId(sharedId).setDsType(dsType).setPid(popularizeId).setDsCode(dsCode)
                .setCk(callback)
                .setCd(customId)
                .setCt(callbackType);
        String state = Codec.DoBase64.custom().setData(Jsons.toJson(redirect)).encodeAsText();
        String wxAuthUrl = authorizationService.createWxAuthLoginUrl(state, wxApp.getAppId(), wxApp.getRedirectUri());
        return GatewayResponse.SUCCESS.newBuilder().toResult(wxAuthUrl);
    }

    /**
     * 网页微信授权后统一跳转
     */
    @GetMapping("/wx/unified/baseRedirect")
    @Deprecated
    public void wxUnifiedRedirect(String code, String state, HttpServletResponse response) throws Exception {
        // 转跳参数
        String json = Codec.DoBase64.custom().setData(state).decodeAsText();
        AuthRedirect re = Jsons.parseObject(json, AuthRedirect.class);
        AuthToken token = weChatService.getAuthToken(code, re.getAp());
        //重定向
        baseRedirect(token, re, User.RegisterEnv.pc, response);
    }

    /**
     * 网页微信授权后跳转
     */
    @GetMapping("/wx/authLogin/baseRedirect")
    public void wxAuthLoginRedirect(String code, String state, HttpServletResponse response) throws Exception {
        String json = Codec.DoBase64.custom().setData(state).decodeAsText();
        AuthRedirect re = Jsons.parseObject(json, AuthRedirect.class);
        AuthToken token = weChatService.getAuthToken(code, wxOpenPlatYHLXLoginConfig.getAppId());
        //重定向
        baseRedirect(token, re, User.RegisterEnv.pc, response);
    }

    /**
     * 网页扫描微信公众号二维码 临时凭证ticket  关注后登录
     */
    @GetMapping("/wx/gzh/login/qrCode")
    public Result<WxGzhQrCodeTicketRep> getWxGzhQrCode(Long sharedId, Integer dsType, Long popularizeId, String dsCode, String callbackType, String callback, String customId, Integer cmt, Boolean cgTj, Boolean isNano) throws Exception {
        //获取gzh带参数的二维码
        GzhBodyDto gzhBodyDto = new GzhBodyDto().setSharedId(sharedId).setDsType(dsType).setPid(popularizeId).setDsCode(dsCode)
                .setCk(callback)
                .setCt(callbackType)
                .setCd(customId)
                .setCmt(cmt)
                .setCgTj(cgTj)
                .setIsNano(isNano);
        WxGzhQrCodeTicketRep result = weChatService.getWxGzhQrCode(gzhBodyDto);
        return GatewayResponse.SUCCESS.newBuilder().toResult(result);
    }

    /**
     * pc端公众号二维码绑定微信账号信息
     */
    @GetMapping("/wx/gzh/qrCode")
    public Result<WxGzhQrCodeTicketRep> getWxGzhBindQrcode(String loginPhone) throws Exception {
        GzhBodyDto gzhBodyDto = new GzhBodyDto().setLoginPhone(loginPhone);
        WxGzhQrCodeTicketRep result = weChatService.getWxGzhQrCode(gzhBodyDto);
        return GatewayResponse.SUCCESS.newBuilder().toResult(result);
    }

    /**
     * 根据公众号的场景值是否 已经扫码了公众号二维码
     */
    @GetMapping("/wx/gzh/sceneStr/checkQrCode")
    public Result<String> checkQrCodeByGzhSceneStr(String sceneStr) throws Exception {
        String key = RedisService.key.WX_GZH_QRCODE_LOGIN.getNameFormat(sceneStr);
        Object value = redisService.get(key);
        if (value == null) {
            return GatewayResponse.SUCCESS.newBuilder().setMsg("用户未扫码").toResult();
        }
        WxUserSceneDto wxUserSceneDto = Jsons.parseObject(value.toString(), WxUserSceneDto.class);
        Long userId = wxUserSceneDto.getUserId();
        redisService.del(key);
        User user = userService.getById(userId);
        if (StrUtil.isEmpty(user.getRegisterEnv())) {
            user.setRegisterEnv(User.RegisterEnv.pc.name());
            userService.updateById(user);
        }
        StpUserUtil.login(userId);
        String token = StpUserUtil.getTokenValue();
        if (StrUtil.isEmpty(user.getShowId())) {
            user.setShowId(userCommonService.getUserShowId(userId));
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.putOpt("saToken", token);
        jsonObject.putOpt("showId", user.getShowId());
        jsonObject.putOpt("nickname", user.getNickname());
        jsonObject.putOpt("headimgurl", user.getHeadimgurl());

        //发送模板消息
        user.setOpenId(wxUserSceneDto.getOpenId());
        templateCommonService.sendWxGzhQrCodeSuccessMsg(user);
        return GatewayResponse.SUCCESS.newBuilder().toResult(jsonObject.toString());
    }

    /**
     * pc用户是否 已通过二维码 扫码关注公众号
     */
    @GetMapping("/wx/gzh/subscribe")
    public Result<Boolean> isSubscribeWxGzh(String sceneStr) {
        String key = RedisService.key.WX_GZH_QRCODE_BIND.getNameFormat(sceneStr);
        Object value = redisService.get(key);
        if (value == null) {
            return GatewayResponse.SUCCESS.newBuilder().toResult(false);
        }
        return GatewayResponse.SUCCESS.newBuilder().toResult(true);
    }

    /**
     * 网页微信用户登录授权后，重定向至web端
     */
    @GetMapping("/wx/login/redirect")
    public void wxLoginRedirect(String code, String state, HttpServletResponse response) throws Exception {
        String domain = envCommonService.getNotifyHost();
        String url = String.format("%sweChat/baseRedirect?code=%s&state=%s", domain, code, state);
        response.sendRedirect(url);
    }

    /**
     * 获取手机验证码
     */
    @GetMapping("/get/phone/code")
    @NoSubmit
    public Result<String> getPhoneCode(String phone, Integer digit, @RequestParam(defaultValue = "0") Boolean isFree, Integer cid, String verifyCode, String ticket,String randStr) throws Exception {
        if (cid == null) cid = 86;
        if (StrUtil.isBlank(phone) || (86 == cid && !Validator.isMobile(phone))) {
            throw BusinessRuntimeException.getInstance("请输入正确的手机号");
        }
        //是否是虚拟手机号开头
        if (BlackOpsUtil.phoneIsStart(phone)) {
            throw BusinessRuntimeException.getInstance("请输入正确的手机号");
        }
        Object exists = redisService.get(RedisService.key.PHONE_CODE_KEY.getName() + phone);
        if (exists != null) {
            throw BusinessRuntimeException.getInstance("短信验证码未失效");
        }
        //是否是恶意用户
        badIntentionOpService.checkHandleBadUserOp(phone, verifyCode, ticket, randStr, request);
        String code = StringUtil.getRandomCodeStr(digit);
        Boolean isFlag;
        if (!isFree) {
            isFlag = SmsUtil.sendTencent(cid, phone, code);
        } else {
            // 发送短信
            isFlag = SmsUtil.sendLuoKey2Msg(phone, String.format("尊敬的用户，您的验证码为%s，此验证码仅用于银河录像。【崇宇信息】", code));
        }
        if (!isFlag) {
            return GatewayResponse.SUCCESS.newBuilder().toResult("发送短信验证码失败");
        }
        redisService.setNx(RedisService.key.PHONE_CODE_KEY.getName() + phone, phone, RedisService.key.PHONE_CODE_KEY.getTimeout());
        try {
            PhoneCode phoneCode = phoneCodeMapper.selectOne(Wrappers.lambdaQuery(PhoneCode.class).eq(PhoneCode::getPhone, phone).last("limit 1"));
            if (phoneCode == null) {
                phoneCode = new PhoneCode();
                phoneCode.setPhone(phone);
            }
            phoneCode.setCode(code);
            if (phoneCode.getId() == null) {
                phoneCode.setCid(cid);
                phoneCodeMapper.insert(phoneCode);
            } else {
                phoneCodeMapper.updateById(phoneCode);
            }
        } catch (DuplicateKeyException e) {
        }
        return GatewayResponse.SUCCESS.newBuilder().toResult(
                "发送成功");
    }

    /**
     * 发放邮箱验证码
     */
    @GetMapping("/get/email/code")
    @NoSubmit
    public Result<String> getEmailCode(String email, Integer digit, Integer cmt) {
        if (email == null || !Validator.isEmail(email)) {
            throw BusinessRuntimeException.getInstance("请输入正确邮箱");
        }
        if (envCommonService.isPrdEnv()) {
            //首次注册只能gmail邮箱
            if (!email.contains("@gmail")) {
                if (cmt == null || cmt != 2) {
                    User user = userService.getOne(Wrappers.lambdaQuery(User.class).eq(User::getEmail, email).last("limit 1"));
                    if (user == null) {
                        throw BusinessRuntimeException.getInstance("暂只支持使用谷歌邮箱注册");
                    }
                }
            }
        }
        Object exists = redisService.get(RedisService.key.EMAIL_CODE_KEY.getNameFormat(email));
        if (exists != null) {
            throw BusinessRuntimeException.getInstance("验证码未失效");
        }
        String code = mailService.sendLoginCodeEmailToPeople(digit, email);
        if (code == null) {
            throw BusinessRuntimeException.getInstance("获取邮箱验证码错误");
        }
        return GatewayResponse.SUCCESS.newBuilder().toResult("发送成功");
    }

    /**
     * 手机号、邮箱验证码授权登录
     */
    @PostMapping("/login/phone")
    @NoSubmit
    public Result<UserAuthLoginResp> loginByPhone(@RequestBody LoginReq loginReq) throws Exception {
        User user = userService.webLogin(loginReq, request);
        Optional.ofNullable(user.getIsBlack())
                .ifPresent(black -> {
                    if (black) {
                        throw BusinessRuntimeException.getInstance("您的账号已被注销...");
                    }
                });
        //写回登陆信息
        StpUserUtil.login(user.getId());
        UserAuthLoginResp loginPhoneRep = new UserAuthLoginResp(StpUserUtil.getTokenValue(), user.getShowId(), user.getNickname(), user.getHeadimgurl());
        if (loginReq.getPhone() != null) {
            redisService.del(RedisService.key.PHONE_CODE_KEY.getName() + loginReq.getPhone());
        }
        return GatewayResponse.SUCCESS.newBuilder().toResult(loginPhoneRep);
    }

    public void baseRedirect(AuthToken token, AuthRedirect re, User.RegisterEnv registerEnv, HttpServletResponse response) throws Exception {
        // 根据openid 与 access_token 获取用户信息
        GzhOAuth2UserInfo userinfo = weChatService.getUserInfo(token.getAccessToken(), token.getOpenid());

        //保存用户信息
        User user = userService.saveAuth(userinfo, re, registerEnv);
        if (user == null) {
            throw BusinessRuntimeException.getInstance("系统错误,请重新授权");
        }

        Optional.ofNullable(user.getIsBlack())
                .ifPresent(black -> {
                    if (black) {
                        throw BusinessRuntimeException.getInstance("您的账号已被注销...");
                    }
                });

        //写回登陆信息
        StpUserUtil.login(user.getId());
        response.addHeader("satoken-user", StpUserUtil.getTokenValue());

        Cookie cookie = new Cookie("satoken-user", StpUserUtil.getTokenValue());
        cookie.setMaxAge(31536000);
        cookie.setPath("/");
        response.addCookie(cookie);
        JSONObject jsonObject = new JSONObject();
        if (StrUtil.isEmpty(user.getShowId())) {
            user.setShowId(userCommonService.getUserShowId(user.getId()));
        }
        jsonObject.putOpt("showId", user.getShowId());
        jsonObject.putOpt("nickName", user.getNickname());

        Cookie userInfo = new Cookie("info", Base64.encode(jsonObject.toString()));
        cookie.setMaxAge(31536000);
        cookie.setPath("/");
        response.addCookie(userInfo);
        String url = redisService.getStr(re.getMappingId().toString());
        log.info("授权成功跳转地址:{}", url);
        //获客助手 加粉深度回传拼接广告标识.
        try {
            url = appendCorpAcquistion(userinfo, url);
        }catch (Exception e){
            log.error("获客助手 加粉深度回传拼接广告标识 拼接异常 error:{}", StringUtil.getErrorText(e));
        }

        log.info("微信授权转跳.url: {}", url);
        if (registerEnv == User.RegisterEnv.pc) {
            response.sendRedirect(url.contains("?") ? url + "&t=" + StpUserUtil.getTokenValue() : url + "?t=" + StpUserUtil.getTokenValue());
            return;
        }
        response.sendRedirect(url);
    }

    @PostMapping("/google/login")
    public Result<UserAuthLoginResp> googleLogin(LoginReq loginReq,String credential) throws Exception {
        log.info("google loginReq:{},credential:{}", loginReq, credential);
        String result = HttpUtil.post("https://galaxyva.com/8081/api/auth/google/login/inner?credential=" + credential, new HashMap<>());
        log.info("google result:{}",result);
        GoogleLoginRep googleLoginRep = Jsons.parseObject(Jsons.toMap(result).get("data"), GoogleLoginRep.class);
        loginReq.setType(3);
        loginReq.setEmail(googleLoginRep.getEmail());
        loginReq.setSubject(googleLoginRep.getSubject());
        User user = userService.webLogin(loginReq, request);

        Optional.ofNullable(user.getIsBlack())
                .ifPresent(black -> {
                    if (black) {
                        throw BusinessRuntimeException.getInstance("您的账号已被注销...");
                    }
                });
        //写回登陆信息
        StpUserUtil.login(user.getId());
        UserAuthLoginResp loginPhoneRep = new UserAuthLoginResp(StpUserUtil.getTokenValue(), user.getShowId(), user.getNickname(), user.getHeadimgurl());
        return GatewayResponse.SUCCESS.newBuilder().toResult(loginPhoneRep);
    }

    @GetMapping("/clear/token")
    public void clearUserToken() {
        long userId = StpUserUtil.getLoginIdAsLong();
        if (userId != 55075) {
            return;
        }
        Set<String> keys = redisService.keys("satoken:user:*");
        redisService.del(keys.toArray(String[]::new));
    }

    private String appendCorpAcquistion(GzhOAuth2UserInfo userinfo, String url) throws Exception {
        if (StringUtils.isNotBlank(userinfo.getUnionid())){
            //获客助手投放链路根据unionId查询redis缓存中是否存在广告平台的clickId
            String params = redisService.getStr(String.format(RedisService.key.CORP_CUSTOMER_ACQUISTION_UNIONID_CLICKID.getName(), userinfo.getUnionid()));
            if (StringUtils.isNotBlank(params)) {
                JSONObject paramsObj = JSONUtil.parseObj(params);
                String callback = paramsObj.getStr("callback");

                if (StringUtils.isNotBlank(callback)){

                    Map<String, String> paramMap = HttpUtil.decodeParamMap(callback, IoKit.Charsets.UTF_8.getCharset());
                    Map<String, String> urlParmaMap = HttpUtil.decodeParamMap(url, IoKit.Charsets.UTF_8.getCharset());
                    paramMap.putAll(urlParmaMap);
                    url = (URLUtil.getHost(new URL(url)) + URLUtil.getPath(url)+ "?" + HttpUtil.toParams(paramMap));

                }
            }
        }
        return url;
    }
}
