Skip to content

Commit

Permalink
Merge pull request #82 from Team-KeepGoing/feature/notice
Browse files Browse the repository at this point in the history
feat :: 공지 기능 구현
  • Loading branch information
priverg authored Sep 19, 2024
2 parents 90edae8 + 69e1873 commit c2e9965
Show file tree
Hide file tree
Showing 44 changed files with 693 additions and 98 deletions.
18 changes: 14 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ repositories {
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
Expand All @@ -36,12 +37,21 @@ dependencies {
implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.3'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.3'
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
implementation 'org.apache.poi:poi:3.11'
implementation 'org.apache.poi:poi-ooxml:3.11' // 엑셀 2007 이상 버전에서 사용
implementation 'commons-io:commons-io:2.4'
implementation 'io.awspring.cloud:spring-cloud-starter-aws:2.4.4'

implementation group: 'org.apache.poi', name: 'poi', version: '5.3.0'
implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '5.3.0'
implementation 'commons-io:commons-io:2.7'

implementation 'com.querydsl:querydsl-core:5.1.0'
implementation 'com.querydsl:querydsl-jpa:5.1.0:jakarta'
implementation 'com.querydsl:querydsl-apt:5.1.0:jakarta'
annotationProcessor 'com.querydsl:querydsl-apt:5.1.0:jakarta'
annotationProcessor 'jakarta.persistence:jakarta.persistence-api'
annotationProcessor 'jakarta.annotation:jakarta.annotation-api'

implementation 'org.mapstruct:mapstruct:1.5.5.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final'
}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
package com.keepgoing.keepserver;

import jakarta.annotation.PostConstruct;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.util.TimeZone;

@SpringBootApplication
public class KeepServerApplication {
@PostConstruct
public void init() {
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul"));
}

public static void main(String[] args) {
SpringApplication.run(KeepServerApplication.class, args);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
package com.keepgoing.keepserver.domain.book.payload.response;

import com.keepgoing.keepserver.domain.book.domain.entity.enums.BookState;
import com.querydsl.core.annotations.QueryProjection;
import lombok.Builder;

import java.time.LocalDateTime;

@Builder
public record BookResponseDto(
Long id,
long id,
String bookName,
String writer,
String imageUrl,
LocalDateTime registrationDate,
LocalDateTime rentDate,
BookState state
) {
@QueryProjection
public BookResponseDto {
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.keepgoing.keepserver.domain.book.service;

import com.keepgoing.keepserver.domain.book.domain.entity.Book;
import com.keepgoing.keepserver.domain.book.domain.repository.BookRepository;
import com.keepgoing.keepserver.domain.book.mapper.BookMapper;
import com.keepgoing.keepserver.domain.book.payload.request.BookDto;
import com.keepgoing.keepserver.domain.book.payload.request.BookRequestDto;
import com.keepgoing.keepserver.domain.book.mapper.BookMapper;
import com.keepgoing.keepserver.domain.book.domain.repository.BookRepository;
import com.keepgoing.keepserver.domain.user.domain.entity.user.User;
import com.keepgoing.keepserver.domain.user.domain.repository.user.UserRepository;
import com.keepgoing.keepserver.global.common.BaseResponse;
Expand Down Expand Up @@ -34,7 +34,7 @@ public BaseResponse bookRegister(BookDto bookDto) {

@Override
public BaseResponse selectAllBook() {
return new BaseResponse(HttpStatus.OK, "책 불러오기 성공", bookRepository.findAll());
return new BaseResponse(HttpStatus.OK, "책 불러오기 성공", bookRepository.findAll().stream().map(bookMapper::entityToDto).toList());
}

@Override
Expand All @@ -55,7 +55,7 @@ public BaseResponse deleteBook(String nfcCode, Authentication auth) {
public BaseResponse selectMyBook(Authentication auth) {
User user = getUserByAuthentication(auth);
List<Book> books = bookRepository.findByBorrower(user);
return new BaseResponse(HttpStatus.OK, "책 가져오기 성공", books);
return new BaseResponse(HttpStatus.OK, "책 가져오기 성공", books.stream().map(bookMapper::entityToDto).toList());
}

@Override
Expand All @@ -64,7 +64,7 @@ public BaseResponse alertMyBook(Authentication auth, String dateString) {
DateRange dateRange = DateRange.fromDateString(dateString, "yyyyMMdd");

List<Book> books = bookRepository.findByBorrowerAndRentDateBetween(user, dateRange.getSt(), dateRange.getEnd());
return new BaseResponse(HttpStatus.OK, "책 가져오기 성공", books);
return new BaseResponse(HttpStatus.OK, "책 가져오기 성공", books.stream().map(bookMapper::entityToDto).toList());
}

@Override
Expand All @@ -86,10 +86,6 @@ public BaseResponse editBook(String nfcCode, BookRequestDto bookRequest) {
bookRepository.save(book);
return new BaseResponse(HttpStatus.OK, "책 정보 수정 성공");
}

public List<Book> findBooksBorrowedByUser(User user) {
return bookRepository.findByBorrower(user);
}
public User getUserByAuthentication(Authentication auth) {
if (auth == null) {
throw BookException.userNotFound();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class Device {
/*
기기 사진
*/
@Column(nullable = false)
@Column
private String imgUrl;

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import com.keepgoing.keepserver.domain.device.domain.entity.Device;
import com.keepgoing.keepserver.domain.device.domain.entity.enums.DeviceStatus;
import com.keepgoing.keepserver.domain.device.payload.response.DeviceResponseDto;
import com.keepgoing.keepserver.domain.device.payload.request.DeviceDto;
import com.keepgoing.keepserver.domain.device.payload.response.DeviceResponseDto;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package com.keepgoing.keepserver.domain.device.payload.response;

import com.keepgoing.keepserver.domain.device.domain.entity.enums.DeviceStatus;
import com.querydsl.core.annotations.QueryProjection;
import lombok.Builder;

import java.time.LocalDateTime;

@Builder
public record DeviceResponseDto (
Long id,
public record DeviceResponseDto(
long id,
String deviceName,
String imgUrl,
LocalDateTime regDate,
LocalDateTime rentDate,
DeviceStatus status
) {
@QueryProjection
public DeviceResponseDto {
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package com.keepgoing.keepserver.domain.device.service;

import com.keepgoing.keepserver.domain.device.domain.entity.Device;
import com.keepgoing.keepserver.domain.device.domain.repository.DeviceRepository;
import com.keepgoing.keepserver.domain.device.mapper.DeviceMapper;
import com.keepgoing.keepserver.domain.device.payload.request.DeviceDto;
import com.keepgoing.keepserver.domain.device.payload.request.DeviceEditRequest;
import com.keepgoing.keepserver.domain.device.payload.response.DeviceResponseDto;
import com.keepgoing.keepserver.domain.device.domain.repository.DeviceRepository;
import com.keepgoing.keepserver.domain.user.domain.entity.user.User;
import com.keepgoing.keepserver.domain.user.domain.repository.user.UserRepository;
import com.keepgoing.keepserver.global.common.BaseResponse;
import com.keepgoing.keepserver.global.exception.device.DeviceError;
import com.keepgoing.keepserver.global.exception.device.DeviceException;
import com.keepgoing.keepserver.global.exception.user.UserError;
import com.keepgoing.keepserver.global.exception.user.UserException;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
Expand Down Expand Up @@ -48,7 +50,8 @@ public BaseResponse deviceRead(Long id) {
@Override
public BaseResponse deleteDevice(Long id, Authentication authentication) {
User user = findUserByEmail(authentication.getName());
validateTeacher(user);
userRepository.findByIdAndTeacherIsTrue(user.getId())
.orElseThrow(() -> new UserException(UserError.USER_NOT_TEACHER));
deleteDeviceById(id);
return new BaseResponse(HttpStatus.OK, "기기 삭제 성공");
}
Expand Down Expand Up @@ -85,12 +88,6 @@ public List<Device> findDevicesBorrowedByUser(User user) {
return deviceRepository.findByBorrower(user);
}

private void validateTeacher(User user) {
if (!user.isTeacher()) {
throw new DeviceException(DeviceError.USER_NOT_FOUND);
}
}

private void deleteDeviceById(Long id) {
if (!deviceRepository.existsById(id)) {
throw new DeviceException(DeviceError.DEVICE_NOT_FOUND_EXCEPTION);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.keepgoing.keepserver.domain.notice.domain.entity.notice;

import com.keepgoing.keepserver.domain.user.domain.entity.user.User;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

@Entity
@Getter
@Setter
@SuperBuilder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@EntityListeners(AuditingEntityListener.class)
@Table(name = "notice")
public class Notice {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long idx;

@Lob
@Column(nullable = false)
private String message;

@ManyToOne
@JoinColumn(name = "teacher_id", nullable = false)
private User teacher;

@Column(nullable = false)
private boolean isGlobal;

@CreatedDate
@Column(nullable = false, updatable = false)
private LocalDateTime createTime;

@LastModifiedDate
@Column
private LocalDateTime editTime;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.keepgoing.keepserver.domain.notice.domain.entity.notice;

import com.keepgoing.keepserver.domain.user.domain.entity.user.User;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

@Entity
@Getter
@Setter
@SuperBuilder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@EntityListeners(AuditingEntityListener.class)
@Table(name = "notice_reception")
public class NoticeReception {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long idx;

@JoinColumn(name = "user_id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
@ManyToOne
private User user;

@JoinColumn(name = "notice_id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
@ManyToOne
private Notice notice;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.keepgoing.keepserver.domain.notice.domain.mapper;

import com.keepgoing.keepserver.domain.notice.domain.entity.notice.Notice;
import com.keepgoing.keepserver.domain.notice.payload.req.NoticeRequestDto;
import com.keepgoing.keepserver.domain.notice.payload.res.NoticeResponseDto;
import com.keepgoing.keepserver.domain.user.domain.entity.user.User;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper(componentModel = "spring")
public interface NoticeMapper {
@Mapping(source = "idx", target = "id")
@Mapping(source = "teacher.name", target = "teacherName")
NoticeResponseDto entityToDto(Notice notice);

@Mapping(target = "teacher", source = "teacher")
@Mapping(target = "isGlobal", source = "noticeRequestDto.isGlobal")
@Mapping(target = "message", source = "noticeRequestDto.message")
Notice toEntity(NoticeRequestDto noticeRequestDto, User teacher);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.keepgoing.keepserver.domain.notice.domain.repository;

import com.keepgoing.keepserver.domain.notice.domain.entity.notice.Notice;
import com.keepgoing.keepserver.domain.notice.domain.entity.notice.NoticeReception;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface NoticeReceptionRepository extends JpaRepository<NoticeReception, Long> {
void deleteAllByNotice(Notice notice);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.keepgoing.keepserver.domain.notice.domain.repository;

import com.keepgoing.keepserver.domain.notice.domain.entity.notice.Notice;
import com.keepgoing.keepserver.domain.user.domain.entity.user.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface NoticeRepository extends JpaRepository<Notice, Long> {
Notice findNoticeByIdxAndTeacher_Id(long idx, long tIdx);
List<Notice> findNoticesByTeacher(User teacher);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.keepgoing.keepserver.domain.notice.payload.req;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Builder;

import java.util.List;

@Builder
public record NoticeRequestDto(
@NotBlank(message = "메시지는 필수입니다.")
String message,
@NotNull(message = "isGlobal 값은 필수입니다.")
boolean isGlobal,
List<Long> userIds
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.keepgoing.keepserver.domain.notice.payload.res;

import com.querydsl.core.annotations.QueryProjection;
import lombok.Builder;

import java.time.LocalDateTime;

@Builder
public record NoticeResponseDto (
long id,
String message,
String teacherName,
LocalDateTime createTime,
LocalDateTime editTime
) {
@QueryProjection
public NoticeResponseDto{}
}
Loading

0 comments on commit c2e9965

Please sign in to comment.