Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
8 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.factoreal.backend.controller;

import com.factoreal.backend.dto.abnormalLog.AbnormalPagingDto;
import com.factoreal.backend.dto.abnormalLog.SystemLogResponseDto;
import com.factoreal.backend.service.AbnormalLogService;
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.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@Tag(name = "μ‹œμŠ€ν…œ 둜그 API", description = "곡간별 μ‹œμŠ€ν…œ 둜그 쑰회 API")
@RestController
@RequestMapping("/api/system-logs")
@RequiredArgsConstructor
public class SystemLogController {
private final AbnormalLogService abnormalLogService;

@Operation(summary = "곡간별 μ‹œμŠ€ν…œ 둜그 쑰회", description = "νŠΉμ • 곡간(zone)의 μ‹œμŠ€ν…œ 둜그λ₯Ό νŽ˜μ΄μ§• μ²˜λ¦¬ν•˜μ—¬ μ‘°νšŒν•©λ‹ˆλ‹€.")
@GetMapping("/zone/{zoneId}")
public ResponseEntity<Page<SystemLogResponseDto>> getSystemLogsByZone(
@Parameter(description = "μ‘°νšŒν•  곡간 ID", required = true)
@PathVariable String zoneId,
@Parameter(description = "νŽ˜μ΄μ§• 정보 (page: νŽ˜μ΄μ§€ 번호, size: νŽ˜μ΄μ§€ 크기)")
@ModelAttribute AbnormalPagingDto pagingDto) {
Page<SystemLogResponseDto> logs = abnormalLogService.findSystemLogsByZoneId(zoneId, pagingDto);
return ResponseEntity.ok(logs);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.factoreal.backend.controller;

import com.factoreal.backend.dto.WorkerDto;
import com.factoreal.backend.dto.ZoneManagerResponseDto;
import com.factoreal.backend.service.WorkerService;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/workers")
@RequiredArgsConstructor
@Slf4j
@Tag(name = "μž‘μ—…μž API", description = "μž‘μ—…μž 쑰회 API")
public class WorkerController {
private final WorkerService workerService;

@Operation(summary = "전체 μž‘μ—…μž λͺ©λ‘ 쑰회", description = "전체 μž‘μ—…μž λͺ©λ‘μ„ μ‘°νšŒν•©λ‹ˆλ‹€.")
@GetMapping
public ResponseEntity<List<WorkerDto>> getAllWorkers() {
log.info("전체 μž‘μ—…μž λͺ©λ‘ 쑰회 μš”μ²­");
List<WorkerDto> workers = workerService.getAllWorkers();
return ResponseEntity.ok(workers);
}

@Operation(summary = "곡간별 μž‘μ—…μž λͺ©λ‘ 쑰회", description = "곡간 IDλ₯Ό 기반으둜 ν˜„μž¬ ν•΄λ‹Ή 곡간에 λ“€μ–΄κ°€μžˆλŠ” μž‘μ—…μž 리슀트λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.")
@GetMapping("/zone/{zoneId}")
public ResponseEntity<List<WorkerDto>> getWorkersByZoneId(@PathVariable String zoneId) {
log.info("곡간 ID: {}의 μž‘μ—…μž λͺ©λ‘ 쑰회 μš”μ²­", zoneId);
List<WorkerDto> zoneWorkers = workerService.getWorkersByZoneId(zoneId);
return ResponseEntity.ok(zoneWorkers);
}

@Operation(summary = "곡간 λ‹΄λ‹Ήμž 정보 쑰회",
description = "곡간 IDλ₯Ό 기반으둜 ν•΄λ‹Ή κ³΅κ°„μ˜ λ‹΄λ‹Ήμžμ™€ ν˜„μž¬ μœ„μΉ˜ 정보λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€.")
@GetMapping("/zone/{zoneId}/manager")
public ResponseEntity<ZoneManagerResponseDto> getZoneManager(@PathVariable String zoneId) {
log.info("곡간 ID: {}의 λ‹΄λ‹Ήμž 정보 쑰회 μš”μ²­", zoneId);
ZoneManagerResponseDto manager = workerService.getZoneManagerWithLocation(zoneId);
return ResponseEntity.ok(manager);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.factoreal.backend.controller;

import com.factoreal.backend.dto.WorkerLocationRequest;
import com.factoreal.backend.service.WorkerLocationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@Slf4j
@Tag(name = "μž‘μ—…μž μœ„μΉ˜ API", description = "μž‘μ—…μžμ˜ μ‹€μ‹œκ°„ μœ„μΉ˜ 정보λ₯Ό κ΄€λ¦¬ν•˜λŠ” API")
@RestController
@RequestMapping("/api/worker-locations")
@RequiredArgsConstructor
// μ›¨μ–΄λŸ¬λΈ” λ””λ°”μ΄μŠ€μ—μ„œ λ°›μ•„μ˜€λŠ” 데이터λ₯Ό μ—…λ°μ΄νŠΈν•˜λŠ” 컨트둀러
public class WorkerLocationController {

private final WorkerLocationService workerLocationService;

@Operation(summary = "μž‘μ—…μž μœ„μΉ˜ μ—…λ°μ΄νŠΈ", description = "μ›¨μ–΄λŸ¬λΈ” λ””λ°”μ΄μŠ€λ‘œλΆ€ν„° 받은 μž‘μ—…μžμ˜ μœ„μΉ˜ 정보λ₯Ό μ—…λ°μ΄νŠΈν•©λ‹ˆλ‹€.")
@PostMapping("/update")
public ResponseEntity<Void> updateWorkerLocation(@RequestBody WorkerLocationRequest request) {
log.info("μž‘μ—…μž μœ„μΉ˜ μ—…λ°μ΄νŠΈ μš”μ²­: {}", request);
workerLocationService.updateWorkerLocation(
request.getWorkerId(),
request.getZoneId(),
request.getTimestamp() != null ? request.getTimestamp() : LocalDateTime.now()
);
return ResponseEntity.ok().build(); // 200 OK 응닡
}
}
30 changes: 30 additions & 0 deletions src/main/java/com/factoreal/backend/dto/WorkerDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.factoreal.backend.dto;

import com.factoreal.backend.entity.Worker;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class WorkerDto {
private String workerId;
private String name;
private String phoneNumber;
private String email;
private Boolean isManager; // κ΄€λ¦¬μž μ—¬λΆ€

// Entity -> DTO λ³€ν™˜
public static WorkerDto fromEntity(Worker worker, Boolean isManager) {
return WorkerDto.builder()
.workerId(worker.getWorkerId())
.name(worker.getName())
.phoneNumber(worker.getPhoneNumber())
.email(worker.getEmail())
.isManager(isManager)
.build();
}
}
17 changes: 17 additions & 0 deletions src/main/java/com/factoreal/backend/dto/WorkerLocationRequest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.factoreal.backend.dto;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.time.LocalDateTime;

@Getter
@Setter
@ToString
// Wearable μž₯μΉ˜μ—μ„œ λ°›μ•„μ˜€λŠ” 데이터 by 우영. μΆ”ν›„ λ…Όμ˜ μ˜ˆμ •
public class WorkerLocationRequest {
private String workerId;
private String zoneId;
private LocalDateTime timestamp; // μž₯μΉ˜μ—μ„œ λ°›μ•„μ˜€λŠ” 데이터
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.factoreal.backend.dto;

import com.factoreal.backend.entity.Worker;
import com.factoreal.backend.entity.Zone;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
// 곡간 λ‹΄λ‹Ήμž 정보 쑰회 μ‹œ μ‚¬μš©λ˜λŠ” DTO (BE -> FE)
public class ZoneManagerResponseDto {
private String workerId; // μž‘μ—…μž ID
private String name; // μž‘μ—…μž 이름
private String phoneNumber; // μ—°λ½μ²˜
private String email; // 이메일
private String currentZoneId; // ν˜„μž¬ μœ„μΉ˜ν•œ 곡간 ID
private String currentZoneName; // ν˜„μž¬ μœ„μΉ˜ν•œ 곡간 이름

public static ZoneManagerResponseDto fromEntity(Worker worker, Zone currentZone) {
return ZoneManagerResponseDto.builder()
.workerId(worker.getWorkerId())
.name(worker.getName())
.phoneNumber(worker.getPhoneNumber())
.email(worker.getEmail())
.currentZoneId(currentZone != null ? currentZone.getZoneId() : null)
.currentZoneName(currentZone != null ? currentZone.getZoneName() : null)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package com.factoreal.backend.dto.abnormalLog;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

@Data
@Schema(description = "νŽ˜μ΄μ§• 정보 DTO")
public class AbnormalPagingDto {
@Schema(description = "νŽ˜μ΄μ§€ 번호 (0λΆ€ν„° μ‹œμž‘)", example = "0")
private int page;

@Schema(description = "νŽ˜μ΄μ§€ 크기", example = "10")
private int size;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.factoreal.backend.dto.abnormalLog;

import com.factoreal.backend.entity.AbnormalLog;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SystemLogResponseDto {
private String zoneId;
private String targetType;
private String sensorType;
private int dangerLevel;
private double value;
private LocalDateTime timestamp;
private String abnormalType;
private String targetId;

public static SystemLogResponseDto fromEntity(AbnormalLog abnormalLog) {
return SystemLogResponseDto.builder()
.zoneId(abnormalLog.getZone().getZoneId())
.targetType(convertLogTypeToKorean(abnormalLog.getTargetType()))
.sensorType(abnormalLog.getTargetType().toString())
.dangerLevel(calculateDangerLevel(abnormalLog.getAbnormalType()))
.value(abnormalLog.getAbnVal())
.timestamp(abnormalLog.getDetectedAt())
.abnormalType(abnormalLog.getAbnormalType())
.targetId(abnormalLog.getTargetId())
.build();
}

private static String convertLogTypeToKorean(LogType logType) {
return switch (logType) {
case Sensor -> "ν™˜κ²½";
case Worker -> "μž‘μ—…μž";
case Equip -> "μ„€λΉ„";
};
}

private static int calculateDangerLevel(String abnormalType) {
if (abnormalType.contains("μœ„ν—˜")) return 2;
if (abnormalType.contains("주의")) return 1;
return 0;
}
}

/**
* {
"content": [
{
"zoneId": "zone123",
"targetType": "ν™˜κ²½", // λ˜λŠ” "μž‘μ—…μž", "μ„€λΉ„"
"sensorType": "TEMPERATURE",
"dangerLevel": 2,
"value": 35.5,
"timestamp": "2024-03-20T14:30:00",
"abnormalType": "μ˜¨λ„ μœ„ν—˜",
"targetId": "sensor456"
}
// ... 더 λ§Žμ€ 둜그
],
"pageable": {
"pageNumber": 0,
"pageSize": 10
},
"totalElements": 50,
"totalPages": 5
}
*/
3 changes: 2 additions & 1 deletion src/main/java/com/factoreal/backend/entity/AbnormalLog.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ public class AbnormalLog {
private String targetId; // 고유 ID : μ„Όμ„œID, WorkerID, EquipID

@Column(name = "abnormal_type", length = 100)
private String abnormalType; // 이상 μœ ν˜• : (예: μ‹¬λ°•μˆ˜ 이상, μ˜¨λ„ 초과, 진동 이상 λ“±)
private String abnormalType; // 이상 μœ ν˜• : (예: μ‹¬λ°•μˆ˜ μœ„ν—˜, μ˜¨λ„ 초과 μœ„ν—˜, 진동 주의 λ“±)
// 이상은 μœ„ν—˜κ³Ό 주의둜 ꡬ뢄이 μ• λ§€ν•˜λ―€λ‘œ λͺ…ν™•ν•œ ν‘œν˜„ ν•„μš”

@Column(name = "abn_val")
private Double abnVal; // μ΄μƒμΉ˜ κ°’
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public void consume(String message) {
SensorKafkaDto dto = objectMapper.readValue(message, SensorKafkaDto.class);

// μ‹œμŠ€ν…œ 둜그 (μœ„ν—˜λ„ λ³€ν™” 감지 -> 비동기 전솑)
sendSystemLog(dto);
// sendSystemLog(dto);

// 곡간 μ„Όμ„œμΌ λ•Œλ§Œ 히트맡용 μ›Ήμ†ŒμΌ“ 전솑
if (dto.getEquipId() != null && dto.getZoneId() != null && dto.getEquipId().equals(dto.getZoneId())) {
Expand Down Expand Up @@ -164,6 +164,7 @@ public void startAlarm(SensorKafkaDto sensorData, AbnormalLog abnormalLog, RiskL

// 곡간(zone)별 μœ„ν—˜λ„ λ³€κ²½ μ‹œ μ‹œμŠ€ν…œ 둜그 전솑
@Async
@Deprecated
public void sendSystemLog(SensorKafkaDto dto) {
String zoneId = dto.getZoneId();
int newLevel = getDangerLevel(dto.getSensorType(), dto.getVal());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ public interface AbnLogRepository extends JpaRepository<AbnormalLog,Long> {
long countByIsReadFalse(); // 읽지 μ•Šμ€ 둜그의 개수 λ°˜ν™˜

Page<AbnormalLog> findAllByIsReadIsFalse(Pageable pageable);

// zoneId둜 νŽ˜μ΄μ§• 처리된 둜그 쑰회
Page<AbnormalLog> findByZone_ZoneIdOrderByDetectedAtDesc(String zoneId, Pageable pageable);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.factoreal.backend.repository;

import com.factoreal.backend.entity.WorkerZone;
import com.factoreal.backend.entity.WorkerZoneId;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;
import java.util.Optional;

public interface WorkerZoneRepository extends JpaRepository<WorkerZone, WorkerZoneId> {

// νŠΉμ • zone_id에 μ†ν•œ μž‘μ—…μž λͺ©λ‘ 쑰회
List<WorkerZone> findByZoneZoneId(String zoneId);

// νŠΉμ • zone_id의 λ‹΄λ‹Ήμž 쑰회 (manageYn = true)
Optional<WorkerZone> findByZoneZoneIdAndManageYnIsTrue(String zoneId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.factoreal.backend.repository;

import com.factoreal.backend.entity.ZoneHist;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface ZoneHistRepository extends JpaRepository<ZoneHist, Long> {
// νŠΉμ • 곡간에 ν˜„μž¬ μžˆλŠ” μž‘μ—…μžλ“€ 쑰회 (existFlag = 1)
List<ZoneHist> findByZone_ZoneIdAndExistFlag(String zoneId, Integer existFlag);

// νŠΉμ • μž‘μ—…μžμ˜ ν˜„μž¬ μœ„μΉ˜ 쑰회 (existFlag = 1)
ZoneHist findByWorker_WorkerIdAndExistFlag(String workerId, Integer existFlag);
}
Loading