Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
669b2d8
Chore: gitignore 수정
dlwls423 Aug 21, 2025
5d18629
Feat: BaseEntity 생성자, 수정자 추가
dlwls423 Aug 21, 2025
8679d1c
Feat: File 테이블 추가
dlwls423 Aug 21, 2025
3cc1af9
Feat: FileUuid 추가 및 생성
dlwls423 Aug 21, 2025
e5c91d5
Chore: EmailService 이동
dlwls423 Aug 21, 2025
bb545b6
Fix: logback-spring.xml 복구
dlwls423 Aug 21, 2025
31ce6ad
Merge pull request #211 from DevKor-github/feat/common
dlwls423 Aug 21, 2025
eca1b2f
Feat: 건물 내부 이미지 수정
dlwls423 Aug 21, 2025
c114657
Rename: 공통 서비스 이름 변경
dlwls423 Aug 21, 2025
8e9204e
Merge branch 'develop' of https://github.com/DevKor-github/team-c-bac…
dlwls423 Aug 21, 2025
1d79d22
Feat: 이미지 응답 수정
dlwls423 Aug 21, 2025
1dc9b95
Feat: 건물, 장소 사진 저장 api 추가
dlwls423 Aug 21, 2025
2d0b401
Fix: 건물, logback-spring.xml 수정
dlwls423 Aug 21, 2025
382d2d1
Merge pull request #212 from DevKor-github/feat/file
dlwls423 Aug 22, 2025
432562d
Feat: 파일 요청 크기 설정
dlwls423 Aug 25, 2025
f9c9fb2
Merge branch 'develop' of https://github.com/DevKor-github/team-c-bac…
dlwls423 Aug 25, 2025
2587abc
Merge pull request #213 from DevKor-github/feat/file
dlwls423 Aug 25, 2025
9d37ea8
Feat: 다회용컵 반납함 추가
dlwls423 Aug 25, 2025
7b753f4
Merge pull request #214 from DevKor-github/feat/place-type
dlwls423 Aug 26, 2025
ebe18cd
Update application.yml
dlwls423 Aug 26, 2025
a04beac
chore: swagger 소요 시간 표기
Yyang-YE Aug 26, 2025
adc2f76
Merge pull request #215 from DevKor-github/chore/mail
Yyang-YE Aug 27, 2025
d6b4577
Merge branch 'develop' of https://github.com/DevKor-github/team-c-bac…
Yyang-YE Aug 27, 2025
fd6c5fc
feat: 행동 로그 수집 기능 추가
Yyang-YE Aug 27, 2025
3479836
feat: LogUtil 추가
Yyang-YE Aug 27, 2025
9749f72
chore: 연동 임시 해제
Yyang-YE Aug 27, 2025
558a8ee
Merge pull request #216 from DevKor-github/feat/logging
Yyang-YE Aug 27, 2025
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ build/
!**/src/main/**/build/
!**/src/test/**/build/
application-test.yml
logback-spring.xml

### STS ###
.apt_generated
Expand Down
6 changes: 6 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ dependencies {

// Logging
implementation 'net.logstash.logback:logstash-logback-encoder:7.4'

// thumbnail
implementation 'net.coobird:thumbnailator:0.4.19'

// elasticsearch
// implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch'
}

dependencyManagement {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package devkor.com.teamcback.domain.bookmark.entity;

import devkor.com.teamcback.domain.bookmark.dto.request.CreateBookmarkReq;
import devkor.com.teamcback.domain.common.BaseEntity;
import devkor.com.teamcback.domain.common.entity.BaseEntity;
import devkor.com.teamcback.domain.common.LocationType;
import jakarta.persistence.*;
import java.util.ArrayList;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import devkor.com.teamcback.domain.bookmark.dto.request.CreateCategoryReq;
import devkor.com.teamcback.domain.bookmark.dto.request.ModifyCategoryReq;
import devkor.com.teamcback.domain.common.BaseEntity;
import devkor.com.teamcback.domain.common.entity.BaseEntity;
import devkor.com.teamcback.domain.user.entity.User;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package devkor.com.teamcback.domain.bookmark.entity;

import devkor.com.teamcback.domain.common.BaseEntity;
import devkor.com.teamcback.domain.common.entity.BaseEntity;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.PostRemove;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package devkor.com.teamcback.domain.building.controller;

import devkor.com.teamcback.domain.building.dto.response.SaveBuildingImageRes;
import devkor.com.teamcback.domain.building.dto.response.SaveBuildingMainImageRes;
import devkor.com.teamcback.domain.building.service.AdminBuildingService;
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 lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/admin/buildings")
public class AdminBuildingController {

private final AdminBuildingService adminBuildingService;

@PostMapping(value = "/{buildingId}/image", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@Operation(summary = "건물 대표 사진 저장", description = "건물 대표 사진 저장")
@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))),
@ApiResponse(responseCode = "403", description = "잘못된 입력입니다.",
content = @Content(schema = @Schema(implementation = CommonResponse.class))),
})
public CommonResponse<SaveBuildingMainImageRes> saveBuildingMainImage(
@Parameter(name = "buildingId", description = "건물 ID")
@PathVariable Long buildingId,
@Parameter(description = "저장할 사진 파일")
@RequestPart("image") MultipartFile image
) {
return CommonResponse.success(
adminBuildingService.saveBuildingMainImage(buildingId, image));
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package devkor.com.teamcback.domain.building.dto.response;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.v3.oas.annotations.media.Schema;

@Schema(description = "건물 메인 사진 저장 완료")
@JsonIgnoreProperties
public class SaveBuildingMainImageRes {
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,12 @@ public SearchBuildingImageRes(BuildingImage buildingImage) {
this.floor = buildingImage.getFloor();
this.image = buildingImage.getImage();
}

public SearchBuildingImageRes(BuildingImage buildingImage, String image) {
this.buildingImageId = buildingImage.getId();
this.buildingId = buildingImage.getBuilding().getId();
this.buildingName = buildingImage.getBuilding().getName();
this.floor = buildingImage.getFloor();
this.image = image;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package devkor.com.teamcback.domain.building.entity;

import devkor.com.teamcback.domain.common.BaseEntity;
import devkor.com.teamcback.domain.common.entity.BaseEntity;
import devkor.com.teamcback.domain.routes.entity.Node;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
Expand All @@ -27,7 +27,10 @@ public class Building extends BaseEntity {
@Column(nullable = false)
private String name;

private String imageUrl;
private String imageUrl; // 추후 삭제

@Setter
private String fileUuid;

@Column(nullable = false)
private String detail;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Entity
@Getter
Expand All @@ -22,9 +23,13 @@ public class BuildingImage {
@Column(nullable = false)
private Double floor;

@Column(nullable = false)
@Column(nullable = false) // 추후 삭제
private String image;

@Setter
@Column
private String fileUuid;

@ManyToOne
@JoinColumn(name = "building_id")
private Building building;
Expand All @@ -35,7 +40,14 @@ public BuildingImage(Double floor, String imageUrl, Building building) {
this.building = building;
}

public BuildingImage(Double floor, Building building, String fileUuid) {
this.floor = floor;
this.fileUuid = fileUuid;
this.building = building;
}

public void update(String imageUrl) {
this.image = imageUrl;
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package devkor.com.teamcback.domain.building.entity;

import devkor.com.teamcback.domain.common.BaseEntity;
import devkor.com.teamcback.domain.common.entity.BaseEntity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package devkor.com.teamcback.domain.building.entity;

import devkor.com.teamcback.domain.common.BaseEntity;
import devkor.com.teamcback.domain.common.entity.BaseEntity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
import devkor.com.teamcback.domain.building.entity.BuildingImage;
import devkor.com.teamcback.domain.building.repository.BuildingImageRepository;
import devkor.com.teamcback.domain.building.repository.BuildingRepository;
import devkor.com.teamcback.domain.common.util.FileUtil;
import devkor.com.teamcback.global.exception.exception.GlobalException;
import devkor.com.teamcback.infra.s3.FilePath;
import devkor.com.teamcback.infra.s3.S3Util;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -26,19 +26,22 @@
public class AdminBuildingImageService {
private final BuildingRepository buildingRepository;
private final BuildingImageRepository buildingImageRepository;
private final S3Util s3Util;
private final FileUtil fileUtil;

// 건물 내부 사진 저장
@Transactional
public SaveBuildingImageRes saveBuildingImage(Long buildingId, Double floor, MultipartFile image) {
String imageUrl = s3Util.uploadFile(image, FilePath.BUILDING_IMAGE);

Building building = findBuilding(buildingId);

if(floor < building.getUnderFloor() * (-1) || floor > building.getFloor()) {
throw new GlobalException(INCORRECT_FLOOR);
}
checkExistedImage(building, floor); // 해당 건물, 층에 해당하는 사진이 있는지 확인
BuildingImage buildingImage = buildingImageRepository.save(new BuildingImage(floor, imageUrl, building));

String fileUuid = fileUtil.createFileUuid();
fileUtil.upload(image, fileUuid, FilePath.BUILDING_IMAGE, 1L);
BuildingImage buildingImage = buildingImageRepository.save(new BuildingImage(floor, building, fileUuid));

return new SaveBuildingImageRes(buildingImage);
}
Expand All @@ -47,12 +50,17 @@ public SaveBuildingImageRes saveBuildingImage(Long buildingId, Double floor, Mul
@Transactional
public ModifyBuildingImageRes modifyBuildingImage(Long buildingImageId, MultipartFile image) {
BuildingImage buildingImage = findBuildingImage(buildingImageId);
if(s3Util.exists(buildingImage.getImage(), FilePath.BUILDING_IMAGE)) {
s3Util.deleteFile(buildingImage.getImage(), FilePath.BUILDING_IMAGE); // 기존 사진 S3에서 삭제

// fileUuid 확인
if(buildingImage.getFileUuid() == null) {
buildingImage.setFileUuid(fileUtil.createFileUuid());
}

String imageUrl = s3Util.uploadFile(image, FilePath.BUILDING_IMAGE);
buildingImage.update(imageUrl);
// 기존 파일 삭제
fileUtil.deleteFile(buildingImage.getFileUuid());

// 새 파일 업로드
fileUtil.upload(image, buildingImage.getFileUuid(), FilePath.BUILDING_IMAGE, 1L);

return new ModifyBuildingImageRes(buildingImage);
}
Expand All @@ -61,9 +69,11 @@ public ModifyBuildingImageRes modifyBuildingImage(Long buildingImageId, Multipar
@Transactional
public DeleteBuildingImageRes deleteBuildingImage(Long buildingImageId) {
BuildingImage buildingImage = findBuildingImage(buildingImageId);
if(s3Util.exists(buildingImage.getImage(), FilePath.BUILDING_IMAGE)) {
s3Util.deleteFile(buildingImage.getImage(), FilePath.BUILDING_IMAGE); // 기존 사진 S3에서 삭제
}

// 기존 파일 삭제
fileUtil.deleteFile(buildingImage.getFileUuid());

// 내부 사진 삭제
buildingImageRepository.delete(buildingImage);

return new DeleteBuildingImageRes();
Expand All @@ -75,7 +85,12 @@ public SearchBuildingImageRes searchBuildingImage(Long buildingId, Double floor)
Building building = findBuilding(buildingId);
BuildingImage buildingImage = findBuildingImage(building, floor);

return new SearchBuildingImageRes(buildingImage);
String fileName = fileUtil.getOriginalFile(buildingImage.getFileUuid());
if(fileName == null){ // TODO: 추후 삭제
return new SearchBuildingImageRes(buildingImage);
}

return new SearchBuildingImageRes(buildingImage, fileName);
}

private Building findBuilding(Long buildingId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package devkor.com.teamcback.domain.building.service;

import devkor.com.teamcback.domain.building.dto.response.SaveBuildingImageRes;
import devkor.com.teamcback.domain.building.dto.response.SaveBuildingMainImageRes;
import devkor.com.teamcback.domain.building.entity.Building;
import devkor.com.teamcback.domain.building.entity.BuildingImage;
import devkor.com.teamcback.domain.building.repository.BuildingRepository;
import devkor.com.teamcback.domain.common.repository.FileRepository;
import devkor.com.teamcback.domain.common.util.FileUtil;
import devkor.com.teamcback.global.exception.exception.GlobalException;
import devkor.com.teamcback.infra.s3.FilePath;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import static devkor.com.teamcback.global.response.ResultCode.INCORRECT_FLOOR;
import static devkor.com.teamcback.global.response.ResultCode.NOT_FOUND_BUILDING;

@Service
@RequiredArgsConstructor
public class AdminBuildingService {

private final BuildingRepository buildingRepository;
private final FileUtil fileUtil;

// 건물 내부 사진 저장
@Transactional
public SaveBuildingMainImageRes saveBuildingMainImage(Long buildingId, MultipartFile image) {

Building building = findBuilding(buildingId);

if(building.getFileUuid() == null) {
building.setFileUuid(fileUtil.createFileUuid());
}

fileUtil.upload(image, building.getFileUuid(), FilePath.BUILDING, 1L);

return new SaveBuildingMainImageRes();
}

private Building findBuilding(Long buildingId) {
return buildingRepository.findById(buildingId).orElseThrow(() -> new GlobalException(NOT_FOUND_BUILDING));
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package devkor.com.teamcback.domain.common;
package devkor.com.teamcback.domain.common.entity;

import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import java.time.LocalDateTime;
import lombok.Getter;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

Expand All @@ -17,6 +19,13 @@ public class BaseEntity {
@CreatedDate
private LocalDateTime createdAt;

@Column(updatable = false)
@CreatedBy
private Long createdBy;

@LastModifiedDate
private LocalDateTime modifiedAt;

@LastModifiedBy
private Long modifiedBy;
}
Loading
Loading