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

[HEENDY-43-user-visit-QR] 유저용 이벤트 참여 API 구현 #16

Merged
merged 2 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.hyundai.app.coupon.controller;

import com.hyundai.app.common.AdventureOfHeendyResponse;
import com.hyundai.app.coupon.domain.Coupon;
import com.hyundai.app.coupon.service.CouponService;
import com.hyundai.app.security.methodparam.MemberId;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import java.util.List;

/**
* @author 엄상은
* @since 2024/02/23
* 사용자용 쿠폰 컨트롤러
*/
@Api("사용자용 쿠폰 관련 API")
@RequiredArgsConstructor
@RequestMapping("/api/v1/coupons")
@RestController
public class CouponController {
private final CouponService couponService;

@ApiOperation("사용자용 쿠폰 전체 조회 API")
@GetMapping
public AdventureOfHeendyResponse<List<Coupon>> findCouponList(@ApiIgnore @MemberId Integer memberId) {
return AdventureOfHeendyResponse.success("사용자의 쿠폰 목록을 가져왔습니다.", couponService.findMemberCouponList(memberId));
}
}
29 changes: 29 additions & 0 deletions src/main/java/com/hyundai/app/coupon/domain/MemberCoupon.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.hyundai.app.coupon.domain;

import com.hyundai.app.common.entity.BaseEntity;

import java.time.LocalDate;

/**
* @author 엄상은
* @since 2024/02/22
* 유저가 가지고 있는 쿠폰 엔티티
*/
public class MemberCoupon extends BaseEntity {
private int id;
private int memberId;
private int couponId;
private int isUsed;
private String channelType;
private LocalDate expiredAt;

public MemberCoupon(int memberId, int couponId, String channelType) {
this.memberId = memberId;
this.couponId = couponId;
this.channelType = channelType;
}

public static MemberCoupon of(int memberId, int couponId, String channelType) {
return new MemberCoupon(memberId, couponId, channelType);
}
}
4 changes: 4 additions & 0 deletions src/main/java/com/hyundai/app/coupon/mapper/CouponMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@
@Mapper
public interface CouponMapper {
List<Coupon> findCouponList(int storeId);

Coupon findById(int couponId);

List<Coupon> findMemberCouponList(Integer memberId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.hyundai.app.coupon.mapper;

import com.hyundai.app.coupon.domain.MemberCoupon;

/**
* @author 엄상은
* @since 2024/02/22
* 쿠폰을 가진 사용자 매퍼
*/
public interface MemberCouponMapper {
void saveMemberCoupon(MemberCoupon memberCoupon);
}
10 changes: 10 additions & 0 deletions src/main/java/com/hyundai/app/coupon/service/CouponService.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,14 @@ public List<Coupon> findCouponList(int storeId) {
}
return couponList;
}

public List<Coupon> findMemberCouponList(Integer memberId) {
List<Coupon> couponList = couponMapper.findMemberCouponList(memberId);
for (Coupon coupon: couponList) {
CouponType couponType = coupon.getCouponType();
String description = couponType.getDescription(coupon);
coupon.updateContent(description);
}
return couponList;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

import com.hyundai.app.common.AdventureOfHeendyResponse;
import com.hyundai.app.event.dto.EventDetailResDto;
import com.hyundai.app.event.dto.EventParticipateResDto;
import com.hyundai.app.event.enumType.EventType;
import com.hyundai.app.event.service.EventService;
import com.hyundai.app.security.methodparam.MemberId;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.util.Random;

Expand All @@ -35,6 +35,13 @@ public AdventureOfHeendyResponse<EventDetailResDto> findCurrentEventByEventType(
return AdventureOfHeendyResponse.success("이벤트 목록을 가져왔습니다.", eventService.findCurrentEventByEventType(eventType));
}

@PostMapping("{eventId}/participate")
@ApiOperation("유저용 이벤트 참여 API")
public AdventureOfHeendyResponse<EventParticipateResDto> participateEvent(@ApiIgnore @MemberId Integer memberId,
@PathVariable int eventId){
return AdventureOfHeendyResponse.success("이벤트 참여에 성공했습니다.", eventService.participateEvent(memberId, eventId));
}

/**
* @author 황수영
* @since 2024/02/14
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/com/hyundai/app/event/domain/MemberEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,13 @@ public class MemberEvent extends BaseEntity {
private int id;
private int eventId;
private int memberId;

public MemberEvent(int eventId, int memberId) {
this.eventId = eventId;
this.memberId = memberId;
}

public static MemberEvent of(int eventId, int memberId) {
return new MemberEvent(eventId, memberId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public class EventDetailResDto {
private LocalDate finishedAt;
private int maxCount;
private int visitedCount;
private int couponId;
private List<EventActiveTimeZoneDto> eventActiveTimeZoneDto;

public void setActiveTimeList(List<EventActiveTimeZoneDto> eventActiveTimeZoneDto) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.hyundai.app.event.dto;

import com.hyundai.app.coupon.domain.Coupon;
import lombok.Getter;

/**
* @author 엄상은
* @since 2024/02/22
* 이벤트 참여 응답 DTO
*/
@Getter
public class EventParticipateResDto {
EventDetailResDto eventDetailResDto;
Coupon coupon;

public EventParticipateResDto(EventDetailResDto eventDetailResDto, Coupon coupon) {
this.eventDetailResDto = eventDetailResDto;
this.coupon = coupon;
}

public static EventParticipateResDto from(EventDetailResDto eventDetailResDto, Coupon coupon) {
return new EventParticipateResDto(eventDetailResDto, coupon);
}

public static EventParticipateResDto of(EventDetailResDto eventDetailResDto) {
return new EventParticipateResDto(eventDetailResDto, null);
}

public void updateCoupon(Coupon coupon) {
this.coupon = coupon;
}
}
2 changes: 2 additions & 0 deletions src/main/java/com/hyundai/app/event/mapper/EventMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ public interface EventMapper {
void delete(int eventId);

List<EventDetailResDto> findEventAllByEventType(EventType eventType);

void increaseVisitedCount(int eventId);
}
14 changes: 14 additions & 0 deletions src/main/java/com/hyundai/app/event/mapper/MemberEventMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.hyundai.app.event.mapper;

import com.hyundai.app.event.domain.MemberEvent;
import org.apache.ibatis.annotations.Mapper;

/**
* @author 엄상은
* @since 2024/02/21
* 이벤트에 참여한 회원 Mapper
*/
@Mapper
public interface MemberEventMapper {
void saveMemberEvent(MemberEvent memberEvent);
}
53 changes: 53 additions & 0 deletions src/main/java/com/hyundai/app/event/service/EventService.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
package com.hyundai.app.event.service;

import com.hyundai.app.common.entity.IdWithCriteria;
import com.hyundai.app.coupon.domain.Coupon;
import com.hyundai.app.coupon.domain.MemberCoupon;
import com.hyundai.app.coupon.mapper.CouponMapper;
import com.hyundai.app.coupon.mapper.MemberCouponMapper;
import com.hyundai.app.event.domain.MemberEvent;
import com.hyundai.app.event.dto.*;
import com.hyundai.app.event.enumType.EventType;
import com.hyundai.app.event.enumType.RewardType;
import com.hyundai.app.event.mapper.EventActiveTimeMapper;
import com.hyundai.app.event.mapper.EventMapper;
import com.hyundai.app.event.mapper.MemberEventMapper;
import com.hyundai.app.exception.AdventureOfHeendyException;
import com.hyundai.app.exception.ErrorCode;
import lombok.RequiredArgsConstructor;
Expand All @@ -24,6 +31,9 @@
public class EventService {
private final EventMapper eventMapper;
private final EventActiveTimeMapper eventActiveTimeMapper;
private final MemberEventMapper memberEventMapper;
private final MemberCouponMapper memberCouponMapper;
private final CouponMapper couponMapper;

public EventDetailResDto findCurrentEventByEventType(EventType eventType) {
EventDetailResDto eventDetailResDto = eventMapper.findCurrentEventByEventType(eventType);
Expand Down Expand Up @@ -71,6 +81,17 @@ public EventDetailResDto findEventAndValidate(int storeId, int eventId) {
return eventDetailResDto;
}

private EventDetailResDto findAvailableEvent(int eventId) {
EventDetailResDto eventDetailResDto = eventMapper.findById(eventId);
if (eventDetailResDto == null) {
throw new IllegalArgumentException("해당 이벤트가 존재하지 않습니다.");
}
if (eventDetailResDto.getVisitedCount() >= eventDetailResDto.getMaxCount()) {
throw new IllegalArgumentException("이벤트 참여가 마감되었습니다.");
}
return eventDetailResDto;
}

private List<EventActiveTimeZoneDto> findEventActiveTime(int eventId) {
List<EventActiveTimeZoneDto> eventActiveTimeZoneDto = eventActiveTimeMapper.findByEventId(eventId);
return eventActiveTimeZoneDto;
Expand Down Expand Up @@ -110,6 +131,38 @@ public Void delete(int storeId, int eventId) {
return null;
}

public EventParticipateResDto participateEvent(Integer memberId, int eventId) {
EventDetailResDto eventDetailResDto = findAvailableEvent(eventId);
EventParticipateResDto eventVisitResDto = EventParticipateResDto.of(eventDetailResDto);
if (eventDetailResDto.getRewardType() == RewardType.COUPON) {
int couponId = eventDetailResDto.getCouponId();
Coupon coupon = findCoupon(couponId);
eventVisitResDto.updateCoupon(coupon);
saveMemberCoupon(memberId, couponId, "OFFLINE");
}
visitEvent(memberId, eventId);
return eventVisitResDto;
}

private Coupon findCoupon(int couponId) {
Coupon coupon = couponMapper.findById(couponId);
if (coupon == null) {
throw new IllegalArgumentException("해당 쿠폰이 존재하지 않습니다.");
}
return coupon;
}

private void saveMemberCoupon(int memberId, int couponId, String channelType) {
MemberCoupon memberCoupon = MemberCoupon.of(memberId, couponId, channelType);
memberCouponMapper.saveMemberCoupon(memberCoupon);
}

private void visitEvent(int memberId, int eventId) {
MemberEvent memberEvent = MemberEvent.of(eventId, memberId);
memberEventMapper.saveMemberEvent(memberEvent);
eventMapper.increaseVisitedCount(eventId);
}

/**
* @author 황수영
* @since 2024/02/20
Expand Down
26 changes: 26 additions & 0 deletions src/main/resources/mapper/CouponMapper.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,30 @@
FROM coupon
WHERE store_id = #{storeId}
</select>

<select id="findById" parameterType="int" resultType="coupon">
SELECT id
, coupon_type
, discount_rate
, discount_amount
, minimum_amount
, started_at
, finished_at
FROM coupon
WHERE id = #{couponId}
</select>

<select id="findMemberCouponList" parameterType="int" resultType="coupon">
SELECT id
, coupon_type
, discount_rate
, discount_amount
, minimum_amount
, started_at
, finished_at
FROM coupon
WHERE id IN (SELECT coupon_id
FROM member_coupon
WHERE member_id = #{memberId})
</select>
</mapper>
7 changes: 7 additions & 0 deletions src/main/resources/mapper/EventMapper.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
, finished_at
, max_count
, visited_count
, coupon_id
FROM event
WHERE id = #{eventId}
</select>
Expand Down Expand Up @@ -139,4 +140,10 @@
AND max_count >= visited_count
AND is_deleted = 0
</select>

<update id="increaseVisitedCount" parameterType="int">
UPDATE event
SET visited_count = visited_count + 1
WHERE id = #{eventId}
</update>
</mapper>
17 changes: 17 additions & 0 deletions src/main/resources/mapper/MemberCouponMapper.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hyundai.app.coupon.mapper.MemberCouponMapper">
<!-- @author 엄상은 -->
<!-- @since 2024/02/22 -->
<!-- 쿠폰을 가진 멤버 mapper -->
<insert id="saveMemberCoupon" parameterType="membercoupon">
INSERT INTO member_coupon (member_id
, coupon_id
, channel_type)
VALUES (#{memberId}
, #{couponId}
, #{channelType})
</insert>
</mapper>
15 changes: 15 additions & 0 deletions src/main/resources/mapper/MemberEventMapper.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hyundai.app.event.mapper.MemberEventMapper">
<!-- @author 엄상은 -->
<!-- @since 2024/02/22 -->
<!-- 이벤트에 참여한 멤버 mapper -->
<insert id="saveMemberEvent" parameterType="memberevent">
INSERT INTO member_event (member_id
, event_id)
VALUES (#{memberId}
, #{eventId})
</insert>
</mapper>
Loading