package com.cyksj.web.controller.advertisement; import com.cyksj.common.exception.BusinessRuntimeException; import com.cyksj.common.snowflake.Sequence; import com.cyksj.common.util.Codec; import com.cyksj.common.util.Jsons; import com.cyksj.dto.Result; import com.cyksj.enums.GatewayResponse; import com.cyksj.enums.WeChatAuthRedirectUrl; import com.cyksj.model.dto.AuthRedirect; import com.cyksj.model.dto.AuthToken; import com.cyksj.model.dto.UserWhoami; import com.cyksj.model.entity.AdvertisementUser; import com.cyksj.model.request.MiniProgramLoginPost; import com.cyksj.redis.RedisService; import com.cyksj.service.advertisement.AdvertisementUserService; 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.beans.factory.annotation.Value; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; /** * @author chan * @date 2023/5/16 11:49 AM */ @Slf4j @RequiredArgsConstructor @RestController @RequestMapping("/applets/advertisement/user") public class AdvertisementUserController { @Value("${advertisementwxapp.notify}") private String notify; @Value("${advertisementwxapp.appId}") private String appId; private final static Sequence SEQUENCE = new Sequence(0); private final AdvertisementUserService advertisementUserService; private final RedisService redisService; private final WeChatService weChatService; /** * 小程序静默授权 */ @PostMapping(value = "/login") @Transactional(rollbackFor = Exception.class) public Result wxlogin(@RequestBody MiniProgramLoginPost miniDataParams) throws Exception{ String methodName = "小程序静默授权"; log.info("{}[start] params:{}",methodName,miniDataParams); if (StringUtils.isBlank(miniDataParams.getCode())) { throw BusinessRuntimeException.getInstance("需要登录凭证code."); } final String code = miniDataParams.getCode(); // 用户token AdvertisementUser user = advertisementUserService.wxlogin(code,miniDataParams.getAppId()); StpUserUtil.login(user.getId()); log.info("{}[end] uuid:{}",methodName, user.getId()); return GatewayResponse.SUCCESS.newBuilder().toResult(StpUserUtil.getTokenValue()); } @GetMapping(value = "/whoami") public Result whoami(){ AdvertisementUser user = advertisementUserService.getById(StpUserUtil.getLoginIdAsLong()); UserWhoami userWhoami = advertisementUserService.whoami(user.getId()); return GatewayResponse.SUCCESS.newBuilder().toResult(userWhoami); } @GetMapping(value = "/weChat") public void base(String url, String authType, HttpServletResponse response) throws Exception { log.info("微信授权转跳. url: {},authType:{}",url,authType); // 无论是否为老用户 均转跳到授权页面 // 若授权过 则无需再次授权 直接回调 /user/wechat/redirect // 新用户同意授权后 也会回调 /user/wechat/redirect Long mappingId = SEQUENCE.nextId(); redisService.set(mappingId.toString(),url,60*60*24L); AuthRedirect redirect = new AuthRedirect().setMappingId(mappingId); String state = Codec.DoBase64.custom().setData(Jsons.toJson(redirect)).encodeAsText(); response.sendRedirect(weChatService.createUrl(state, notify + WeChatAuthRedirectUrl.get(authType).getUrl(), appId, WeChatAuthRedirectUrl.get(authType).getScope() )); } /** * 静默授权 * @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,appId); // 查询用户期望转跳的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); } }