package com.tourguide.api.mini; import com.tourguide.common.api.ApiResponse; import com.tourguide.integration.wechat.WechatMiniProgramClient; import com.tourguide.integration.wechat.WechatPhoneAuthorization; import com.tourguide.modules.user.domain.ClientType; import com.tourguide.modules.user.dto.AuthResponse; import com.tourguide.modules.user.dto.MiniUserResponse; import com.tourguide.modules.user.dto.WechatPhoneLoginRequest; import com.tourguide.modules.user.service.AuthService; import com.tourguide.modules.user.service.MiniAccountService; import com.tourguide.security.AppUserPrincipal; import com.tourguide.security.BearerTokenResolver; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; /** * 游客小程序认证接口。 * 通过微信登录凭证和手机号授权完成身份识别,仅签发和接收 MINI 客户端类型 Token。 */ @RestController @RequestMapping("/api/mini/auth") public class MiniAuthController { private final AuthService authService; private final BearerTokenResolver tokenResolver; private final WechatMiniProgramClient wechatClient; private final MiniAccountService miniAccountService; public MiniAuthController(AuthService authService, BearerTokenResolver tokenResolver, WechatMiniProgramClient wechatClient, MiniAccountService miniAccountService) { this.authService = authService; this.tokenResolver = tokenResolver; this.wechatClient = wechatClient; this.miniAccountService = miniAccountService; } /** * 使用微信登录 code 和手机号授权 code 登录小程序。 * 接口先向微信换取 openid 与手机号,再查找或创建游客账号并签发 MINI Token。 * * @param request 微信登录凭证和手机号授权凭证 * @return Token 信息及当前游客基础资料 */ @PostMapping("/wechat-phone-login") public ApiResponse> wechatPhoneLogin( @Valid @RequestBody WechatPhoneLoginRequest request) { WechatPhoneAuthorization authorization = wechatClient.authorizePhoneLogin( request.getLoginCode(), request.getPhoneCode()); return ApiResponse.success(authService.loginMiniWechat( authorization.getOpenid(), authorization.getMobile())); } /** * 注销当前游客会话,使 Authorization 请求头中的 MINI Token 立即失效。 * * @param authorization Bearer Token 请求头 * @return 无业务数据的成功响应 */ @PostMapping("/logout") public ApiResponse logout(@RequestHeader("Authorization") String authorization) { authService.logout(tokenResolver.resolve(authorization), ClientType.MINI); return ApiResponse.success(); } @DeleteMapping("/account") public ApiResponse cancelAccount(@AuthenticationPrincipal AppUserPrincipal principal, @RequestHeader("Authorization") String authorization) { miniAccountService.cancel(principal.getUserId(), tokenResolver.resolve(authorization)); return ApiResponse.success(); } }