diff --git a/src/main/java/the_monitor/application/dto/request/ClientUpdateRequest.java b/src/main/java/the_monitor/application/dto/request/ClientUpdateRequest.java new file mode 100644 index 0000000..f918919 --- /dev/null +++ b/src/main/java/the_monitor/application/dto/request/ClientUpdateRequest.java @@ -0,0 +1,16 @@ +package the_monitor.application.dto.request; + +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class ClientUpdateRequest { + + @NotBlank(message = "고객사명은 필수입니다.") + private String name; + + @NotBlank(message = "담당자명은 필수입니다.") + private String managerName; +} \ No newline at end of file diff --git a/src/main/java/the_monitor/application/service/ClientService.java b/src/main/java/the_monitor/application/service/ClientService.java index e372858..b29d891 100644 --- a/src/main/java/the_monitor/application/service/ClientService.java +++ b/src/main/java/the_monitor/application/service/ClientService.java @@ -2,6 +2,7 @@ import org.springframework.web.multipart.MultipartFile; import the_monitor.application.dto.request.ClientRequest; +import the_monitor.application.dto.request.ClientUpdateRequest; import the_monitor.application.dto.response.ClientResponse; import the_monitor.domain.model.Client; @@ -16,4 +17,8 @@ public interface ClientService { Client findClientById(Long clientId); ClientResponse getClient(Long clientId); + + String deleteClientById(Long clientId); + + String updateClient(Long clientId, ClientUpdateRequest request, MultipartFile logo); } diff --git a/src/main/java/the_monitor/application/serviceImpl/ClientServiceImpl.java b/src/main/java/the_monitor/application/serviceImpl/ClientServiceImpl.java index a91b96f..8d7c273 100644 --- a/src/main/java/the_monitor/application/serviceImpl/ClientServiceImpl.java +++ b/src/main/java/the_monitor/application/serviceImpl/ClientServiceImpl.java @@ -4,6 +4,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.security.core.context.SecurityContextHolder; import the_monitor.application.dto.request.ClientRequest; +import the_monitor.application.dto.request.ClientUpdateRequest; import the_monitor.application.dto.response.ClientResponse; import the_monitor.application.dto.response.ReportListResponse; import the_monitor.application.service.CategoryService; @@ -130,6 +131,7 @@ public Client findClientById(Long clientId) { return clientRepository.findById(clientId) .orElseThrow(() -> new ApiException(ErrorStatus._CLIENT_NOT_FOUND)); } + @Override public ClientResponse getClient(Long clientId){ @@ -168,4 +170,40 @@ private Long getAccountIdFromJwt() { return jwtProvider.getAccountId(token); } + @Override + @Transactional + public String deleteClientById(Long clientId) { + Long accountId = getAccountIdFromJwt(); // JWT에서 accountId 추출 (유틸리티 메서드) + + // 1. Client 존재 여부 및 권한 확인 + Client client = clientRepository.findById(clientId) + .orElseThrow(() -> new ApiException(ErrorStatus._CLIENT_NOT_FOUND)); + + if (!client.getAccount().getId().equals(accountId)) { + throw new ApiException(ErrorStatus._CLIENT_FORBIDDEN); + } + + // 2. Client 삭제 + clientRepository.delete(client); + + // 3. 성공 메시지 반환 + return "고객사 정보가 성공적으로 삭제되었습니다."; + } + + @Override + @Transactional + public String updateClient(Long clientId, ClientUpdateRequest request, MultipartFile logo) { + // 1. 고객사 조회 + Client client = clientRepository.findById(clientId) + .orElseThrow(() -> new IllegalArgumentException("Client not found with id: " + clientId)); + + String logoPath; + logoPath = (logo != null) ? s3Service.uploadFile(logo) : defaultLogoUrl; + + // 2. 수정 사항 적용 + client.updateClientInfo(request.getName(), request.getManagerName(), logoPath); + + return "고객사 정보가 성공적으로 수정되었습니다."; + } + } \ No newline at end of file diff --git a/src/main/java/the_monitor/common/ErrorStatus.java b/src/main/java/the_monitor/common/ErrorStatus.java index 95f5e8d..f31716a 100644 --- a/src/main/java/the_monitor/common/ErrorStatus.java +++ b/src/main/java/the_monitor/common/ErrorStatus.java @@ -41,6 +41,7 @@ public enum ErrorStatus implements BaseErrorCode { // Client _CLIENT_NOT_FOUND(HttpStatus.NOT_FOUND, "CLIENT404", "해당 클라이언트를 찾을 수 없습니다."), + _CLIENT_FORBIDDEN(HttpStatus.FORBIDDEN, "CLIENT403", "해당 클라이언트에 접속할 수 없습니다,"), // Report _REPORT_NOT_FOUND(HttpStatus.NOT_FOUND, "REPORT404", "해당 리포트를 찾을 수 없습니다."), diff --git a/src/main/java/the_monitor/domain/model/Client.java b/src/main/java/the_monitor/domain/model/Client.java index cf55985..ca200a6 100644 --- a/src/main/java/the_monitor/domain/model/Client.java +++ b/src/main/java/the_monitor/domain/model/Client.java @@ -86,4 +86,15 @@ public void setClientMailCCs(List clientMailCCs) { this.clientMailCCs = clientMailCCs; } + public void updateClientInfo(String name, String managerName, String logoUrl) { + if (name != null && !name.isBlank()) { + this.name = name; + } + if (managerName != null && !managerName.isBlank()) { + this.managerName = managerName; + } + if (logoUrl != null) { + this.logo = logoUrl; + } + } } diff --git a/src/main/java/the_monitor/presentation/ClientController.java b/src/main/java/the_monitor/presentation/ClientController.java index 06ca0f5..16673c2 100644 --- a/src/main/java/the_monitor/presentation/ClientController.java +++ b/src/main/java/the_monitor/presentation/ClientController.java @@ -5,6 +5,8 @@ import org.springframework.http.MediaType; import org.springframework.web.multipart.MultipartFile; import the_monitor.application.dto.request.ClientRequest; +import the_monitor.application.dto.request.ClientUpdateRequest; +import the_monitor.application.dto.request.ReportUpdateTitleRequest; import the_monitor.application.dto.response.ClientResponse; import the_monitor.application.service.ClientService; import the_monitor.common.ApiResponse; @@ -40,10 +42,26 @@ public ApiResponse> getClient() { return ApiResponse.onSuccessData("클라이언트 조회 성공", clientResponses); } + @Operation(summary = "고객사 정보 삭제", description = "고객사 정보를 삭제합니다.") + @DeleteMapping() + public ApiResponse deleteClient(@RequestParam("clientId") Long clientId) { + return ApiResponse.onSuccess(clientService.deleteClientById(clientId)); + + } + @Operation(summary = "clietId로 고객사 정보 반환", description = "clientId로 고객사 정보를 조회합니다.") @GetMapping("/info") public ApiResponse getClientInfo(@RequestParam("clientId") Long clientId){ return ApiResponse.onSuccessData("클라이언트 정보 조회 성공", clientService.getClient(clientId)); } + @Operation(summary = "고객사 정보 수정", description = "고객사 정보를 수정합니다.") + @PutMapping(value = "/update", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public ApiResponse UpdateClient(@RequestParam("clientId") Long clientId, + @RequestPart("clientData") @Valid ClientUpdateRequest request, + @RequestPart(name = "logo", required = false) MultipartFile logo) { + return ApiResponse.onSuccess(clientService.updateClient(clientId, request, logo)); + + } + } \ No newline at end of file