Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ feat: 공고 기능 이미지 추가 #128

Merged
merged 9 commits into from
Feb 6, 2024
4 changes: 3 additions & 1 deletion http/test.http
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ Content-Type: application/json
"title": "무신사 스폰서십",
"type": "SPONSORSHIP",
"category": "MARKETING",
"content": "무신사 스폰서십을 진행할 대학교 학생회를 모집합니다."
"content": "무신사 스폰서십을 진행할 대학교 학생회를 모집합니다.",
"images": [
]
}

### 공고 상세 조회
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.sponus.sponusbe.auth.annotation.AuthOrganization;
import com.sponus.sponusbe.domain.announcement.dto.request.AnnouncementCreateRequest;
import com.sponus.sponusbe.domain.announcement.dto.request.AnnouncementUpdateRequest;
import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementCreateResponse;
import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementResponse;
import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementDetailResponse;
import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementSummaryResponse;
import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementUpdateResponse;
import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementStatus;
import com.sponus.sponusbe.domain.announcement.service.AnnouncementQueryService;
Expand Down Expand Up @@ -48,27 +50,34 @@ public ApiResponse<Void> getAnnouncement() {
}

@GetMapping("/{announcementId}")
public ApiResponse<AnnouncementResponse> getAnnouncement(@PathVariable Long announcementId) {
public ApiResponse<AnnouncementDetailResponse> getAnnouncement(@PathVariable Long announcementId) {
return ApiResponse.onSuccess(announcementService.getAnnouncement(announcementId));
}

@GetMapping("/status")
public ApiResponse<List<AnnouncementResponse>> getListAnnouncement(
public ApiResponse<List<AnnouncementSummaryResponse>> getListAnnouncement(
@RequestParam("status") AnnouncementStatus status) {
return ApiResponse.onSuccess(announcementService.getListAnnouncement(status));
}

@GetMapping
public ApiResponse<List<AnnouncementResponse>> searchAnnouncement(@RequestParam("search") String keyword) {
public ApiResponse<List<AnnouncementSummaryResponse>> searchAnnouncement(@RequestParam("search") String keyword) {
return ApiResponse.onSuccess(announcementQueryService.searchAnnouncement(keyword));
}

@PostMapping
@PostMapping(consumes = "multipart/form-data")
public ApiResponse<AnnouncementCreateResponse> createAnnouncement(
@AuthOrganization Organization authOrganization,
@RequestBody @Valid AnnouncementCreateRequest request
@RequestPart("request") @Valid AnnouncementCreateRequest request,
@RequestPart(value = "images") List<MultipartFile> images
) {
return ApiResponse.onSuccess(announcementService.createAnnouncement(authOrganization, request));
return ApiResponse.onSuccess(
announcementService.createAnnouncement(
authOrganization,
request,
images
)
);
}

@DeleteMapping("/{announcementId}")
Expand All @@ -79,14 +88,19 @@ public ApiResponse<Void> deleteAnnouncement(
return ApiResponse.onSuccess(null);
}

@PatchMapping("/{announcementId}")
@PatchMapping(value = "/{announcementId}", consumes = "multipart/form-data")
public ApiResponse<AnnouncementUpdateResponse> updateAnnouncement(
@AuthOrganization Organization authOrganization,
@PathVariable Long announcementId,
@RequestBody @Valid AnnouncementUpdateRequest request
@RequestPart("request") @Valid AnnouncementUpdateRequest request,
@RequestPart(value = "images", required = false) List<MultipartFile> images
) {
announcementService.updateAnnouncement(authOrganization, announcementId, request);
return ApiResponse.onSuccess(announcementService.updateAnnouncement(authOrganization, announcementId, request));
return ApiResponse.onSuccess(announcementService.updateAnnouncement(
authOrganization,
announcementId,
request,
images
));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,17 @@
import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementType;
import com.sponus.sponusbe.domain.organization.entity.Organization;

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

public record AnnouncementCreateRequest(
@NotBlank(message = "[ERROR] 타이틀 입력은 필수 입니다.")
@NotNull(message = "[ERROR] 타이틀 입력은 필수 입니다.")
String title,
@NotNull(message = "[ERROR] 유형 입력은 필수 입니다.")
AnnouncementType type,
@NotNull(message = "[ERROR] 카테코리 입력은 필수 입니다.")
AnnouncementCategory category,
@NotBlank(message = "[ERROR] 내용 입력은 필수 입니다.")
@NotNull(message = "[ERROR] 내용 입력은 필수 입니다.")
String content,

AnnouncementStatus status
) {

Expand All @@ -35,3 +33,4 @@ public Announcement toEntity(Organization writer) {
.build();
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.sponus.sponusbe.domain.announcement.dto.response;

import java.util.List;

import com.sponus.sponusbe.domain.announcement.entity.Announcement;
import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementCategory;
import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementStatus;
Expand All @@ -8,24 +10,31 @@
import lombok.Builder;

@Builder
public record AnnouncementResponse(
public record AnnouncementDetailResponse(
Long id,
Long writerId,
String title,
AnnouncementType type,
AnnouncementCategory category,
String content,
List<AnnouncementImageResponse> announcementImages,
AnnouncementStatus status,
Long viewCount
) {
public static AnnouncementResponse from(Announcement announcement) {
return AnnouncementResponse.builder()
public static AnnouncementDetailResponse from(Announcement announcement) {
List<AnnouncementImageResponse> announcementImages = announcement.getAnnouncementImages()
.stream()
.map(AnnouncementImageResponse::from)
.toList();

return AnnouncementDetailResponse.builder()
.id(announcement.getId())
.writerId(announcement.getWriter().getId())
.title(announcement.getTitle())
.type(announcement.getType())
.category(announcement.getCategory())
.content(announcement.getContent())
.announcementImages(announcementImages)
.status(announcement.getStatus())
.viewCount(announcement.getViewCount())
.build();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.sponus.sponusbe.domain.announcement.dto.response;

import com.sponus.sponusbe.domain.announcement.entity.AnnouncementImage;

import lombok.Builder;

@Builder
public record AnnouncementImageResponse(
Long id,
String name,
String url
) {
public static AnnouncementImageResponse from(AnnouncementImage image) {
return AnnouncementImageResponse.builder()
.id(image.getId())
.name(image.getName())
.url(image.getUrl())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.sponus.sponusbe.domain.announcement.dto.response;

import com.sponus.sponusbe.domain.announcement.entity.Announcement;
import com.sponus.sponusbe.domain.announcement.entity.AnnouncementImage;
import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementCategory;
import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementStatus;
import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementType;

import lombok.Builder;

@Builder
public record AnnouncementSummaryResponse(
Long id,
Long writerId,
String title,
AnnouncementType type,
AnnouncementCategory category,
AnnouncementImageResponse mainImage,
AnnouncementStatus status,
Long viewCount
) {
public static AnnouncementSummaryResponse from(Announcement announcement) {
AnnouncementImage mainImage = announcement.getAnnouncementImages()
.stream()
.findFirst().orElseThrow();

return AnnouncementSummaryResponse.builder()
.id(announcement.getId())
.writerId(announcement.getWriter().getId())
.title(announcement.getTitle())
.type(announcement.getType())
.category(announcement.getCategory())
.mainImage(AnnouncementImageResponse.from(mainImage))
.status(announcement.getStatus())
.viewCount(announcement.getViewCount())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.sponus.sponusbe.domain.organization.entity.Organization;
import com.sponus.sponusbe.global.common.BaseEntity;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.ConstraintMode;
import jakarta.persistence.Entity;
Expand Down Expand Up @@ -68,14 +69,14 @@ public class Announcement extends BaseEntity {
private Organization writer;

@Builder.Default
@OneToMany(mappedBy = "announcement")
private List<AnnouncementAttachment> announcementAttachments = new ArrayList<>();
@OneToMany(mappedBy = "announcement", cascade = CascadeType.ALL, orphanRemoval = true)
private List<AnnouncementImage> announcementImages = new ArrayList<>();

public void increaseViewCount() {
this.viewCount++;
}

public void update(String title, AnnouncementType type, AnnouncementCategory category, String content,
public void updateInfo(String title, AnnouncementType type, AnnouncementCategory category, String content,
AnnouncementStatus status) {
this.title = title == null ? this.title : title;
this.type = type == null ? this.type : type;
Expand All @@ -84,6 +85,13 @@ public void update(String title, AnnouncementType type, AnnouncementCategory cat
this.status = (status != null) ? status : this.status;
}

public void updateImages(List<AnnouncementImage> images) {
if (images != null) {
this.announcementImages.clear();
this.announcementImages.addAll(images);
}
}

public boolean isAvailable() {
return this.status == AnnouncementStatus.OPENED;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,28 @@
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
@Entity
@Table(name = "announcement_attachment")
public class AnnouncementAttachment {

@Table(name = "announcement_image")
public class AnnouncementImage {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "attachment_id")
@Column(name = "image_id")
private Long id;

@Column(name = "file_name", nullable = false)
@Column(name = "image_name", nullable = false)
private String name;

@Column(name = "file_url", nullable = false)
@Column(name = "image_url", nullable = false)
private String url;

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "announcement_id", foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
private Announcement announcement;

public void setAnnouncement(Announcement announcement) {
if (this.announcement != null) {
this.announcement.getAnnouncementImages().remove(this);
}
this.announcement = announcement;
announcement.getAnnouncementImages().add(this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.sponus.sponusbe.domain.announcement.dto.request.AnnouncementCreateRequest;
import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementBriefResponse;
import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementResponse;
import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementSummaryResponse;
import com.sponus.sponusbe.domain.announcement.repository.AnnouncementRepository;

import lombok.RequiredArgsConstructor;
Expand All @@ -21,13 +19,9 @@ public class AnnouncementQueryService {

private final AnnouncementRepository announcementRepository;

public List<AnnouncementResponse> searchAnnouncement(String keyword) {
public List<AnnouncementSummaryResponse> searchAnnouncement(String keyword) {
log.info("search announcement by keyword: {}", keyword);
return announcementRepository.findByTitleContains(keyword).stream()
.map(AnnouncementResponse::from).toList();
}

public AnnouncementBriefResponse createAnnouncement(AnnouncementCreateRequest request) {
return null;
.map(AnnouncementSummaryResponse::from).toList();
}
}
Loading
Loading