package com.tcm.training.admin.app.register.controller; import com.tcm.training.admin.app.auth.dto.AppSmsCodeSendRequest; import com.tcm.training.admin.app.auth.vo.AppLoginResponse; import com.tcm.training.admin.app.auth.vo.AppSmsCodeSendResponse; import com.tcm.training.admin.app.register.dto.AppRegisterOperatorCompleteRequest; import com.tcm.training.admin.app.register.dto.AppRegisterOperatorPrepareRequest; import com.tcm.training.admin.app.register.dto.AppRegisterUserRequest; import com.tcm.training.admin.app.register.service.AppRegisterService; import com.tcm.training.admin.app.register.vo.AppRegisterOperatorPrepareResponse; import com.tcm.training.admin.app.register.vo.AppRegisterRegionDatasetVO; import com.tcm.training.admin.app.register.vo.AppRegisterRegionOptionVO; import com.tcm.training.admin.common.ApiResponse; import com.tcm.training.admin.upload.ObsUploadService; import com.tcm.training.admin.upload.UploadController; import com.tcm.training.admin.upload.UploadFileResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.validation.Valid; import java.io.IOException; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; /** * APP 注册接口,统一承接用户注册、经营者注册和注册前附件上传。 */ @Validated @RestController @RequestMapping({"/api/app/register", "/api/v1/app/register"}) public class AppRegisterController { private static final long MAX_SIZE = 5 * 1024 * 1024L; private static final Set ALLOWED_TYPES = new HashSet( Arrays.asList("image/jpeg", "image/png", "image/gif", "image/webp") ); private final AppRegisterService appRegisterService; private final ObsUploadService obsUploadService; /** * 注入注册服务与注册阶段附件上传能力。 */ public AppRegisterController(AppRegisterService appRegisterService, ObsUploadService obsUploadService) { this.appRegisterService = appRegisterService; this.obsUploadService = obsUploadService; } /** * 发送注册短信验证码。 */ @PostMapping("/sms-code") public ApiResponse sendSmsCode(@Valid @RequestBody AppSmsCodeSendRequest request) { return ApiResponse.ok(appRegisterService.sendRegisterCode(request.getPhone())); } /** * 查询 APP 注册三级联动行政区划。 */ @GetMapping("/regions") public ApiResponse> listRegions(@RequestParam(value = "parentCode", required = false) String parentCode) { return ApiResponse.ok(appRegisterService.listRegions(parentCode)); } /** * 查询 APP 滚轮地区选择器使用的完整数据集。 */ @GetMapping("/region-dataset") public ApiResponse getRegionDataset() { return ApiResponse.ok(appRegisterService.getRegionDataset()); } /** * 提交普通用户注册。 */ @PostMapping("/user") public ApiResponse registerUser(@Valid @RequestBody AppRegisterUserRequest request) { return ApiResponse.ok(appRegisterService.registerUser(request)); } /** * 校验经营者第一步并回填海诊通诊所资料。 */ @PostMapping("/operator/prepare") public ApiResponse prepareOperator(@Valid @RequestBody AppRegisterOperatorPrepareRequest request) { return ApiResponse.ok(appRegisterService.prepareOperatorRegister(request)); } /** * 提交经营者第二步并创建本地诊所与诊所用户。 */ @PostMapping("/operator/complete") public ApiResponse completeOperator(@Valid @RequestBody AppRegisterOperatorCompleteRequest request) { return ApiResponse.ok(appRegisterService.completeOperatorRegister(request)); } /** * 上传经营者注册阶段的营业执照图片。 */ @PostMapping("/upload/license") public ApiResponse uploadLicense(@RequestParam("file") MultipartFile file) throws IOException { validateImage(file); UploadFileResult uploadResult = obsUploadService.upload(file, "register/license", null); return ApiResponse.ok(new UploadController.UploadResult(uploadResult.getUrl(), uploadResult.getFileName())); } /** * 校验营业执照图片的大小与类型。 */ private void validateImage(MultipartFile file) { if (file == null || file.isEmpty()) { throw new IllegalArgumentException("请选择要上传的文件"); } if (file.getSize() > MAX_SIZE) { throw new IllegalArgumentException("文件大小超出限制"); } String contentType = file.getContentType(); if (contentType == null || !ALLOWED_TYPES.contains(contentType)) { throw new IllegalArgumentException("仅支持 JPG、PNG、GIF、WebP 格式"); } } }