diff --git a/src/main/java/com/mobility/api/domain/auth/controller/AuthOfficeV1Controller.java b/src/main/java/com/mobility/api/domain/auth/controller/AuthOfficeV1Controller.java index 02d1af9..3f9d4cb 100644 --- a/src/main/java/com/mobility/api/domain/auth/controller/AuthOfficeV1Controller.java +++ b/src/main/java/com/mobility/api/domain/auth/controller/AuthOfficeV1Controller.java @@ -2,18 +2,12 @@ import com.mobility.api.domain.auth.dto.response.TokenDto; import com.mobility.api.domain.auth.service.AuthService; -import com.mobility.api.domain.office.dto.request.DispatchSearchDto; -import com.mobility.api.domain.office.dto.request.OfficeLoginReq; -import com.mobility.api.domain.office.dto.request.OfficeSignupReq; -import com.mobility.api.domain.office.dto.response.GetAllDispatchRes; -import com.mobility.api.global.annotation.SwaggerPageable; +import com.mobility.api.domain.auth.dto.request.OfficeLoginReq; +import com.mobility.api.domain.auth.dto.request.OfficeSignupReq; import com.mobility.api.global.response.CommonResponse; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import org.springframework.web.bind.annotation.*; @Tag(name = "사무실 인증 관련 요청(/api/v1/auth/office/...)") diff --git a/src/main/java/com/mobility/api/domain/auth/controller/AuthTransporterV1Controller.java b/src/main/java/com/mobility/api/domain/auth/controller/AuthTransporterV1Controller.java new file mode 100644 index 0000000..ed113da --- /dev/null +++ b/src/main/java/com/mobility/api/domain/auth/controller/AuthTransporterV1Controller.java @@ -0,0 +1,51 @@ +package com.mobility.api.domain.auth.controller; + +import com.mobility.api.domain.auth.dto.request.OfficeLoginReq; +import com.mobility.api.domain.auth.dto.request.TransporterLoginReq; +import com.mobility.api.domain.auth.dto.request.TransporterSignupReq; +import com.mobility.api.domain.auth.dto.response.TokenDto; +import com.mobility.api.domain.auth.service.AuthService; +import com.mobility.api.domain.auth.dto.request.OfficeSignupReq; +import com.mobility.api.global.response.CommonResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +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.RestController; + +@Tag(name = "기사 인증 관련 요청(/api/v1/auth/transporter/...)") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/v1/auth/transporter") +public class AuthTransporterV1Controller { + + private final AuthService authService; + + @Operation(summary = "기사 회원가입") + @PostMapping("/signup") + public CommonResponse signupOffice( + @RequestBody TransporterSignupReq req + ) { + authService.signupTransporter(req); + return CommonResponse.success(null); + } + + /** + *
+     * 기사 - 로그인
+     * 
+ */ + @Operation(summary = "기사 로그인 요청", description = "전화번호를 입력받아 Access Token을 발급합니다.") + @PostMapping("/login") // RequestMapping(method=POST)와 같습니다. + public CommonResponse login(@RequestBody TransporterLoginReq req) { + + // 1. 서비스 호출 (로그인 로직 수행) + TokenDto tokenDto = authService.transporterLogin(req); + + // 2. 결과 반환 + return CommonResponse.success(tokenDto); + } + +} diff --git a/src/main/java/com/mobility/api/domain/office/dto/request/OfficeLoginReq.java b/src/main/java/com/mobility/api/domain/auth/dto/request/OfficeLoginReq.java similarity index 84% rename from src/main/java/com/mobility/api/domain/office/dto/request/OfficeLoginReq.java rename to src/main/java/com/mobility/api/domain/auth/dto/request/OfficeLoginReq.java index ec794c5..2db45c6 100644 --- a/src/main/java/com/mobility/api/domain/office/dto/request/OfficeLoginReq.java +++ b/src/main/java/com/mobility/api/domain/auth/dto/request/OfficeLoginReq.java @@ -1,4 +1,4 @@ -package com.mobility.api.domain.office.dto.request; +package com.mobility.api.domain.auth.dto.request; import io.swagger.v3.oas.annotations.media.Schema; diff --git a/src/main/java/com/mobility/api/domain/office/dto/request/OfficeSignupReq.java b/src/main/java/com/mobility/api/domain/auth/dto/request/OfficeSignupReq.java similarity index 95% rename from src/main/java/com/mobility/api/domain/office/dto/request/OfficeSignupReq.java rename to src/main/java/com/mobility/api/domain/auth/dto/request/OfficeSignupReq.java index 9df4fe7..603bcd7 100644 --- a/src/main/java/com/mobility/api/domain/office/dto/request/OfficeSignupReq.java +++ b/src/main/java/com/mobility/api/domain/auth/dto/request/OfficeSignupReq.java @@ -1,4 +1,4 @@ -package com.mobility.api.domain.office.dto.request; +package com.mobility.api.domain.auth.dto.request; import io.swagger.v3.oas.annotations.media.Schema; diff --git a/src/main/java/com/mobility/api/domain/auth/dto/request/TransporterLoginReq.java b/src/main/java/com/mobility/api/domain/auth/dto/request/TransporterLoginReq.java new file mode 100644 index 0000000..22d7462 --- /dev/null +++ b/src/main/java/com/mobility/api/domain/auth/dto/request/TransporterLoginReq.java @@ -0,0 +1,5 @@ +package com.mobility.api.domain.auth.dto.request; + +public record TransporterLoginReq( + String phone +) {} \ No newline at end of file diff --git a/src/main/java/com/mobility/api/domain/auth/dto/request/TransporterSignupReq.java b/src/main/java/com/mobility/api/domain/auth/dto/request/TransporterSignupReq.java new file mode 100644 index 0000000..d99ebc3 --- /dev/null +++ b/src/main/java/com/mobility/api/domain/auth/dto/request/TransporterSignupReq.java @@ -0,0 +1,7 @@ +package com.mobility.api.domain.auth.dto.request; + +public record TransporterSignupReq( + String name, + String phone, + Boolean isAutoDispatch +) {} \ No newline at end of file diff --git a/src/main/java/com/mobility/api/domain/auth/service/AuthService.java b/src/main/java/com/mobility/api/domain/auth/service/AuthService.java index a92a1fa..85659b2 100644 --- a/src/main/java/com/mobility/api/domain/auth/service/AuthService.java +++ b/src/main/java/com/mobility/api/domain/auth/service/AuthService.java @@ -1,13 +1,17 @@ package com.mobility.api.domain.auth.service; +import com.mobility.api.domain.auth.dto.request.TransporterLoginReq; +import com.mobility.api.domain.auth.dto.request.TransporterSignupReq; import com.mobility.api.domain.auth.dto.response.TokenDto; -import com.mobility.api.domain.office.dto.request.OfficeLoginReq; -import com.mobility.api.domain.office.dto.request.OfficeSignupReq; +import com.mobility.api.domain.auth.dto.request.OfficeLoginReq; +import com.mobility.api.domain.auth.dto.request.OfficeSignupReq; import com.mobility.api.domain.office.entity.Manager; import com.mobility.api.domain.office.entity.Office; import com.mobility.api.domain.office.enums.ManagerRole; import com.mobility.api.domain.office.repository.ManagerRepository; import com.mobility.api.domain.office.repository.OfficeRepository; +import com.mobility.api.domain.transporter.entity.Transporter; +import com.mobility.api.domain.transporter.repository.TransporterRepository; import com.mobility.api.global.exception.GlobalException; import com.mobility.api.global.jwt.JwtProvider; import com.mobility.api.global.response.ResultCode; @@ -22,6 +26,7 @@ public class AuthService { private final ManagerRepository managerRepository; private final OfficeRepository officeRepository; + private final TransporterRepository transporterRepository; private final JwtProvider jwtProvider; // 토큰 발급기 private final PasswordEncoder passwordEncoder; // 비밀번호 검사기 @@ -86,4 +91,43 @@ public TokenDto officeLogin(OfficeLoginReq req) { return new TokenDto(accessToken, "Bearer"); } + /** + * [기사] 회원가입 + */ + @Transactional + public void signupTransporter(TransporterSignupReq req) { + // 1. 전화번호 중복 검사 + if (transporterRepository.existsByPhone(req.phone())) { + throw new GlobalException(ResultCode.FIXME_FAIL); // 이미 가입된 번호 + } + + // 2. 기사 정보 생성 및 저장 + Transporter transporter = Transporter.builder() + .name(req.name()) + .phone(req.phone()) + .isAutoDispatch(req.isAutoDispatch()) + .build(); + + transporterRepository.save(transporter); + } + + /** + * [기사] 로그인 (전화번호만 일치하면 통과) + */ + @Transactional + public TokenDto transporterLogin(TransporterLoginReq req) { + // 1. 전화번호로 기사 찾기 + Transporter transporter = transporterRepository.findByPhone(req.phone()) + .orElseThrow(() -> new GlobalException(ResultCode.NOT_FOUND_USER)); // 가입되지 않은 기사 + + // 2. 비밀번호 검증 없음 (요구사항 반영: 전화번호만 맞으면 바로 로그인 처리) + + // 3. 토큰 생성 + // Subject: phone (기사는 ID 대신 전화번호를 식별자로 씀) + // Role: "ROLE_TRANSPORTER" (권한 분리) + String accessToken = jwtProvider.createToken(transporter.getPhone(), "ROLE_TRANSPORTER"); + + return new TokenDto(accessToken, "Bearer"); + } + } diff --git a/src/main/java/com/mobility/api/domain/transporter/repository/TransporterRepository.java b/src/main/java/com/mobility/api/domain/transporter/repository/TransporterRepository.java index 4735255..a55ddce 100644 --- a/src/main/java/com/mobility/api/domain/transporter/repository/TransporterRepository.java +++ b/src/main/java/com/mobility/api/domain/transporter/repository/TransporterRepository.java @@ -58,6 +58,10 @@ List findEligibleDriversForAutoDispatch( @Param("lon") double lon ); + // 전화번호 중복 가입 체크용 + boolean existsByPhone(String phoneNumber); + + // 로그인 시 기사 조회용 (기사 id는 전화번호이므로 username을 받아서 phone을 조회함) Optional findByPhone(String username); }