Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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,19 @@
package capstone.checkIT.DTO.LocationDTO;


import lombok.Getter;
import lombok.Setter;

import java.math.BigDecimal;
import java.sql.Timestamp;

@Getter
@Setter
public class LocationRequestDTO {
private Long id; //디바이스아이디
private BigDecimal latitude; // 위도
private BigDecimal longitude; // 경도
private BigDecimal velocity; // 속도
private Timestamp time; // 기록 시간
private Timestamp startTime; // 시작 시간
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package capstone.checkIT.DTO.LocationDTO;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.math.BigDecimal;
import java.sql.Timestamp;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class LocationResponseDTO {
private Long id; // Location ID
private BigDecimal latitude; // 위도
private BigDecimal longitude; // 경도
private BigDecimal velocity; // 속도
private Timestamp time; // 기록 시간
private Timestamp startTime; // 시작 시간
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public enum ErrorStatus implements BaseCode {

example(HttpStatus.BAD_REQUEST, "example4001", "예시 에러코드입니다."),


// Member
LOGIN_ERROR_EMAIL(HttpStatus.BAD_REQUEST, "LOGIN4001", "해당 사용자가 존재하지 않습니다."),
MEMBER_DUPLICATE(HttpStatus.BAD_REQUEST, "LOGIN4002", "이미 로그인 하셨습니다."),
LOGIN_ERROR_PW(HttpStatus.BAD_REQUEST, "LOGIN4003", "올바르지 않은 비밀번호입니다"),
Expand All @@ -26,8 +26,13 @@ public enum ErrorStatus implements BaseCode {

// DEVICE
DEVICE_NOT_FOUND(HttpStatus.UNAUTHORIZED, "DEVICE4001", "해당 디바이스가 존재하지 않습니다."),
DEVICE_UNVALID(HttpStatus.UNAUTHORIZED, "DEVICE4002", "현재 접속중인 디바이스가 아닙니다.");
DEVICE_UNVALID(HttpStatus.UNAUTHORIZED, "DEVICE4002", "현재 접속중인 디바이스가 아닙니다."),



// Location
START_TIME_NOT_FOUND(HttpStatus.BAD_REQUEST, "STARTTIME4001", "해당 시작시간이 존재하지 않습니다."),
LOCATION_NOT_FOUND(HttpStatus.BAD_REQUEST, "LOCATION4001", "위치정보를 찾을 수 없습니다.");

private final HttpStatus httpStatus;
private final String code;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,32 @@
package capstone.checkIT.controller;

import capstone.checkIT.apipayLoad.ApiResponse;
import capstone.checkIT.config.JwtManager;
import capstone.checkIT.service.deviceLocationService.DeviceLocationService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.sql.Timestamp;

@RestController
@RequestMapping("/device-location")
@RequiredArgsConstructor
public class DeviceLocationController {

private final DeviceLocationService deviceLocationService;
private final JwtManager jwtManager;

@PostMapping("/stop")
public ApiResponse<String> stopLocation(
HttpServletRequest token,
@RequestParam Timestamp startTime) {

String accessToken = jwtManager.getToken(token);
deviceLocationService.stopLocation(accessToken, startTime);
return ApiResponse.onSuccess("경로저장이 종료되었습니다.");
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,48 @@
package capstone.checkIT.controller;

import capstone.checkIT.DTO.LocationDTO.LocationRequestDTO;
import capstone.checkIT.DTO.LocationDTO.LocationResponseDTO;
import capstone.checkIT.apipayLoad.ApiResponse;
import capstone.checkIT.config.JwtManager;
import capstone.checkIT.service.deviceLocationService.DeviceLocationService;
import capstone.checkIT.service.locationService.LocationService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/location")
public class LocationController {
}

private final LocationService locationService;
private final DeviceLocationService deviceLocationService;
private final JwtManager jwtManager;

// 위치 데이터 저장
@PostMapping
public ApiResponse<String> saveLocation(HttpServletRequest token, @RequestBody LocationRequestDTO request) {
String accessToken = jwtManager.getToken(token);
log.info("Location save request received: {}", request);
locationService.saveLocation(accessToken, request);
log.info("Location data saved successfully.");
return ApiResponse.onSuccess("위치 저장 완료");
}

// 가장 최신 경로 반환
@GetMapping("/latest/{deviceId}")
public ApiResponse<List<LocationResponseDTO>> getLatestRoute(
HttpServletRequest token,
@PathVariable("deviceId") Long deviceId) {
String accessToken = jwtManager.getToken(token);
List<LocationResponseDTO> response = locationService.getLatestRoute(accessToken, deviceId);
return ApiResponse.onSuccess(response);
}



}
8 changes: 4 additions & 4 deletions src/main/java/capstone/checkIT/entity/Location.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import org.hibernate.annotations.DynamicUpdate;

import java.math.BigDecimal;
import java.security.Timestamp;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

Expand All @@ -30,14 +30,14 @@ public class Location extends BaseEntity {
@Column(nullable=false, precision=10, scale=5)
private BigDecimal longitude;

@Column(nullable = false)
private Boolean isFinish;
/*@Column(nullable = false)
private Boolean isFinish;*/

@Column(nullable = false, precision = 5, scale = 2)
private BigDecimal velocity;

@Column
private Timestamp timestamp;
private Timestamp time;

@Column
private Timestamp startTime;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
package capstone.checkIT.repository;

public interface DeviceLocationRepository {
import capstone.checkIT.entity.DeviceLocation;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.sql.Timestamp;

public interface DeviceLocationRepository extends JpaRepository<DeviceLocation, Long> {
@Modifying
@Query("UPDATE DeviceLocation dl SET dl.isFinished = true " +
"WHERE dl.location.startTime = :startTime " +
"AND dl.device.member.id = :memberId")
int updateIsFinishedByStartTimeAndMemberId(@Param("startTime") Timestamp startTime, @Param("memberId") Long memberId);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
package capstone.checkIT.repository;

public interface LocationRepository {
import capstone.checkIT.entity.Location;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.sql.Timestamp;
import java.util.List;
import java.util.Optional;

public interface LocationRepository extends JpaRepository<Location, Long> {
List<Location> findByStartTime(Timestamp startTime);

// 최신 startTime 찾기
@Query("SELECT MAX(l.startTime) FROM Location l WHERE l.id IN " +
"(SELECT dl.location.id FROM DeviceLocation dl WHERE dl.device.id = :deviceId)")
Optional<Timestamp> findLatestStartTimeByDeviceId(@Param("deviceId") Long deviceId);

}
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
package capstone.checkIT.service.deviceLocationService;

import java.sql.Timestamp;

public interface DeviceLocationService {
void stopLocation(String accessToken, Timestamp startTime);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,42 @@
package capstone.checkIT.service.deviceLocationService;

import capstone.checkIT.apipayLoad.code.status.ErrorStatus;
import capstone.checkIT.config.JwtManager;
import capstone.checkIT.entity.Location;
import capstone.checkIT.exception.GeneralException;
import capstone.checkIT.repository.DeviceLocationRepository;
import capstone.checkIT.repository.LocationRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class DeviceLocationServiceImpl implements DeviceLocationService {
public class DeviceLocationServiceImpl implements DeviceLocationService{

private final DeviceLocationRepository deviceLocationRepository;
private final LocationRepository locationRepository;
private final JwtManager jwtManager;

public void stopLocation(String accessToken, Timestamp startTime) {
log.info("Stopping location tracking for startTime: {}", startTime);

// 1. JWT 토큰에서 memberId 추출
Long memberId = jwtManager.validateJwt(accessToken);

// 2. 해당 memberId의 Location과 DeviceLocation 조회
List<Location> locations = locationRepository.findByStartTime(startTime);
if (locations.isEmpty()) {
throw new GeneralException(ErrorStatus.START_TIME_NOT_FOUND); // 시작 시간에 해당하는 경로가 없는 경우
}

// 3. Location과 연결된 DeviceLocation의 isFinished 업데이트
int updatedRows = deviceLocationRepository.updateIsFinishedByStartTimeAndMemberId(startTime, memberId);

log.info("Updated {} rows for startTime: {}", updatedRows, startTime);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import capstone.checkIT.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
package capstone.checkIT.service.locationService;

import capstone.checkIT.DTO.LocationDTO.LocationRequestDTO;
import capstone.checkIT.DTO.LocationDTO.LocationResponseDTO;

import java.util.List;

public interface LocationService {
void saveLocation(String accessToken, LocationRequestDTO request);

List<LocationResponseDTO> getLatestRoute(String accessToken, Long deviceId);
}
Loading