From 1add3bd342969051957943d8d99f80c2ee13aab5 Mon Sep 17 00:00:00 2001 From: danbaram0420 Date: Sun, 31 Aug 2025 23:52:07 +0900 Subject: [PATCH 1/4] ble initial push --- .../domain/ble/dto/request/CreateBLEReq.java | 20 +++++++ .../domain/ble/dto/request/ModifyBLEReq.java | 20 +++++++ .../domain/ble/entity/BLEdevice.java | 54 +++++++++++++++++++ .../domain/ble/entity/BLEstatus.java | 17 ++++++ 4 files changed, 111 insertions(+) create mode 100644 src/main/java/devkor/com/teamcback/domain/ble/dto/request/CreateBLEReq.java create mode 100644 src/main/java/devkor/com/teamcback/domain/ble/dto/request/ModifyBLEReq.java create mode 100644 src/main/java/devkor/com/teamcback/domain/ble/entity/BLEdevice.java create mode 100644 src/main/java/devkor/com/teamcback/domain/ble/entity/BLEstatus.java diff --git a/src/main/java/devkor/com/teamcback/domain/ble/dto/request/CreateBLEReq.java b/src/main/java/devkor/com/teamcback/domain/ble/dto/request/CreateBLEReq.java new file mode 100644 index 00000000..5d2fdb68 --- /dev/null +++ b/src/main/java/devkor/com/teamcback/domain/ble/dto/request/CreateBLEReq.java @@ -0,0 +1,20 @@ +package devkor.com.teamcback.domain.ble.dto.request; + +import devkor.com.teamcback.domain.ble.entity.BLEstatus; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalTime; + +@Schema(description = "BLEdevice 생성 정보") +@Getter +@Setter +public class CreateBLEReq { + @Schema(description = "라운지 설치된 기기명", example = "woodang_1f_lounge") + private String deviceName; + @Schema(description ="라운지 placeId" , example = "2499") + private Long placeId; + @Schema(description = "라운지별 최대정원", example = "20") + private int capacity; +} diff --git a/src/main/java/devkor/com/teamcback/domain/ble/dto/request/ModifyBLEReq.java b/src/main/java/devkor/com/teamcback/domain/ble/dto/request/ModifyBLEReq.java new file mode 100644 index 00000000..6dd92e9b --- /dev/null +++ b/src/main/java/devkor/com/teamcback/domain/ble/dto/request/ModifyBLEReq.java @@ -0,0 +1,20 @@ +package devkor.com.teamcback.domain.ble.dto.request; + +import devkor.com.teamcback.domain.ble.entity.BLEstatus; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalTime; + +@Schema(description = "BLEdevice 수정 정보") +@Getter +@Setter +public class ModifyBLEReq { + @Schema(description = "최근 감지 인원", example = "10") + private int lastCount; + @Schema(description = "최근 Status", example = "AVAILABLE") + private BLEstatus lastStatus; + @Schema(description = "최근 신호 전송 시간") + private LocalTime lastTime; +} diff --git a/src/main/java/devkor/com/teamcback/domain/ble/entity/BLEdevice.java b/src/main/java/devkor/com/teamcback/domain/ble/entity/BLEdevice.java new file mode 100644 index 00000000..614d79f1 --- /dev/null +++ b/src/main/java/devkor/com/teamcback/domain/ble/entity/BLEdevice.java @@ -0,0 +1,54 @@ +package devkor.com.teamcback.domain.ble.entity; + + +import devkor.com.teamcback.domain.ble.dto.request.CreateBLEReq; +import devkor.com.teamcback.domain.ble.dto.request.ModifyBLEReq; +import devkor.com.teamcback.domain.common.entity.BaseEntity; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.time.LocalTime; + +@Entity +@Table(name="tb_ble_device") +@Getter +@Setter +@NoArgsConstructor +public class BLEdevice extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, unique = true) + private String deviceName; + + @Column + private Long placeId; + + @Column + private int capacity; + + @Column + private int lastCount; + + @Column + private BLEstatus lastStatus; + + @Column + private LocalTime lastTime; + + public BLEdevice(CreateBLEReq req){ + this.deviceName = req.getDeviceName(); + this.placeId = req.getPlaceId(); + this.capacity = req.getCapacity(); + } + + public void update(ModifyBLEReq req){ + this.lastCount = req.getLastCount(); + this.lastStatus = req.getLastStatus(); + this.lastTime = req.getLastTime(); + } + +} diff --git a/src/main/java/devkor/com/teamcback/domain/ble/entity/BLEstatus.java b/src/main/java/devkor/com/teamcback/domain/ble/entity/BLEstatus.java new file mode 100644 index 00000000..c628993f --- /dev/null +++ b/src/main/java/devkor/com/teamcback/domain/ble/entity/BLEstatus.java @@ -0,0 +1,17 @@ +package devkor.com.teamcback.domain.ble.entity; + + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum BLEstatus { + VACANT(0, "여유"), + AVAILABLE(1, "보통"), + CROWDED(2, "포화"), + FAILURE(3, "신호없음"); + + private final int code; + private final String label; +} From 5a6b087042155cd35b141e338abdee56381e9ccb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=8A=B9=ED=98=84?= Date: Mon, 1 Sep 2025 19:52:37 +0900 Subject: [PATCH 2/4] =?UTF-8?q?Feat:=20ble=EC=83=9D=EC=84=B1,=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8,=20=EC=A1=B0=ED=9A=8C=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ble/controller/AdminBLEController.java | 41 +++++++++++++ .../domain/ble/controller/BLEController.java | 48 ++++++++++++++++ .../domain/ble/dto/request/CreateBLEReq.java | 3 +- .../{ModifyBLEReq.java => UpdateBLEReq.java} | 12 ++-- .../domain/ble/dto/response/CreateBLERes.java | 15 +++++ .../domain/ble/dto/response/GetBLERes.java | 27 +++++++++ .../domain/ble/dto/response/UpdateBLERes.java | 27 +++++++++ .../entity/{BLEdevice.java => BLEDevice.java} | 31 +++++----- .../ble/repository/BLEDeviceRepository.java | 13 +++++ .../domain/ble/service/AdminBLEService.java | 28 +++++++++ .../domain/ble/service/BLEService.java | 57 +++++++++++++++++++ .../teamcback/global/response/ResultCode.java | 9 ++- 12 files changed, 291 insertions(+), 20 deletions(-) create mode 100644 src/main/java/devkor/com/teamcback/domain/ble/controller/AdminBLEController.java create mode 100644 src/main/java/devkor/com/teamcback/domain/ble/controller/BLEController.java rename src/main/java/devkor/com/teamcback/domain/ble/dto/request/{ModifyBLEReq.java => UpdateBLEReq.java} (57%) create mode 100644 src/main/java/devkor/com/teamcback/domain/ble/dto/response/CreateBLERes.java create mode 100644 src/main/java/devkor/com/teamcback/domain/ble/dto/response/GetBLERes.java create mode 100644 src/main/java/devkor/com/teamcback/domain/ble/dto/response/UpdateBLERes.java rename src/main/java/devkor/com/teamcback/domain/ble/entity/{BLEdevice.java => BLEDevice.java} (51%) create mode 100644 src/main/java/devkor/com/teamcback/domain/ble/repository/BLEDeviceRepository.java create mode 100644 src/main/java/devkor/com/teamcback/domain/ble/service/AdminBLEService.java create mode 100644 src/main/java/devkor/com/teamcback/domain/ble/service/BLEService.java diff --git a/src/main/java/devkor/com/teamcback/domain/ble/controller/AdminBLEController.java b/src/main/java/devkor/com/teamcback/domain/ble/controller/AdminBLEController.java new file mode 100644 index 00000000..39e4ffc9 --- /dev/null +++ b/src/main/java/devkor/com/teamcback/domain/ble/controller/AdminBLEController.java @@ -0,0 +1,41 @@ +package devkor.com.teamcback.domain.ble.controller; + +import devkor.com.teamcback.domain.ble.dto.request.CreateBLEReq; +import devkor.com.teamcback.domain.ble.dto.response.CreateBLERes; +import devkor.com.teamcback.domain.ble.entity.BLEDevice; +import devkor.com.teamcback.domain.ble.service.AdminBLEService; +import devkor.com.teamcback.global.response.CommonResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import jakarta.validation.Valid; +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; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/admin/ble") +public class AdminBLEController { + private final AdminBLEService adminBLEService; + + @PostMapping + @Operation(summary = "BLE장비 생성", + description = "BLE장비 생성") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "정상 처리 되었습니다."), + @ApiResponse(responseCode = "404", description = "건물을 찾을 수 없습니다.", + content = @Content(schema = @Schema(implementation = CommonResponse.class))), + @ApiResponse(responseCode = "401", description = "권한이 없습니다.", + content = @Content(schema = @Schema(implementation = CommonResponse.class))), + }) + public CommonResponse createBLE( + @Parameter(description = "BLE장비 생성 요청 dto") @Valid @RequestBody CreateBLEReq createBLEReq) { + return CommonResponse.success(adminBLEService.CreateBLEDevice(createBLEReq)); + } +} diff --git a/src/main/java/devkor/com/teamcback/domain/ble/controller/BLEController.java b/src/main/java/devkor/com/teamcback/domain/ble/controller/BLEController.java new file mode 100644 index 00000000..db1d3dbb --- /dev/null +++ b/src/main/java/devkor/com/teamcback/domain/ble/controller/BLEController.java @@ -0,0 +1,48 @@ +package devkor.com.teamcback.domain.ble.controller; + +import devkor.com.teamcback.domain.ble.dto.request.UpdateBLEReq; +import devkor.com.teamcback.domain.ble.dto.response.GetBLERes; +import devkor.com.teamcback.domain.ble.dto.response.UpdateBLERes; +import devkor.com.teamcback.domain.ble.service.BLEService; +import devkor.com.teamcback.global.response.CommonResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/ble") + +public class BLEController { + private final BLEService bleService; + + /*** + * + * @param placeId BLE정보를 얻고자 하는 place Id + */ + @GetMapping + @Operation(summary = "placeId를 통한 BLE device 상태 요청", + description = "placeId를 통한 BLE device 상태 요청") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "정상 처리 되었습니다."), + @ApiResponse(responseCode = "404", description = "Not Found", + content = @Content(schema = @Schema(implementation = CommonResponse.class))), + }) + public CommonResponse getBLE( + @Parameter(name="placeId", description = "BLE 정보를 얻고자 하는 placeId") + @RequestParam Long placeId) { + return CommonResponse.success(bleService.getBLE(placeId)); + } + + @PutMapping + public CommonResponse updateBLE( + @Valid @RequestBody UpdateBLEReq updateBLEReq){ + return CommonResponse.success(bleService.updateBLEDevice(updateBLEReq)); + } +} diff --git a/src/main/java/devkor/com/teamcback/domain/ble/dto/request/CreateBLEReq.java b/src/main/java/devkor/com/teamcback/domain/ble/dto/request/CreateBLEReq.java index 5d2fdb68..72266bb5 100644 --- a/src/main/java/devkor/com/teamcback/domain/ble/dto/request/CreateBLEReq.java +++ b/src/main/java/devkor/com/teamcback/domain/ble/dto/request/CreateBLEReq.java @@ -1,6 +1,7 @@ package devkor.com.teamcback.domain.ble.dto.request; import devkor.com.teamcback.domain.ble.entity.BLEstatus; +import devkor.com.teamcback.domain.place.entity.Place; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.Setter; @@ -13,7 +14,7 @@ public class CreateBLEReq { @Schema(description = "라운지 설치된 기기명", example = "woodang_1f_lounge") private String deviceName; - @Schema(description ="라운지 placeId" , example = "2499") + @Schema(description ="라운지 place") private Long placeId; @Schema(description = "라운지별 최대정원", example = "20") private int capacity; diff --git a/src/main/java/devkor/com/teamcback/domain/ble/dto/request/ModifyBLEReq.java b/src/main/java/devkor/com/teamcback/domain/ble/dto/request/UpdateBLEReq.java similarity index 57% rename from src/main/java/devkor/com/teamcback/domain/ble/dto/request/ModifyBLEReq.java rename to src/main/java/devkor/com/teamcback/domain/ble/dto/request/UpdateBLEReq.java index 6dd92e9b..4af66dc7 100644 --- a/src/main/java/devkor/com/teamcback/domain/ble/dto/request/ModifyBLEReq.java +++ b/src/main/java/devkor/com/teamcback/domain/ble/dto/request/UpdateBLEReq.java @@ -1,20 +1,22 @@ package devkor.com.teamcback.domain.ble.dto.request; +import com.fasterxml.jackson.annotation.JsonFormat; import devkor.com.teamcback.domain.ble.entity.BLEstatus; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; import lombok.Setter; -import java.time.LocalTime; +import java.time.LocalDateTime; @Schema(description = "BLEdevice 수정 정보") @Getter @Setter -public class ModifyBLEReq { +public class UpdateBLEReq { + @Schema(description = "라운지 설치된 기기명", example = "woodang_1f_lounge") + private String deviceName; @Schema(description = "최근 감지 인원", example = "10") private int lastCount; - @Schema(description = "최근 Status", example = "AVAILABLE") - private BLEstatus lastStatus; @Schema(description = "최근 신호 전송 시간") - private LocalTime lastTime; + @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") + private LocalDateTime lastTime; } diff --git a/src/main/java/devkor/com/teamcback/domain/ble/dto/response/CreateBLERes.java b/src/main/java/devkor/com/teamcback/domain/ble/dto/response/CreateBLERes.java new file mode 100644 index 00000000..68577888 --- /dev/null +++ b/src/main/java/devkor/com/teamcback/domain/ble/dto/response/CreateBLERes.java @@ -0,0 +1,15 @@ +package devkor.com.teamcback.domain.ble.dto.response; + +import devkor.com.teamcback.domain.ble.entity.BLEDevice; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; + +@Schema(description = "BLEdevice 생성 정보") +@Getter +public class CreateBLERes { + private Long id; + + public CreateBLERes(BLEDevice bleDevice) { + this.id = bleDevice.getId(); + } +} diff --git a/src/main/java/devkor/com/teamcback/domain/ble/dto/response/GetBLERes.java b/src/main/java/devkor/com/teamcback/domain/ble/dto/response/GetBLERes.java new file mode 100644 index 00000000..9c5b03ad --- /dev/null +++ b/src/main/java/devkor/com/teamcback/domain/ble/dto/response/GetBLERes.java @@ -0,0 +1,27 @@ +package devkor.com.teamcback.domain.ble.dto.response; + +import devkor.com.teamcback.domain.ble.entity.BLEDevice; +import lombok.Getter; + +import java.time.LocalDateTime; + +@Getter +public class GetBLERes { + private Long id; + private String deviceName; + private Long placeId; + private int capacity; + private int lastCount; + private int lastStatus; + private LocalDateTime lastTime; + + public GetBLERes(BLEDevice device) { + this.id = device.getId(); + this.deviceName = device.getDeviceName(); + this.placeId = device.getPlace().getId(); + this.capacity = device.getCapacity(); + this.lastCount = device.getLastCount(); + this.lastStatus = device.getLastStatus().getCode(); + this.lastTime = device.getLastTime(); + } +} diff --git a/src/main/java/devkor/com/teamcback/domain/ble/dto/response/UpdateBLERes.java b/src/main/java/devkor/com/teamcback/domain/ble/dto/response/UpdateBLERes.java new file mode 100644 index 00000000..2388fc02 --- /dev/null +++ b/src/main/java/devkor/com/teamcback/domain/ble/dto/response/UpdateBLERes.java @@ -0,0 +1,27 @@ +package devkor.com.teamcback.domain.ble.dto.response; + +import devkor.com.teamcback.domain.ble.entity.BLEDevice; +import devkor.com.teamcback.domain.ble.entity.BLEstatus; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; + +import java.time.LocalDateTime; + +@Getter +public class UpdateBLERes { + @Schema(description = "라운지 설치된 기기명", example = "woodang_1f_lounge") + private String deviceName; + @Schema(description = "최근 감지 인원", example = "10") + private int lastCount; + @Schema(description = "최근 Status", example = "AVAILABLE") + private BLEstatus lastStatus; + @Schema(description = "최근 신호 전송 시간") + private LocalDateTime lastTime; + + public UpdateBLERes(BLEDevice device) { + this.deviceName = device.getDeviceName(); + this.lastCount = device.getLastCount(); + this.lastStatus = device.getLastStatus(); + this.lastTime = device.getLastTime(); + } +} diff --git a/src/main/java/devkor/com/teamcback/domain/ble/entity/BLEdevice.java b/src/main/java/devkor/com/teamcback/domain/ble/entity/BLEDevice.java similarity index 51% rename from src/main/java/devkor/com/teamcback/domain/ble/entity/BLEdevice.java rename to src/main/java/devkor/com/teamcback/domain/ble/entity/BLEDevice.java index 614d79f1..0d9c47e2 100644 --- a/src/main/java/devkor/com/teamcback/domain/ble/entity/BLEdevice.java +++ b/src/main/java/devkor/com/teamcback/domain/ble/entity/BLEDevice.java @@ -1,22 +1,22 @@ package devkor.com.teamcback.domain.ble.entity; -import devkor.com.teamcback.domain.ble.dto.request.CreateBLEReq; -import devkor.com.teamcback.domain.ble.dto.request.ModifyBLEReq; +import devkor.com.teamcback.domain.ble.dto.request.UpdateBLEReq; import devkor.com.teamcback.domain.common.entity.BaseEntity; +import devkor.com.teamcback.domain.place.entity.Place; import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import java.time.LocalTime; +import java.time.LocalDateTime; @Entity @Table(name="tb_ble_device") @Getter @Setter @NoArgsConstructor -public class BLEdevice extends BaseEntity { +public class BLEDevice extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -24,8 +24,9 @@ public class BLEdevice extends BaseEntity { @Column(nullable = false, unique = true) private String deviceName; - @Column - private Long placeId; + @OneToOne + @JoinColumn(name = "placeId") + private Place place; @Column private int capacity; @@ -37,18 +38,22 @@ public class BLEdevice extends BaseEntity { private BLEstatus lastStatus; @Column - private LocalTime lastTime; + private LocalDateTime lastTime; - public BLEdevice(CreateBLEReq req){ - this.deviceName = req.getDeviceName(); - this.placeId = req.getPlaceId(); - this.capacity = req.getCapacity(); + public BLEDevice(String deviceName, Place place, int capacity) { + this.deviceName = deviceName; + this.place = place; + this.capacity = capacity; } - public void update(ModifyBLEReq req){ + public void update(UpdateBLEReq req, BLEstatus status) { this.lastCount = req.getLastCount(); - this.lastStatus = req.getLastStatus(); + this.lastStatus = status; this.lastTime = req.getLastTime(); } + public void update(BLEstatus status){ + this.lastStatus = status; + } + } diff --git a/src/main/java/devkor/com/teamcback/domain/ble/repository/BLEDeviceRepository.java b/src/main/java/devkor/com/teamcback/domain/ble/repository/BLEDeviceRepository.java new file mode 100644 index 00000000..64f254e8 --- /dev/null +++ b/src/main/java/devkor/com/teamcback/domain/ble/repository/BLEDeviceRepository.java @@ -0,0 +1,13 @@ +package devkor.com.teamcback.domain.ble.repository; + +import devkor.com.teamcback.domain.ble.entity.BLEDevice; +import devkor.com.teamcback.domain.place.entity.Place; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface BLEDeviceRepository extends JpaRepository { + List findByDeviceName(String deviceName); + List findByPlace(Place place); + boolean existsByDeviceName(String deviceName); +} diff --git a/src/main/java/devkor/com/teamcback/domain/ble/service/AdminBLEService.java b/src/main/java/devkor/com/teamcback/domain/ble/service/AdminBLEService.java new file mode 100644 index 00000000..c80d52f7 --- /dev/null +++ b/src/main/java/devkor/com/teamcback/domain/ble/service/AdminBLEService.java @@ -0,0 +1,28 @@ +package devkor.com.teamcback.domain.ble.service; + +import devkor.com.teamcback.domain.ble.dto.request.CreateBLEReq; +import devkor.com.teamcback.domain.ble.dto.response.CreateBLERes; +import devkor.com.teamcback.domain.ble.entity.BLEDevice; +import devkor.com.teamcback.domain.ble.repository.BLEDeviceRepository; +import devkor.com.teamcback.domain.place.entity.Place; +import devkor.com.teamcback.domain.place.repository.PlaceRepository; +import devkor.com.teamcback.global.exception.exception.GlobalException; +import devkor.com.teamcback.global.response.ResultCode; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class AdminBLEService { + private final BLEDeviceRepository bleDeviceRepository; + private final PlaceRepository placeRepository; + + @Transactional + public CreateBLERes CreateBLEDevice(CreateBLEReq createBLEReq) { + Place place = placeRepository.findById(createBLEReq.getPlaceId()).orElse(null); + if (bleDeviceRepository.existsByDeviceName(createBLEReq.getDeviceName())) throw new GlobalException(ResultCode.EXISTING_DEVICE_NAME); + BLEDevice bleDevice = bleDeviceRepository.save(new BLEDevice(createBLEReq.getDeviceName(), place, createBLEReq.getCapacity())); + return new CreateBLERes(bleDevice); + } +} diff --git a/src/main/java/devkor/com/teamcback/domain/ble/service/BLEService.java b/src/main/java/devkor/com/teamcback/domain/ble/service/BLEService.java new file mode 100644 index 00000000..92541fe9 --- /dev/null +++ b/src/main/java/devkor/com/teamcback/domain/ble/service/BLEService.java @@ -0,0 +1,57 @@ +package devkor.com.teamcback.domain.ble.service; + + +import devkor.com.teamcback.domain.ble.dto.request.UpdateBLEReq; +import devkor.com.teamcback.domain.ble.dto.response.GetBLERes; +import devkor.com.teamcback.domain.ble.dto.response.UpdateBLERes; +import devkor.com.teamcback.domain.ble.entity.BLEDevice; +import devkor.com.teamcback.domain.ble.entity.BLEstatus; +import devkor.com.teamcback.domain.ble.repository.BLEDeviceRepository; +import devkor.com.teamcback.domain.place.entity.Place; +import devkor.com.teamcback.domain.place.repository.PlaceRepository; +import devkor.com.teamcback.global.exception.exception.GlobalException; +import devkor.com.teamcback.global.response.ResultCode; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.List; + +@Slf4j +@Service +@RequiredArgsConstructor +public class BLEService { + private final BLEDeviceRepository blEdeviceRepository; + private final PlaceRepository placeRepository; + + @Transactional + public UpdateBLERes updateBLEDevice(UpdateBLEReq updateBLEReq) { + List deviceList = blEdeviceRepository.findByDeviceName(updateBLEReq.getDeviceName()); + if (deviceList.isEmpty()) throw new GlobalException(ResultCode.NOT_FOUND_DEVICE_NAME); + BLEDevice bleDevice = deviceList.get(0); + double ratio = (double) updateBLEReq.getLastCount() /bleDevice.getCapacity(); + BLEstatus status; + if (ratio < 0.3) status = BLEstatus.VACANT; + else if (ratio < 0.7) status = BLEstatus.AVAILABLE; + else status = BLEstatus.CROWDED; + bleDevice.update(updateBLEReq, status); + return new UpdateBLERes(bleDevice); + } + + @Transactional(readOnly = true) + public GetBLERes getBLE(Long placeId) { + LocalDateTime now = LocalDateTime.now(); + Place place = placeRepository.findById(placeId).orElse(null); + List devices = blEdeviceRepository.findByPlace(place); + if (devices.isEmpty()) throw new GlobalException(ResultCode.NOT_FOUND_DEVICE); + BLEDevice device = devices.get(0); + if (Duration.between(device.getLastTime(),now).toMinutes() >= 30) { + device.update(BLEstatus.FAILURE); + }; + return new GetBLERes(device); + } + +} diff --git a/src/main/java/devkor/com/teamcback/global/response/ResultCode.java b/src/main/java/devkor/com/teamcback/global/response/ResultCode.java index 880c15ad..d3c536e2 100644 --- a/src/main/java/devkor/com/teamcback/global/response/ResultCode.java +++ b/src/main/java/devkor/com/teamcback/global/response/ResultCode.java @@ -74,7 +74,14 @@ public enum ResultCode { OPER_CONDITION_HAS_NO_OPER_TIME(HttpStatus.NOT_FOUND, 10000, "운영 조건이 운영 시간을 가지고 있지 않습니다."), // 고연전 11000번대 - NOT_FOUND_TAG(HttpStatus.NOT_FOUND, 11000, "음식 태그를 찾을 수 없습니다.") + NOT_FOUND_TAG(HttpStatus.NOT_FOUND, 11000, "음식 태그를 찾을 수 없습니다."), + + + //ble 12000번대 + NOT_FOUND_DEVICE(HttpStatus.NOT_FOUND, 12000, "해당 placeId에 해당하는 device가 없습니다."), + NOT_FOUND_DEVICE_NAME(HttpStatus.NOT_FOUND, 12001, "해당 device 이름이 없습니다."), + EXISTING_DEVICE_NAME(HttpStatus.CONFLICT, 12002, "중복되는 device 이름입니다."), + ; private final HttpStatus status; From fb6e0862334700b95b2e2e955a09a364fd20e1fb Mon Sep 17 00:00:00 2001 From: danbaram0420 Date: Sun, 14 Sep 2025 22:22:39 +0900 Subject: [PATCH 3/4] resolve resultcode conflict --- .../teamcback/global/response/ResultCode.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main/java/devkor/com/teamcback/global/response/ResultCode.java b/src/main/java/devkor/com/teamcback/global/response/ResultCode.java index d3c536e2..30a79ff3 100644 --- a/src/main/java/devkor/com/teamcback/global/response/ResultCode.java +++ b/src/main/java/devkor/com/teamcback/global/response/ResultCode.java @@ -73,18 +73,23 @@ public enum ResultCode { // 운영 시간 10000번대 OPER_CONDITION_HAS_NO_OPER_TIME(HttpStatus.NOT_FOUND, 10000, "운영 조건이 운영 시간을 가지고 있지 않습니다."), - // 고연전 11000번대 + // 행사 11000번대 NOT_FOUND_TAG(HttpStatus.NOT_FOUND, 11000, "음식 태그를 찾을 수 없습니다."), + NOT_FOUND_SCHOOL_CALENDAR(HttpStatus.NOT_FOUND, 11001, "관련 일정을 찾을 수 없습니다."), + // 투표 12000번대 + NOT_FOUND_VOTE(HttpStatus.NOT_FOUND, 12000, "투표를 찾을 수 없습니다."), + NOT_FOUND_VOTE_TOPIC(HttpStatus.NOT_FOUND, 12001, "투표 주제를 찾을 수 없습니다."), + NOT_FOUND_VOTE_OPTION(HttpStatus.NOT_FOUND, 12002, "투표 항목을 찾을 수 없습니다."), + CLOSED_VOTE(HttpStatus.BAD_REQUEST, 12003, "종료된 투표입니다."), - //ble 12000번대 - NOT_FOUND_DEVICE(HttpStatus.NOT_FOUND, 12000, "해당 placeId에 해당하는 device가 없습니다."), - NOT_FOUND_DEVICE_NAME(HttpStatus.NOT_FOUND, 12001, "해당 device 이름이 없습니다."), - EXISTING_DEVICE_NAME(HttpStatus.CONFLICT, 12002, "중복되는 device 이름입니다."), - + //ble 13000번대 + NOT_FOUND_DEVICE(HttpStatus.NOT_FOUND, 13000, "해당 placeId에 해당하는 device가 없습니다."), + NOT_FOUND_DEVICE_NAME(HttpStatus.NOT_FOUND, 13001, "해당 device 이름이 없습니다."), + EXISTING_DEVICE_NAME(HttpStatus.CONFLICT, 13002, "중복되는 device 이름입니다."), ; private final HttpStatus status; private final int code; private final String message; -} +} \ No newline at end of file From 9def626f79709bdea39042368c0fa1b01657b0b1 Mon Sep 17 00:00:00 2001 From: danbaram0420 Date: Sun, 14 Sep 2025 23:35:00 +0900 Subject: [PATCH 4/4] =?UTF-8?q?data=20=ED=85=8C=EC=9D=B4=EB=B8=94=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ble/controller/AdminBLEController.java | 2 +- .../domain/ble/dto/response/GetBLERes.java | 10 +++--- .../domain/ble/dto/response/UpdateBLERes.java | 14 ++++---- .../teamcback/domain/ble/entity/BLEData.java | 36 +++++++++++++++++++ .../domain/ble/entity/BLEDevice.java | 19 ---------- .../ble/repository/BLEDataRepository.java | 12 +++++++ .../domain/ble/service/AdminBLEService.java | 4 ++- .../domain/ble/service/BLEService.java | 36 +++++++++++++------ .../teamcback/global/response/ResultCode.java | 1 + 9 files changed, 92 insertions(+), 42 deletions(-) create mode 100644 src/main/java/devkor/com/teamcback/domain/ble/entity/BLEData.java create mode 100644 src/main/java/devkor/com/teamcback/domain/ble/repository/BLEDataRepository.java diff --git a/src/main/java/devkor/com/teamcback/domain/ble/controller/AdminBLEController.java b/src/main/java/devkor/com/teamcback/domain/ble/controller/AdminBLEController.java index 39e4ffc9..8475a12c 100644 --- a/src/main/java/devkor/com/teamcback/domain/ble/controller/AdminBLEController.java +++ b/src/main/java/devkor/com/teamcback/domain/ble/controller/AdminBLEController.java @@ -29,7 +29,7 @@ public class AdminBLEController { description = "BLE장비 생성") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "정상 처리 되었습니다."), - @ApiResponse(responseCode = "404", description = "건물을 찾을 수 없습니다.", + @ApiResponse(responseCode = "404", description = "장비를 찾을 수 없습니다.", content = @Content(schema = @Schema(implementation = CommonResponse.class))), @ApiResponse(responseCode = "401", description = "권한이 없습니다.", content = @Content(schema = @Schema(implementation = CommonResponse.class))), diff --git a/src/main/java/devkor/com/teamcback/domain/ble/dto/response/GetBLERes.java b/src/main/java/devkor/com/teamcback/domain/ble/dto/response/GetBLERes.java index 9c5b03ad..716ea1b0 100644 --- a/src/main/java/devkor/com/teamcback/domain/ble/dto/response/GetBLERes.java +++ b/src/main/java/devkor/com/teamcback/domain/ble/dto/response/GetBLERes.java @@ -1,6 +1,8 @@ package devkor.com.teamcback.domain.ble.dto.response; +import devkor.com.teamcback.domain.ble.entity.BLEData; import devkor.com.teamcback.domain.ble.entity.BLEDevice; +import devkor.com.teamcback.domain.ble.entity.BLEstatus; import lombok.Getter; import java.time.LocalDateTime; @@ -15,13 +17,13 @@ public class GetBLERes { private int lastStatus; private LocalDateTime lastTime; - public GetBLERes(BLEDevice device) { + public GetBLERes(BLEDevice device, BLEData data, BLEstatus status) { this.id = device.getId(); this.deviceName = device.getDeviceName(); this.placeId = device.getPlace().getId(); this.capacity = device.getCapacity(); - this.lastCount = device.getLastCount(); - this.lastStatus = device.getLastStatus().getCode(); - this.lastTime = device.getLastTime(); + this.lastCount = data.getLastCount(); + this.lastStatus = status.getCode(); + this.lastTime = data.getLastTime(); } } diff --git a/src/main/java/devkor/com/teamcback/domain/ble/dto/response/UpdateBLERes.java b/src/main/java/devkor/com/teamcback/domain/ble/dto/response/UpdateBLERes.java index 2388fc02..f6d515b3 100644 --- a/src/main/java/devkor/com/teamcback/domain/ble/dto/response/UpdateBLERes.java +++ b/src/main/java/devkor/com/teamcback/domain/ble/dto/response/UpdateBLERes.java @@ -1,6 +1,6 @@ package devkor.com.teamcback.domain.ble.dto.response; -import devkor.com.teamcback.domain.ble.entity.BLEDevice; +import devkor.com.teamcback.domain.ble.entity.BLEData; import devkor.com.teamcback.domain.ble.entity.BLEstatus; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; @@ -10,7 +10,7 @@ @Getter public class UpdateBLERes { @Schema(description = "라운지 설치된 기기명", example = "woodang_1f_lounge") - private String deviceName; + private Long deviceId; @Schema(description = "최근 감지 인원", example = "10") private int lastCount; @Schema(description = "최근 Status", example = "AVAILABLE") @@ -18,10 +18,10 @@ public class UpdateBLERes { @Schema(description = "최근 신호 전송 시간") private LocalDateTime lastTime; - public UpdateBLERes(BLEDevice device) { - this.deviceName = device.getDeviceName(); - this.lastCount = device.getLastCount(); - this.lastStatus = device.getLastStatus(); - this.lastTime = device.getLastTime(); + public UpdateBLERes(BLEData data) { + this.deviceId = data.getDevice().getId(); + this.lastCount = data.getLastCount(); + this.lastStatus = data.getLastStatus(); + this.lastTime = data.getLastTime(); } } diff --git a/src/main/java/devkor/com/teamcback/domain/ble/entity/BLEData.java b/src/main/java/devkor/com/teamcback/domain/ble/entity/BLEData.java new file mode 100644 index 00000000..89ec79da --- /dev/null +++ b/src/main/java/devkor/com/teamcback/domain/ble/entity/BLEData.java @@ -0,0 +1,36 @@ +package devkor.com.teamcback.domain.ble.entity; + + +import devkor.com.teamcback.domain.ble.dto.request.UpdateBLEReq; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.time.LocalDateTime; + +@Entity +@Table(name="tb_ble_data") +@Getter +@Setter +@NoArgsConstructor +public class BLEData { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(optional = false, fetch = FetchType.LAZY) + @JoinColumn(name = "device_id", nullable = false) + private BLEDevice device; + + @Column + private Integer lastCount; + + @Enumerated(EnumType.ORDINAL) + @Column + private BLEstatus lastStatus; + + @Column(nullable = false) + private LocalDateTime lastTime; + +} diff --git a/src/main/java/devkor/com/teamcback/domain/ble/entity/BLEDevice.java b/src/main/java/devkor/com/teamcback/domain/ble/entity/BLEDevice.java index 0d9c47e2..e5d7dca6 100644 --- a/src/main/java/devkor/com/teamcback/domain/ble/entity/BLEDevice.java +++ b/src/main/java/devkor/com/teamcback/domain/ble/entity/BLEDevice.java @@ -31,29 +31,10 @@ public class BLEDevice extends BaseEntity { @Column private int capacity; - @Column - private int lastCount; - - @Column - private BLEstatus lastStatus; - - @Column - private LocalDateTime lastTime; - public BLEDevice(String deviceName, Place place, int capacity) { this.deviceName = deviceName; this.place = place; this.capacity = capacity; } - public void update(UpdateBLEReq req, BLEstatus status) { - this.lastCount = req.getLastCount(); - this.lastStatus = status; - this.lastTime = req.getLastTime(); - } - - public void update(BLEstatus status){ - this.lastStatus = status; - } - } diff --git a/src/main/java/devkor/com/teamcback/domain/ble/repository/BLEDataRepository.java b/src/main/java/devkor/com/teamcback/domain/ble/repository/BLEDataRepository.java new file mode 100644 index 00000000..d03d497f --- /dev/null +++ b/src/main/java/devkor/com/teamcback/domain/ble/repository/BLEDataRepository.java @@ -0,0 +1,12 @@ +package devkor.com.teamcback.domain.ble.repository; + +import devkor.com.teamcback.domain.ble.entity.BLEData; +import devkor.com.teamcback.domain.ble.entity.BLEDevice; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.repository.CrudRepository; + +import java.util.Optional; + +public interface BLEDataRepository extends JpaRepository { + Optional findTopByDeviceOrderByLastTimeDesc(BLEDevice device); +} diff --git a/src/main/java/devkor/com/teamcback/domain/ble/service/AdminBLEService.java b/src/main/java/devkor/com/teamcback/domain/ble/service/AdminBLEService.java index c80d52f7..4ecc8885 100644 --- a/src/main/java/devkor/com/teamcback/domain/ble/service/AdminBLEService.java +++ b/src/main/java/devkor/com/teamcback/domain/ble/service/AdminBLEService.java @@ -12,6 +12,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import static devkor.com.teamcback.global.response.ResultCode.NOT_FOUND_PLACE; + @Service @RequiredArgsConstructor public class AdminBLEService { @@ -20,7 +22,7 @@ public class AdminBLEService { @Transactional public CreateBLERes CreateBLEDevice(CreateBLEReq createBLEReq) { - Place place = placeRepository.findById(createBLEReq.getPlaceId()).orElse(null); + Place place = placeRepository.findById(createBLEReq.getPlaceId()).orElseThrow(() -> new GlobalException(NOT_FOUND_PLACE)); if (bleDeviceRepository.existsByDeviceName(createBLEReq.getDeviceName())) throw new GlobalException(ResultCode.EXISTING_DEVICE_NAME); BLEDevice bleDevice = bleDeviceRepository.save(new BLEDevice(createBLEReq.getDeviceName(), place, createBLEReq.getCapacity())); return new CreateBLERes(bleDevice); diff --git a/src/main/java/devkor/com/teamcback/domain/ble/service/BLEService.java b/src/main/java/devkor/com/teamcback/domain/ble/service/BLEService.java index 92541fe9..a1bbc85c 100644 --- a/src/main/java/devkor/com/teamcback/domain/ble/service/BLEService.java +++ b/src/main/java/devkor/com/teamcback/domain/ble/service/BLEService.java @@ -4,8 +4,10 @@ import devkor.com.teamcback.domain.ble.dto.request.UpdateBLEReq; import devkor.com.teamcback.domain.ble.dto.response.GetBLERes; import devkor.com.teamcback.domain.ble.dto.response.UpdateBLERes; +import devkor.com.teamcback.domain.ble.entity.BLEData; import devkor.com.teamcback.domain.ble.entity.BLEDevice; import devkor.com.teamcback.domain.ble.entity.BLEstatus; +import devkor.com.teamcback.domain.ble.repository.BLEDataRepository; import devkor.com.teamcback.domain.ble.repository.BLEDeviceRepository; import devkor.com.teamcback.domain.place.entity.Place; import devkor.com.teamcback.domain.place.repository.PlaceRepository; @@ -20,16 +22,19 @@ import java.time.LocalDateTime; import java.util.List; +import static devkor.com.teamcback.global.response.ResultCode.NOT_FOUND_PLACE; + @Slf4j @Service @RequiredArgsConstructor public class BLEService { - private final BLEDeviceRepository blEdeviceRepository; + private final BLEDeviceRepository bledeviceRepository; + private final BLEDataRepository bleDataRepository; private final PlaceRepository placeRepository; @Transactional public UpdateBLERes updateBLEDevice(UpdateBLEReq updateBLEReq) { - List deviceList = blEdeviceRepository.findByDeviceName(updateBLEReq.getDeviceName()); + List deviceList = bledeviceRepository.findByDeviceName(updateBLEReq.getDeviceName()); if (deviceList.isEmpty()) throw new GlobalException(ResultCode.NOT_FOUND_DEVICE_NAME); BLEDevice bleDevice = deviceList.get(0); double ratio = (double) updateBLEReq.getLastCount() /bleDevice.getCapacity(); @@ -37,21 +42,32 @@ public UpdateBLERes updateBLEDevice(UpdateBLEReq updateBLEReq) { if (ratio < 0.3) status = BLEstatus.VACANT; else if (ratio < 0.7) status = BLEstatus.AVAILABLE; else status = BLEstatus.CROWDED; - bleDevice.update(updateBLEReq, status); - return new UpdateBLERes(bleDevice); + + BLEData bleData = new BLEData(); + bleData.setDevice(bleDevice); + bleData.setLastCount(updateBLEReq.getLastCount()); + bleData.setLastStatus(status); + bleData.setLastTime(updateBLEReq.getLastTime()); + bleDataRepository.save(bleData); + + return new UpdateBLERes(bleData); } @Transactional(readOnly = true) public GetBLERes getBLE(Long placeId) { LocalDateTime now = LocalDateTime.now(); - Place place = placeRepository.findById(placeId).orElse(null); - List devices = blEdeviceRepository.findByPlace(place); + Place place = placeRepository.findById(placeId).orElseThrow(() -> new GlobalException(NOT_FOUND_PLACE)); + List devices = bledeviceRepository.findByPlace(place); if (devices.isEmpty()) throw new GlobalException(ResultCode.NOT_FOUND_DEVICE); BLEDevice device = devices.get(0); - if (Duration.between(device.getLastTime(),now).toMinutes() >= 30) { - device.update(BLEstatus.FAILURE); - }; - return new GetBLERes(device); + BLEData latest = bleDataRepository.findTopByDeviceOrderByLastTimeDesc(device).orElseThrow(() -> new GlobalException(ResultCode.NO_DATA_FOR_DEVICE)); + BLEstatus status; + if (latest.getLastTime() == null || + Duration.between(latest.getLastTime(), LocalDateTime.now()).toMinutes() >= 30) { + status = BLEstatus.FAILURE; + } + else status = latest.getLastStatus(); + return new GetBLERes(device, latest, status); } } diff --git a/src/main/java/devkor/com/teamcback/global/response/ResultCode.java b/src/main/java/devkor/com/teamcback/global/response/ResultCode.java index 30a79ff3..90c588d7 100644 --- a/src/main/java/devkor/com/teamcback/global/response/ResultCode.java +++ b/src/main/java/devkor/com/teamcback/global/response/ResultCode.java @@ -87,6 +87,7 @@ public enum ResultCode { NOT_FOUND_DEVICE(HttpStatus.NOT_FOUND, 13000, "해당 placeId에 해당하는 device가 없습니다."), NOT_FOUND_DEVICE_NAME(HttpStatus.NOT_FOUND, 13001, "해당 device 이름이 없습니다."), EXISTING_DEVICE_NAME(HttpStatus.CONFLICT, 13002, "중복되는 device 이름입니다."), + NO_DATA_FOR_DEVICE(HttpStatus.NOT_FOUND, 13003, "device에 해당하는 정보가 없습니다.") ; private final HttpStatus status;