Skip to content

Commit

Permalink
Merge pull request #3 from PLADI-ALM/feat/PDS-35-upload-file
Browse files Browse the repository at this point in the history
[PDS-35] 아카이빙 자료 업로드 API 기능구현
  • Loading branch information
dangnak2 authored Oct 14, 2023
2 parents f179b31 + c3d5f0a commit 9f64760
Show file tree
Hide file tree
Showing 22 changed files with 569 additions and 44 deletions.
8 changes: 8 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ dependencies {
//feignClient
implementation "org.springframework.cloud:spring-cloud-starter-openfeign:3.1.1"
compileOnly "org.springframework.cloud:spring-cloud-starter-openfeign:3.1.1"

// jwt
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'

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

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.example.PLADIALMArchiving.archiving.controller;

import com.example.PLADIALMArchiving.archiving.dto.request.RegisterProjectReq;
import com.example.PLADIALMArchiving.archiving.dto.request.UploadMaterialReq;
import com.example.PLADIALMArchiving.archiving.service.ArchivingService;
import com.example.PLADIALMArchiving.global.resolver.Account;
import com.example.PLADIALMArchiving.global.response.ResponseCustom;
import com.example.PLADIALMArchiving.user.entity.User;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

@Api(tags = "아카이빙 API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/archives")
public class ArchivingController {

private final ArchivingService archivingService;

/**
* 프로젝트를 추가한다.
*/
@PostMapping("/projects/register")
public ResponseCustom<?> registerProject(@RequestBody RegisterProjectReq registerProjectReq) {
archivingService.registerProject(registerProjectReq);
return ResponseCustom.OK();
}

/**
* 자료를 업로드한다.
*/
@PostMapping("/projects/{projectId}/upload")
public ResponseCustom<?> uploadMaterial(
@RequestBody UploadMaterialReq uploadMaterialReq,
@PathVariable Long projectId,
@Account User user
)
{
archivingService.uploadMaterial(uploadMaterialReq, projectId, user);
return ResponseCustom.OK();
}
/**
* 자료목록을 조회 및 검색한다.
*/

/**
* 자료를 삭제한다.
*/

/**
* 자료를 다운로드한다.
*/
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.PLADIALMArchiving.archiving.dto.request;

import lombok.Getter;

@Getter
public class RegisterProjectReq {
private String name;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.example.PLADIALMArchiving.archiving.dto.request;

import lombok.Getter;

@Getter
public class UploadMaterialReq {
private String fileKey;
private String name;
private String extension;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.example.PLADIALMArchiving.archiving.entity;

import com.example.PLADIALMArchiving.archiving.dto.request.UploadMaterialReq;
import com.example.PLADIALMArchiving.global.entity.BaseEntity;
import com.example.PLADIALMArchiving.user.entity.User;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Where;

import javax.persistence.*;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@DynamicInsert
@DynamicUpdate
@Where(clause = "is_enable = true")
public class Material extends BaseEntity {

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

private String name;

private String extension;

private String fileKey;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(nullable = false, name = "project_id")
private Project project;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(nullable = false, name = "user_id")
private User user;

@Builder
public Material(String name, String extension, String fileKey, Project project, User user) {
this.name = name;
this.extension = extension;
this.fileKey = fileKey;
this.project = project;
this.user = user;
}

public static Material toEntity(UploadMaterialReq uploadMaterialReq, Project project, User user) {
return Material.builder()
.name(uploadMaterialReq.getName())
.extension(uploadMaterialReq.getExtension())
.fileKey(uploadMaterialReq.getFileKey())
.project(project)
.user(user)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.example.PLADIALMArchiving.archiving.entity;

import com.example.PLADIALMArchiving.global.entity.BaseEntity;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Where;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@DynamicInsert
@DynamicUpdate
@Where(clause = "is_enable = true")
public class Project extends BaseEntity {

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

@NotNull
@Size(max = 50)
private String name;

@OneToMany(mappedBy = "project", fetch = FetchType.LAZY)
private List<Material> materialList = new ArrayList<>();

public static Project toEntity(String name) {
return Project.builder().name(name).build();
}

@Builder
public Project(String name) {
this.name = name;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.example.PLADIALMArchiving.archiving.repository;

import com.example.PLADIALMArchiving.archiving.entity.Material;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface MaterialRepository extends JpaRepository<Material, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.PLADIALMArchiving.archiving.repository;

import com.example.PLADIALMArchiving.archiving.entity.Project;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public interface ProjectRepository extends JpaRepository<Project, Long> {

Optional<Project> findByName(String name);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.example.PLADIALMArchiving.archiving.service;

import com.example.PLADIALMArchiving.archiving.dto.request.RegisterProjectReq;
import com.example.PLADIALMArchiving.archiving.dto.request.UploadMaterialReq;
import com.example.PLADIALMArchiving.archiving.entity.Material;
import com.example.PLADIALMArchiving.archiving.entity.Project;
import com.example.PLADIALMArchiving.archiving.repository.MaterialRepository;
import com.example.PLADIALMArchiving.archiving.repository.ProjectRepository;
import com.example.PLADIALMArchiving.global.exception.BaseException;
import com.example.PLADIALMArchiving.global.exception.BaseResponseCode;
import com.example.PLADIALMArchiving.user.entity.User;
import com.example.PLADIALMArchiving.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class ArchivingService {

private final UserRepository userRepository;
private final ProjectRepository projectRepository;
private final MaterialRepository materialRepository;


@Transactional
public void registerProject(RegisterProjectReq registerProjectReq) {
boolean present = projectRepository.findByName(registerProjectReq.getName()).isPresent();
if(present) throw new BaseException(BaseResponseCode.ALREADY_REGISTERED_PROJECT);
projectRepository.save(Project.toEntity(registerProjectReq.getName()));
}

@Transactional
public void uploadMaterial(UploadMaterialReq uploadMaterialReq, Long projectId, User user) {
Project project = projectRepository.findById(projectId).orElseThrow(() -> new BaseException(BaseResponseCode.PROJECT_NOT_FOUND));
materialRepository.save(Material.toEntity(uploadMaterialReq, project, user));
}
}
42 changes: 0 additions & 42 deletions src/main/java/com/example/PLADIALMArchiving/global/BaseEntity.java

This file was deleted.

19 changes: 19 additions & 0 deletions src/main/java/com/example/PLADIALMArchiving/global/Constants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.example.PLADIALMArchiving.global;

public class Constants {
public static final String TIME_PATTERN = "HH:mm";
public static final String DATE_PATTERN = "yyyy-MM-dd";
public static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm";

public static class Booking{
public static final String BOOKED_TIMES = "bookedTimes";
}

public static class JWT{
public static final String AUTHORIZATION_HEADER = "Authorization";
public static final String BEARER_PREFIX = "Bearer ";
public static final String CLAIM_NAME = "userIdx";
public static final String LOGOUT = "logout";
public static final String SIGNOUT = "signout";
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
package com.example.PLADIALMArchiving.global.config;

import com.example.PLADIALMArchiving.global.resolver.LoginResolver;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@RequiredArgsConstructor
@Configuration
public class WebConfig implements WebMvcConfigurer {

private final LoginResolver loginResolver;

@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // url 패턴
Expand All @@ -17,4 +25,9 @@ public void addCorsMappings(CorsRegistry registry) {
.allowedMethods(HttpMethod.GET.name(), HttpMethod.POST.name(), HttpMethod.PATCH.name(), HttpMethod.DELETE.name(), HttpMethod.OPTIONS.name()) // 허용 method
.allowedHeaders("Authorization", "Content-Type"); // 허용 header
}

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(loginResolver);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ public enum BaseResponseCode {
// User
USER_NOT_FOUND("U0001", HttpStatus.NOT_FOUND, "사용자를 찾을 수 없습니다."),

// Token
NULL_TOKEN("T0001", HttpStatus.UNAUTHORIZED, "토큰 값을 입력해주세요."),
INVALID_TOKEN("T0002", HttpStatus.UNAUTHORIZED, "유효하지 않은 토큰 값입니다."),
UNSUPPORTED_TOKEN("T0003", HttpStatus.UNAUTHORIZED, "잘못된 형식의 토큰 값입니다."),
MALFORMED_TOKEN("T0004", HttpStatus.UNAUTHORIZED, "잘못된 구조의 토큰 값입니다."),
EXPIRED_TOKEN("T0005", HttpStatus.FORBIDDEN, "만료된 토큰 값입니다."),
NOT_ACCESS_HEADER("T0006", HttpStatus.INTERNAL_SERVER_ERROR, "헤더에 접근할 수 없습니다."),
BLACKLIST_TOKEN("T0007", HttpStatus.FORBIDDEN, "로그아웃 혹은 회원 탈퇴된 토큰입니다."),

// Booking
DATE_OR_TIME_IS_NULL("B0001", HttpStatus.BAD_REQUEST, "날짜와 시간을 모두 입력해주세요."),
MEMO_SIZE_OVER("B0002", HttpStatus.BAD_REQUEST, "요청사항은 30자 이하로 작성해주세요."),
Expand All @@ -30,6 +39,10 @@ public enum BaseResponseCode {

// Office
OFFICE_NOT_FOUND("O0001", HttpStatus.NOT_FOUND, "존재하지 않는 회의실입니다."),

// Archiving
ALREADY_REGISTERED_PROJECT("P0001", HttpStatus.BAD_REQUEST, "이미 등록된 프로젝트입니다."),
PROJECT_NOT_FOUND("P0002", HttpStatus.NOT_FOUND, "존재하지 않는 프로젝트입니다."),
;

public final String code;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;


@Component
Expand Down
Loading

0 comments on commit 9f64760

Please sign in to comment.