Skip to content
Merged
3 changes: 3 additions & 0 deletions uniro_backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ dependencies {
//webClient
implementation 'org.springframework.boot:spring-boot-starter-webflux'

//hibernate envers
implementation 'org.hibernate.orm:hibernate-envers:6.3.1.Final'

// actuator
implementation 'org.springframework.boot:spring-boot-starter-actuator'
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.softeer5.uniro_backend.admin.annotation;

import com.softeer5.uniro_backend.admin.entity.RevisionOperationType;

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RevisionOperation {
RevisionOperationType value() default RevisionOperationType.DEFAULT;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.softeer5.uniro_backend.admin.aspect;

import com.softeer5.uniro_backend.admin.annotation.RevisionOperation;
import com.softeer5.uniro_backend.admin.entity.RevisionOperationType;
import com.softeer5.uniro_backend.admin.setting.RevisionContext;
import com.softeer5.uniro_backend.route.dto.PostRiskReqDTO;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import static com.softeer5.uniro_backend.common.constant.UniroConst.*;

@Aspect
@Component
@Order(BEFORE_DEFAULT_ORDER)
public class RevisionOperationAspect {

@Around("@annotation(revisionOperation)")
public Object around(ProceedingJoinPoint joinPoint, RevisionOperation revisionOperation) throws Throwable {
RevisionOperationType opType = revisionOperation.value();

Object result;
switch (opType) {
case UPDATE_RISK -> result = updateRiskHandler(joinPoint);
default -> result = joinPoint.proceed();
}

return result;
}

private Object updateRiskHandler(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
String[] parameterNames = signature.getParameterNames();
Object[] args = joinPoint.getArgs();

Long univId = null;
String action = null;
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof Long && "univId".equals(parameterNames[i])) {
univId = (Long) args[i];
}
else if(args[i] instanceof PostRiskReqDTO postRiskReqDTO){
int cautionSize = postRiskReqDTO.getCautionTypes().size();
int dangerSize = postRiskReqDTO.getDangerTypes().size();

if (cautionSize > 0) {
action = "주의요소 업데이트";
} else if (dangerSize > 0) {
action = "위험요소 업데이트";
} else {
action = "위험/주의요소 해제";
Comment on lines +41 to +54
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상수화 시키는 것에 대한 의견 궁금합니다!

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다른 상수화 작업과 함께 진행하겠습니다!

}
}
}
RevisionContext.setUnivId(univId);
RevisionContext.setAction(action);
try{
return joinPoint.proceed();
}
finally {
RevisionContext.clear();
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.softeer5.uniro_backend.admin.controller;

import com.softeer5.uniro_backend.admin.dto.RevInfoDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.List;

@Tag(name = "admin 페이지 API")
public interface AdminApi {

@Operation(summary = "모든 버전정보 조회")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "모든 버전정보 조회 성공"),
@ApiResponse(responseCode = "400", description = "EXCEPTION(임시)", content = @Content),
})
ResponseEntity<List<RevInfoDTO>> getAllRev(@PathVariable("univId") Long univId);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.softeer5.uniro_backend.admin.controller;

import com.softeer5.uniro_backend.admin.dto.RevInfoDTO;
import com.softeer5.uniro_backend.admin.service.AdminService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequiredArgsConstructor
public class AdminController implements AdminApi {
private final AdminService adminService;

@Override
@GetMapping("/admin/revision/{univId}")
public ResponseEntity<List<RevInfoDTO>> getAllRev(@PathVariable("univId") Long univId) {
return ResponseEntity.ok().body(adminService.getAllRevInfo(univId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.softeer5.uniro_backend.admin.dto;

import com.softeer5.uniro_backend.admin.entity.RevInfo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;

import java.time.LocalDateTime;

@Getter
@Schema(name = "GetBuildingResDTO", description = "건물 노드 조회 DTO")
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class RevInfoDTO {
@Schema(description = "버전명", example = "4")
private final Long rev; // Revision 번호
@Schema(description = "버전 타임스탬프", example = "2025-02-04T17:56:06.832")
private final LocalDateTime revTime; // Revision 시간
@Schema(description = "학교id", example = "1")
private final Long univId; //UnivId
@Schema(description = "변경사항 desc", example = "위험요소 추가")
private final String action; // 행위

public static RevInfoDTO of(Long rev, LocalDateTime revTime, Long univId, String action) {
return new RevInfoDTO(rev, revTime, univId, action);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.softeer5.uniro_backend.admin.entity;

import com.softeer5.uniro_backend.admin.setting.CustomReversionListener;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.envers.RevisionEntity;
import org.hibernate.envers.RevisionNumber;
import org.hibernate.envers.RevisionTimestamp;

@Entity
@RevisionEntity(CustomReversionListener.class)
@Getter
@Setter
@Table(name = "Revinfo")
public class RevInfo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@RevisionNumber
private Long rev;

@RevisionTimestamp
@Column(name = "revtstmp")
private long revTimeStamp;
@Column(name = "univ_id", nullable = false)
private Long univId;
private String action;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.softeer5.uniro_backend.admin.entity;

public enum RevisionOperationType {
UPDATE_RISK,
DEFAULT;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.softeer5.uniro_backend.admin.repository;

import com.softeer5.uniro_backend.admin.entity.RevInfo;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;


public interface RevInfoRepository extends JpaRepository<RevInfo,Long> {
List<RevInfo> findAllByUnivId(Long univId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.softeer5.uniro_backend.admin.service;

import com.softeer5.uniro_backend.admin.dto.RevInfoDTO;
import com.softeer5.uniro_backend.admin.repository.RevInfoRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class AdminService {
private final RevInfoRepository revInfoRepository;

public List<RevInfoDTO> getAllRevInfo(Long univId){
return revInfoRepository.findAllByUnivId(univId).stream().map(r -> RevInfoDTO.of(r.getRev(),
LocalDateTime.ofInstant(Instant.ofEpochMilli(r.getRevTimeStamp()), ZoneId.systemDefault()),
r.getUnivId(),
r.getAction())).toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.softeer5.uniro_backend.admin.setting;

import com.softeer5.uniro_backend.admin.entity.RevInfo;
import org.hibernate.envers.RevisionListener;

public class CustomReversionListener implements RevisionListener {
@Override
public void newRevision(Object revisionEntity) {
RevInfo revinfo = (RevInfo) revisionEntity;
revinfo.setUnivId(RevisionContext.getUnivId());
revinfo.setAction(RevisionContext.getAction());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.softeer5.uniro_backend.admin.setting;

public class RevisionContext {
private static final ThreadLocal<Long> univIdHolder = new ThreadLocal<>();
private static final ThreadLocal<String> actionHolder = new ThreadLocal<>();

public static void setAction(String action) {
actionHolder.set(action);
}

public static String getAction() {
return actionHolder.get();
}

public static void setUnivId(Long univId) {
univIdHolder.set(univId);
}

public static Long getUnivId() {
return univIdHolder.get();
}

public static void clear() {
univIdHolder.remove();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
public final class UniroConst {
public static final String NODE_KEY_DELIMITER = " ";
public static final int CORE_NODE_CONDITION = 3;
public static final int BEFORE_DEFAULT_ORDER = -1;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.util.Map;

import lombok.*;
import org.hibernate.envers.Audited;
import org.locationtech.jts.geom.Point;

import jakarta.persistence.Column;
Expand All @@ -21,13 +22,15 @@
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
@ToString
@Audited
public class Node {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@NotNull
@Column(columnDefinition = "POINT SRID 4326")
private Point coordinates;

private double height;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public interface RouteApi {
@ApiResponse(responseCode = "200", description = "모든 지도 조회 성공"),
@ApiResponse(responseCode = "400", description = "EXCEPTION(임시)", content = @Content),
})
public ResponseEntity<GetAllRoutesResDTO> getAllRoutesAndNodes(@PathVariable("univId") Long univId);
ResponseEntity<GetAllRoutesResDTO> getAllRoutesAndNodes(@PathVariable("univId") Long univId);

@Operation(summary = "위험&주의 요소 조회")
@ApiResponses(value = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import com.softeer5.uniro_backend.resolver.CautionListConverter;
import com.softeer5.uniro_backend.resolver.DangerListConverter;
import com.softeer5.uniro_backend.node.entity.Node;
import org.hibernate.envers.Audited;
import org.hibernate.envers.RelationTargetAuditMode;
import org.locationtech.jts.geom.LineString;

import jakarta.persistence.Column;
Expand All @@ -27,6 +29,7 @@
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Audited
public class Route {

@Id
Expand All @@ -35,16 +38,18 @@ public class Route {

private double cost;

@Column(columnDefinition = "geometry(LineString, 4326)") // WGS84 좌표계
@Column(columnDefinition = "LINESTRING SRID 4326") // WGS84 좌표계
private LineString path;

@ManyToOne(fetch = LAZY)
@JoinColumn(referencedColumnName = "id", name = "node1_id")
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
@NotNull
private Node node1;

@ManyToOne(fetch = LAZY)
@JoinColumn(referencedColumnName = "id", name = "node2_id")
@Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
@NotNull
private Node node2;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.util.*;
import java.util.stream.Collectors;

import com.softeer5.uniro_backend.admin.annotation.RevisionOperation;
import com.softeer5.uniro_backend.admin.entity.RevisionOperationType;
import com.softeer5.uniro_backend.common.error.ErrorCode;
import com.softeer5.uniro_backend.common.exception.custom.DangerCautionConflictException;
import com.softeer5.uniro_backend.common.exception.custom.InvalidMapException;
Expand Down Expand Up @@ -215,6 +217,7 @@ public GetRiskResDTO getRisk(Long univId, double startLat, double startLng, doub
return GetRiskResDTO.of(routeWithJoin);
}

@RevisionOperation(RevisionOperationType.UPDATE_RISK)
@Transactional
public void updateRisk(Long univId, Long routeId, PostRiskReqDTO postRiskReqDTO) {
Route route = routeRepository.findByIdAndUnivId(routeId, univId)
Expand Down