| | |
| | | |
| | | import com.tourguide.common.api.ApiResponse; |
| | | import com.tourguide.common.api.PageResponse; |
| | | import com.tourguide.common.exception.BusinessException; |
| | | import com.tourguide.modules.user.dto.*; |
| | | import com.tourguide.modules.user.service.GuideAutoDisableService; |
| | | import com.tourguide.modules.user.service.GuideRegistrationDocumentStorageService; |
| | | import com.tourguide.modules.user.service.GuideUserService; |
| | | import com.tourguide.modules.user.service.MiniAvatarStorageService; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | import org.springframework.http.MediaType; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | import javax.validation.Valid; |
| | | import java.time.LocalDate; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 管理后台导游账号管理接口。 |
| | |
| | | @RequestMapping("/api/admin/guide-users") |
| | | public class AdminGuideUserController { |
| | | private final GuideUserService userService; |
| | | public AdminGuideUserController(GuideUserService userService) { this.userService = userService; } |
| | | private final GuideAutoDisableService autoDisableService; |
| | | private final MiniAvatarStorageService avatarStorageService; |
| | | private final GuideRegistrationDocumentStorageService documentStorageService; |
| | | |
| | | public AdminGuideUserController(GuideUserService userService, |
| | | GuideAutoDisableService autoDisableService, |
| | | MiniAvatarStorageService avatarStorageService, |
| | | GuideRegistrationDocumentStorageService documentStorageService) { |
| | | this.userService = userService; |
| | | this.autoDisableService = autoDisableService; |
| | | this.avatarStorageService = avatarStorageService; |
| | | this.documentStorageService = documentStorageService; |
| | | } |
| | | |
| | | /** |
| | | * 分页查询导游账号,支持基础关键字、状态、日期、评级、团队类型和白名单筛选。 |
| | |
| | | } |
| | | |
| | | /** |
| | | * 上传并更新指定导游头像。 |
| | | * |
| | | * @param id 导游账号主键 |
| | | * @param file JPG、PNG 或 WebP 图片,最大 5MB |
| | | * @return 更新后的导游基础信息 |
| | | */ |
| | | @PostMapping(value = "/{id}/avatar", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) |
| | | public ApiResponse<GuideUserResponse> updateAvatar(@PathVariable Long id, |
| | | @RequestPart("file") MultipartFile file) { |
| | | String avatar = avatarStorageService.store(file); |
| | | return ApiResponse.success(userService.updateAvatarByAdmin(id, avatar)); |
| | | } |
| | | |
| | | /** |
| | | * 上传并更新指定导游的证件图片。 |
| | | * |
| | | * @param id 导游账号主键 |
| | | * @param documentType 证件字段名:idCardFrontUrl、idCardBackUrl、guideCertificateUrl 或 qualificationCertificateUrl |
| | | * @param file JPG、PNG 或 WebP 图片,最大 5MB |
| | | * @return 上传后保存的证件图片地址 |
| | | */ |
| | | @PostMapping(value = "/{id}/documents/{documentType}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) |
| | | public ApiResponse<GuideRegistrationDocumentResponse> uploadDocument(@PathVariable Long id, |
| | | @PathVariable String documentType, |
| | | @RequestPart("file") MultipartFile file) { |
| | | if (!userService.supportsDocumentType(documentType)) { |
| | | throw new BusinessException(400, "不支持的证件类型"); |
| | | } |
| | | String documentUrl = documentStorageService.store(file); |
| | | return ApiResponse.success(new GuideRegistrationDocumentResponse( |
| | | userService.updateDocumentByAdmin(id, documentType, documentUrl))); |
| | | } |
| | | |
| | | @PostMapping("/{id}/scenic-configs") |
| | | public ApiResponse<List<GuideScenicConfigResponse>> addScenicConfig( |
| | | @PathVariable Long id, |
| | | @Valid @RequestBody GuideScenicConfigCreateRequest request) { |
| | | return ApiResponse.success(userService.addScenicConfig(id, request.getScenicSpotId())); |
| | | } |
| | | |
| | | @DeleteMapping("/{id}/scenic-configs/{configId}") |
| | | public ApiResponse<List<GuideScenicConfigResponse>> deleteScenicConfig( |
| | | @PathVariable Long id, |
| | | @PathVariable Long configId) { |
| | | return ApiResponse.success(userService.deleteScenicConfig(id, configId)); |
| | | } |
| | | |
| | | /** |
| | | * 由后台直接创建导游账号,适用于无需走入驻审核流程的运营录入场景。 |
| | | * |
| | | * @param request 导游账号创建参数 |
| | |
| | | |
| | | /** |
| | | * 启用或禁用指定导游账号,禁用后导游无法继续使用导游端受保护接口。 |
| | | * 自动禁用的导游必须先加入自动禁用白名单后才能手动启用。 |
| | | * |
| | | * @param id 导游账号主键 |
| | | * @param request 目标状态,1 为启用、0 为禁用 |
| | |
| | | @PutMapping("/{id}/status") |
| | | public ApiResponse<Void> updateStatus(@PathVariable Long id, @Valid @RequestBody UserStatusRequest request) { |
| | | userService.updateStatus(id, request.getStatus()); |
| | | if (request.getStatus() == GuideUserService.STATUS_ENABLED) { |
| | | autoDisableService.disableGuideIfEligible(id); |
| | | } |
| | | return ApiResponse.success(); |
| | | } |
| | | |
| | |
| | | @PutMapping("/{id}/whitelist") |
| | | public ApiResponse<Void> updateWhitelist(@PathVariable Long id, @Valid @RequestBody GuideWhitelistRequest request) { |
| | | userService.updateWhitelist(id, request.getEnabled()); |
| | | if (!request.getEnabled()) { |
| | | autoDisableService.disableGuideIfEligible(id); |
| | | } |
| | | return ApiResponse.success(); |
| | | } |
| | | |
| | |
| | | @PutMapping("/auto-disable/config") |
| | | public ApiResponse<GuideAutoDisableConfigResponse> updateAutoDisableConfig( |
| | | @Valid @RequestBody GuideAutoDisableConfigRequest request) { |
| | | return ApiResponse.success(userService.updateAutoDisableConfig(request)); |
| | | GuideAutoDisableConfigResponse config = userService.updateAutoDisableConfig(request); |
| | | autoDisableService.synchronizeGuideStatuses(); |
| | | return ApiResponse.success(config); |
| | | } |
| | | } |