package com.tourguide.api.guide; import com.tourguide.common.api.ApiResponse; import com.tourguide.modules.user.domain.ClientType; import com.tourguide.modules.user.dto.AuthResponse; import com.tourguide.modules.user.dto.GuidePhoneLoginRequest; import com.tourguide.modules.user.dto.GuideSmsCodeRequest; import com.tourguide.modules.user.dto.GuideUserResponse; import com.tourguide.modules.user.dto.LoginRequest; import com.tourguide.modules.user.dto.SmsCodeResponse; import com.tourguide.modules.user.service.AuthService; import com.tourguide.modules.user.service.GuideAccountService; import com.tourguide.modules.user.service.GuideVerificationCodeService; 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; /** * 导游端认证接口。 * 仅签发和接收 GUIDE 客户端类型的 Token,防止导游凭证跨端访问后台或游客接口。 */ @RestController @RequestMapping("/api/guide/auth") public class GuideAuthController { private final AuthService authService; private final GuideAccountService guideAccountService; private final GuideVerificationCodeService verificationCodeService; private final BearerTokenResolver tokenResolver; public GuideAuthController(AuthService authService, GuideAccountService guideAccountService, GuideVerificationCodeService verificationCodeService, BearerTokenResolver tokenResolver) { this.authService = authService; this.guideAccountService = guideAccountService; this.verificationCodeService = verificationCodeService; this.tokenResolver = tokenResolver; } /** * 使用导游账号和密码登录,校验账号状态后签发 GUIDE Token。 * * @param request 导游登录账号和明文密码 * @return Token 信息及当前导游基础资料 */ @PostMapping("/password-login") public ApiResponse> passwordLogin(@Valid @RequestBody LoginRequest request) { return ApiResponse.success(authService.loginGuide(request)); } /** 发送导游手机号登录验证码。 */ @PostMapping("/sms-code") public ApiResponse sendSmsCode(@Valid @RequestBody GuideSmsCodeRequest request) { authService.ensureGuidePhoneCanLogin(request.getPhone()); return ApiResponse.success(verificationCodeService.send(request.getPhone())); } /** 校验一次性验证码并签发 GUIDE Token。 */ @PostMapping("/login") public ApiResponse> login(@Valid @RequestBody GuidePhoneLoginRequest request) { verificationCodeService.verifyAndConsume(request.getPhone(), request.getCode()); return ApiResponse.success(authService.loginGuideByPhone(request.getPhone())); } /** * 注销当前导游会话,使 Authorization 请求头中的 GUIDE Token 立即失效。 * * @param authorization Bearer Token 请求头 * @return 无业务数据的成功响应 */ @PostMapping("/logout") public ApiResponse logout(@RequestHeader("Authorization") String authorization) { authService.logout(tokenResolver.resolve(authorization), ClientType.GUIDE); return ApiResponse.success(); } /** 注销当前导游账号;存在未完成订单时拒绝注销,并保留后台历史业务资料。 */ @DeleteMapping("/account") public ApiResponse cancelAccount(@AuthenticationPrincipal AppUserPrincipal principal, @RequestHeader("Authorization") String authorization) { guideAccountService.cancel(principal.getUserId(), tokenResolver.resolve(authorization)); return ApiResponse.success(); } }