diff --git a/src/main/java/com/mobility/api/domain/office/controller/OfficeV1Controller.java b/src/main/java/com/mobility/api/domain/office/controller/OfficeV1Controller.java index fc20a67..cab9e60 100644 --- a/src/main/java/com/mobility/api/domain/office/controller/OfficeV1Controller.java +++ b/src/main/java/com/mobility/api/domain/office/controller/OfficeV1Controller.java @@ -1,14 +1,8 @@ package com.mobility.api.domain.office.controller; import com.mobility.api.domain.dispatch.entity.Dispatch; -import com.mobility.api.domain.office.dto.request.CancelDispatchReq; -import com.mobility.api.domain.office.dto.request.CreateDispatchReq; -import com.mobility.api.domain.office.dto.request.DispatchSearchDto; -import com.mobility.api.domain.office.dto.request.UpdateDispatchReq; -import com.mobility.api.domain.office.dto.response.DispatchFeedRes; -import com.mobility.api.domain.office.dto.response.DispatchSummaryRes; -import com.mobility.api.domain.office.dto.response.GetAllDispatchRes; -import com.mobility.api.domain.office.dto.response.GetDispatchDetailRes; +import com.mobility.api.domain.office.dto.request.*; +import com.mobility.api.domain.office.dto.response.*; import com.mobility.api.domain.office.service.OfficeService; import com.mobility.api.domain.transporter.dto.request.TransporterCreateReq; import com.mobility.api.domain.transporter.dto.request.TransporterStatusUpdateReq; @@ -40,6 +34,34 @@ public class OfficeV1Controller { private final OfficeService officeService; + /** + *
+ * 사무실 정보 조회 + *+ */ + @Operation(summary = "사무실 정보 조회", description = "현재 로그인한 관리자가 소속된 사무실의 상세 정보를 조회합니다.") + @GetMapping("/profile") // URL: /api/v1/office/profile + public CommonResponse
+ * 사무실 정보 수정 + *+ */ + @Operation(summary = "사무실 정보 수정", description = "소속된 사무실의 상세 정보를 수정합니다.") + @PatchMapping("/profile") + public CommonResponse
* 사무실 - 배차 리스트 조회
diff --git a/src/main/java/com/mobility/api/domain/office/dto/request/OfficeUpdateReq.java b/src/main/java/com/mobility/api/domain/office/dto/request/OfficeUpdateReq.java
new file mode 100644
index 0000000..6c61fbd
--- /dev/null
+++ b/src/main/java/com/mobility/api/domain/office/dto/request/OfficeUpdateReq.java
@@ -0,0 +1,16 @@
+package com.mobility.api.domain.office.dto.request;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Pattern;
+
+public record OfficeUpdateReq(
+
+ String name, // officeName 매핑
+
+ String registrationNumber, // officeRegistrationNumber 매핑
+
+ String address, // officeAddress 매핑
+
+ @Pattern(regexp = "^\\d{2,3}-\\d{3,4}-\\d{4}$", message = "올바른 전화번호 형식이 아닙니다.")
+ String telNumber // officeTelNumber 매핑
+) {}
\ No newline at end of file
diff --git a/src/main/java/com/mobility/api/domain/office/dto/response/OfficeProfileRes.java b/src/main/java/com/mobility/api/domain/office/dto/response/OfficeProfileRes.java
new file mode 100644
index 0000000..1bc1277
--- /dev/null
+++ b/src/main/java/com/mobility/api/domain/office/dto/response/OfficeProfileRes.java
@@ -0,0 +1,27 @@
+package com.mobility.api.domain.office.dto.response;
+
+import com.mobility.api.domain.office.entity.Office;
+import lombok.Builder;
+
+@Builder
+public record OfficeProfileRes(
+ Long id,
+ String name, // 사무실 이름
+ String registrationNumber, // 사업자 번호
+ String telNumber, // 사업장 전화번호
+ String address, // 주소
+ String createdAt, // 가입일
+ String updatedAt // 수정일
+) {
+ public static OfficeProfileRes from(Office office) {
+ return OfficeProfileRes.builder()
+ .id(office.getId())
+ .name(office.getOfficeName())
+ .registrationNumber(office.getOfficeRegistrationNumber())
+ .telNumber(office.getOfficeTelNumber())
+ .address(office.getOfficeAddress())
+ .createdAt(office.getCreatedAt().toString())
+ .updatedAt(office.getUpdatedAt().toString())
+ .build();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mobility/api/domain/office/entity/Manager.java b/src/main/java/com/mobility/api/domain/office/entity/Manager.java
index 7440721..7b1b5ea 100644
--- a/src/main/java/com/mobility/api/domain/office/entity/Manager.java
+++ b/src/main/java/com/mobility/api/domain/office/entity/Manager.java
@@ -4,10 +4,7 @@
import com.mobility.api.domain.office.enums.ManagerStatus;
import com.mobility.api.global.entity.BaseSoftDeleteEntity;
import jakarta.persistence.*;
-import lombok.AccessLevel;
-import lombok.Builder;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
+import lombok.*;
import org.hibernate.annotations.SQLDelete;
@Entity
diff --git a/src/main/java/com/mobility/api/domain/office/entity/Office.java b/src/main/java/com/mobility/api/domain/office/entity/Office.java
index b6c6fe7..b973b33 100644
--- a/src/main/java/com/mobility/api/domain/office/entity/Office.java
+++ b/src/main/java/com/mobility/api/domain/office/entity/Office.java
@@ -1,5 +1,7 @@
package com.mobility.api.domain.office.entity;
+import com.mobility.api.domain.office.dto.request.OfficeUpdateReq;
+import com.mobility.api.global.entity.BaseEntity;
import jakarta.persistence.*;
import lombok.*;
@@ -8,7 +10,7 @@
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Table(name = "office")
-public class Office {
+public class Office extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@@ -37,4 +39,20 @@ public Office(String officeName, String officeRegistrationNumber, String officeA
this.officeAddress = officeAddress;
this.officeTelNumber = officeTelNumber;
}
+
+ public void updateProfile(OfficeUpdateReq req) {
+ // 값이 null이 아니고, (필요시) 비어있지 않은 경우에만 업데이트
+ if (req.name() != null) {
+ this.officeName = req.name();
+ }
+ if (req.registrationNumber() != null) {
+ this.officeRegistrationNumber = req.registrationNumber();
+ }
+ if (req.address() != null) {
+ this.officeAddress = req.address();
+ }
+ if (req.telNumber() != null) {
+ this.officeTelNumber = req.telNumber();
+ }
+ }
}
diff --git a/src/main/java/com/mobility/api/domain/office/service/OfficeService.java b/src/main/java/com/mobility/api/domain/office/service/OfficeService.java
index 0b3ce20..5422ea1 100644
--- a/src/main/java/com/mobility/api/domain/office/service/OfficeService.java
+++ b/src/main/java/com/mobility/api/domain/office/service/OfficeService.java
@@ -5,16 +5,11 @@
import com.mobility.api.domain.dispatch.enums.StatusType;
import com.mobility.api.domain.dispatch.repository.DispatchRepository;
import com.mobility.api.domain.dispatch.service.AutoDispatchService;
-import com.mobility.api.domain.office.dto.request.CancelDispatchReq;
-import com.mobility.api.domain.office.dto.request.CreateDispatchReq;
-import com.mobility.api.domain.office.dto.request.DispatchSearchDto;
-import com.mobility.api.domain.office.dto.request.UpdateDispatchReq;
-import com.mobility.api.domain.office.dto.response.DispatchFeedRes;
-import com.mobility.api.domain.office.dto.response.DispatchSummaryRes;
-import com.mobility.api.domain.office.dto.response.GetAllDispatchRes;
-import com.mobility.api.domain.office.dto.response.GetDispatchDetailRes;
+import com.mobility.api.domain.office.dto.request.*;
+import com.mobility.api.domain.office.dto.response.*;
import com.mobility.api.domain.office.entity.Manager;
import com.mobility.api.domain.office.entity.Office;
+import com.mobility.api.domain.office.repository.OfficeRepository;
import com.mobility.api.domain.transporter.TransporterStatus;
import com.mobility.api.domain.transporter.dto.request.TransporterCreateReq;
import com.mobility.api.domain.transporter.dto.response.TransporterRes;
@@ -43,6 +38,40 @@ public class OfficeService {
private final DispatchRepository dispatchRepository;
private final TransporterRepository transporterRepository;
private final AutoDispatchService autoDispatchService;
+ private final OfficeRepository officeRepository;
+
+ /**
+ * 사무실 정보 조회
+ */
+ @Transactional(readOnly = true)
+ public OfficeProfileRes getOfficeProfile(Manager manager) {
+
+ Long officeId = manager.getOffice().getId(); // 여기의 manager객체는 office의 id만 가지고 있음
+
+ Office office = officeRepository.findById(officeId)
+ .orElseThrow(() -> new GlobalException(ResultCode.NOT_FOUND_OFFICE));
+
+ // 2. DTO 변환
+ return OfficeProfileRes.from(office);
+ }
+
+ /**
+ * 사무실 정보 수정
+ */
+ @Transactional
+ public void updateOfficeProfile(Manager manager, OfficeUpdateReq req) {
+ // 1. 매니저가 가진 프록시 객체에서 ID만 추출 (쿼리 안나감)
+ Long officeId = manager.getOffice().getId();
+
+ // 2. 수정을 위해 진짜 엔티티 조회
+ Office office = officeRepository.findById(officeId)
+ .orElseThrow(() -> new GlobalException(ResultCode.NOT_FOUND_OFFICE));
+
+ // 3. 비즈니스 로직 호출 (변경 감지 활용)
+ office.updateProfile(req);
+
+ // 트랜잭션 종료 시점에 Dirty Checking으로 DB 반영
+ }
public Page findAllDispatch(DispatchSearchDto searchDto, Pageable pageable) {
diff --git a/src/main/java/com/mobility/api/global/entity/BaseEntity.java b/src/main/java/com/mobility/api/global/entity/BaseEntity.java
index 7c481c9..cead1b6 100644
--- a/src/main/java/com/mobility/api/global/entity/BaseEntity.java
+++ b/src/main/java/com/mobility/api/global/entity/BaseEntity.java
@@ -19,11 +19,17 @@
@NoArgsConstructor
public abstract class BaseEntity {
+ // db에 직접 데이터를 넣을 때에도 자동으로 시간이 들어가도록 columnDefinition 설정
@CreationTimestamp
- @Column(name = "created_at", updatable = false)
+ @Column(name = "created_at",
+ updatable = false,
+ nullable = false,
+ columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
private LocalDateTime createdAt;
@UpdateTimestamp
- @Column(name = "updated_at")
+ @Column(name = "updated_at",
+ nullable = false,
+ columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
private LocalDateTime updatedAt;
}
\ No newline at end of file