feat(memberCenter): 新增会员促销活动功能
- 新增积分奖励活动类型 - 实现活动期间内订阅或续订会员的积分加成 - 增加活动参与记录和状态管理 - 优化活动列表展示逻辑 - 修复活动开始时间不能大于结束时间的问题feature/comment
parent
40bc8128eb
commit
4fc9909191
|
@ -18,6 +18,7 @@ import lombok.RequiredArgsConstructor;
|
|||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
|
@ -43,10 +44,11 @@ public class MemberController {
|
|||
* @return 用户会员
|
||||
*/
|
||||
@PostMapping("createMember")
|
||||
public AjaxResult createMemberCenter(@RequestBody UserMemberDto userMemberDto) {
|
||||
public AjaxResult createMemberCenter(@RequestBody @Valid UserMemberDto userMemberDto) {
|
||||
Long userId = userMemberDto.getUserId();
|
||||
Long memberLevelId = userMemberDto.getMemberLevelId();
|
||||
String paymentMethod = userMemberDto.getPaymentMethod();
|
||||
Long promotionId = userMemberDto.getPromotionId();
|
||||
|
||||
SysUser sysUser = sysUserService.selectUserById(userId);
|
||||
if (!Optional.ofNullable(sysUser).isPresent()) {
|
||||
|
@ -58,7 +60,7 @@ public class MemberController {
|
|||
return AjaxResult.warn("会员等级不存在");
|
||||
}
|
||||
|
||||
Member member = memberService.createUserMember(userId, memberLevelId, paymentMethod);
|
||||
Member member = memberService.createUserMember(userId, memberLevelId, paymentMethod, promotionId);
|
||||
if (!Optional.ofNullable(member).isPresent()) {
|
||||
return AjaxResult.warn("创建会员失败");
|
||||
}
|
||||
|
@ -69,6 +71,7 @@ public class MemberController {
|
|||
|
||||
/**
|
||||
* 获取积分余额和历史记录
|
||||
*
|
||||
* @return 积分余额和历史记录
|
||||
*/
|
||||
@GetMapping("getPoints")
|
||||
|
@ -99,7 +102,7 @@ public class MemberController {
|
|||
* 会员积分充值
|
||||
*/
|
||||
@PostMapping("rechargePoints")
|
||||
public AjaxResult rechargePoints(@RequestBody RechargePointsDto rechargePointsDto) {
|
||||
public AjaxResult rechargePoints(@RequestBody @Valid RechargePointsDto rechargePointsDto) {
|
||||
Long userId = rechargePointsDto.getUserId();
|
||||
Double amount = rechargePointsDto.getAmount();
|
||||
|
||||
|
|
|
@ -4,12 +4,15 @@ package com.mcwl.web.controller.memberCenter;
|
|||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.mcwl.common.core.domain.AjaxResult;
|
||||
import com.mcwl.common.utils.SecurityUtils;
|
||||
import com.mcwl.memberCenter.domain.Member;
|
||||
import com.mcwl.memberCenter.domain.MemberPromotion;
|
||||
import com.mcwl.memberCenter.domain.Promotion;
|
||||
import com.mcwl.memberCenter.domain.dto.JoinPromotionDto;
|
||||
import com.mcwl.memberCenter.domain.dto.PromotionDto;
|
||||
import com.mcwl.memberCenter.enums.MemberEnum;
|
||||
import com.mcwl.memberCenter.enums.PromotionEnum;
|
||||
import com.mcwl.memberCenter.service.MemberPromotionService;
|
||||
import com.mcwl.memberCenter.service.MemberService;
|
||||
import com.mcwl.memberCenter.service.PromotionService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
@ -32,6 +35,8 @@ public class PromotionController {
|
|||
|
||||
private final MemberPromotionService memberPromotionService;
|
||||
|
||||
private final MemberService memberService;
|
||||
|
||||
|
||||
/**
|
||||
* 创建活动
|
||||
|
@ -39,6 +44,11 @@ public class PromotionController {
|
|||
@PostMapping("createPromotion")
|
||||
public AjaxResult createPromotion(@RequestBody @Valid PromotionDto promotionDto) {
|
||||
|
||||
Date startTime = promotionDto.getStartTime();
|
||||
Date endTime = promotionDto.getEndTime();
|
||||
if (startTime.after(endTime)) {
|
||||
return AjaxResult.warn("活动开始时间不能大于结束时间");
|
||||
}
|
||||
Promotion promotion = new Promotion();
|
||||
|
||||
BeanUtil.copyProperties(promotionDto, promotion);
|
||||
|
@ -55,7 +65,7 @@ public class PromotionController {
|
|||
@GetMapping("promotionList")
|
||||
public AjaxResult promotionList() {
|
||||
List<Promotion> promotionList = promotionService.lambdaQuery()
|
||||
.lt(Promotion::getEndTime, new Date())
|
||||
.gt(Promotion::getEndTime, new Date())
|
||||
.list();
|
||||
return AjaxResult.success(promotionList);
|
||||
}
|
||||
|
@ -68,7 +78,7 @@ public class PromotionController {
|
|||
// 获取当前用户
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
List<MemberPromotion> memberPromotionList = memberPromotionService.lambdaQuery()
|
||||
.eq(MemberPromotion::getMemberId, userId)
|
||||
.eq(MemberPromotion::getUserId, userId)
|
||||
.list();
|
||||
return AjaxResult.success(memberPromotionList);
|
||||
}
|
||||
|
@ -98,20 +108,63 @@ public class PromotionController {
|
|||
return AjaxResult.warn("活动已过期");
|
||||
}
|
||||
|
||||
String memberLevelIds = promotion.getMemberLevelId();
|
||||
if (!memberLevelIds.contains(userId.toString())) {
|
||||
// 获取当前用户是否参与过该活动
|
||||
if (isJoinPromotion(userId, promotionId)) {
|
||||
return AjaxResult.warn("您已参与过该活动");
|
||||
}
|
||||
|
||||
// 是否在活动期间内订阅或续订会员
|
||||
// if (!isSubscribe(userId, promotion)) {
|
||||
// return AjaxResult.warn("请在活动期间内订阅或续期会员后参加该活动");
|
||||
// }
|
||||
|
||||
Member member = memberService.getUseUserMemberByUserId(userId);
|
||||
|
||||
String memberLevelIds = promotion.getMemberLevelIds();
|
||||
if (!memberLevelIds.contains(member.getMemberLevelId().toString())) {
|
||||
return AjaxResult.warn("无法参与该活动,请查看活动条件");
|
||||
}
|
||||
MemberPromotion memberPromotion = new MemberPromotion();
|
||||
memberPromotion.setMemberId(userId);
|
||||
memberPromotion.setPromotionId(promotionId);
|
||||
memberPromotion.setStatus(PromotionEnum.EXPIRED);
|
||||
memberPromotion.setParticipationTime(new Date());
|
||||
MemberPromotion memberPromotion = getMemberPromotion(userId, promotionId);
|
||||
memberPromotionService.save(memberPromotion);
|
||||
|
||||
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
// private boolean isSubscribe(Long userId, Promotion promotion) {
|
||||
// if (promotion.getActivityType() == PromotionEnum.SUBSCRIBE) {
|
||||
// // 获取当前用户最新的订阅或续订
|
||||
// Member member = memberService.latestSubscription(userId);
|
||||
// if (!Optional.ofNullable(member).isPresent()) {
|
||||
// return false;
|
||||
// }
|
||||
// Date createTime = member.getCreateTime();
|
||||
// // 会员创建时间在活动开始时间之前,说明用户不符合“活动期间内订阅或续订会员”的条件
|
||||
// return !createTime.before(promotion.getStartTime());
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
|
||||
private boolean isJoinPromotion(Long userId, Long promotionId) {
|
||||
MemberPromotion memberPromotion = memberPromotionService.lambdaQuery()
|
||||
.eq(MemberPromotion::getUserId, userId)
|
||||
.eq(MemberPromotion::getPromotionId, promotionId)
|
||||
.one();
|
||||
return memberPromotion != null;
|
||||
}
|
||||
|
||||
private static MemberPromotion getMemberPromotion(Long userId, Long promotionId) {
|
||||
MemberPromotion memberPromotion = new MemberPromotion();
|
||||
memberPromotion.setUserId(userId);
|
||||
memberPromotion.setPromotionId(promotionId);
|
||||
memberPromotion.setStatus(PromotionEnum.PARTICIPATE);
|
||||
memberPromotion.setParticipationTime(new Date());
|
||||
memberPromotion.setCreateBy(SecurityUtils.getUsername());
|
||||
memberPromotion.setCreateTime(new Date());
|
||||
memberPromotion.setUpdateBy(SecurityUtils.getUsername());
|
||||
memberPromotion.setUpdateTime(new Date());
|
||||
return memberPromotion;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public class MemberCenterTest {
|
|||
private EmptyPointsRemindConsumer emptyPointsRemindConsumer;
|
||||
@Test
|
||||
public void createUserMember() {
|
||||
System.out.println(memberService.createUserMember(1L, 1013L, "wechat"));
|
||||
System.out.println(memberService.createUserMember(1L, 1013L, "wechat",1L));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -20,9 +20,9 @@ public class MemberPromotion extends BaseEntity {
|
|||
private Long id;
|
||||
|
||||
/**
|
||||
* 会员ID
|
||||
* 用户ID
|
||||
*/
|
||||
private Long memberId;
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 优惠活动ID
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.mcwl.memberCenter.domain;
|
|||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.mcwl.common.core.domain.BaseEntity;
|
||||
import com.mcwl.memberCenter.enums.PromotionEnum;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
|
@ -35,9 +36,9 @@ public class Promotion extends BaseEntity {
|
|||
private Date endTime;
|
||||
|
||||
/**
|
||||
* 活动类型,如“限时折扣”、“额外积分”、“活动期间内订阅或续订会员”
|
||||
* 活动类型,如“限时折扣”、“积分奖励”
|
||||
*/
|
||||
private String activityType;
|
||||
private PromotionEnum activityType;
|
||||
|
||||
/**
|
||||
* 折扣/积分奖励 根据活动类型,这里可以是折扣率(如0.8代表8折)
|
||||
|
@ -52,7 +53,7 @@ public class Promotion extends BaseEntity {
|
|||
/**
|
||||
* 适用会员等级 可选字段,用于指定哪些会员等级可以享受此活动(用逗号分隔的会员等级ID)
|
||||
*/
|
||||
private String memberLevelId;
|
||||
private String memberLevelIds;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -3,8 +3,10 @@ package com.mcwl.memberCenter.domain.dto;
|
|||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.mcwl.common.core.domain.BaseEntity;
|
||||
import com.mcwl.memberCenter.enums.PromotionEnum;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
@ -30,19 +32,21 @@ public class PromotionDto {
|
|||
* 活动开始时间 校验时间格式
|
||||
*/
|
||||
@NotNull(message = "活动开始时间不能为空")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date startTime;
|
||||
|
||||
/**
|
||||
* 活动结束时间
|
||||
*/
|
||||
@NotNull(message = "活动结束时间不能为空")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date endTime;
|
||||
|
||||
/**
|
||||
* 活动类型,如“限时折扣”、“额外积分”
|
||||
*/
|
||||
@NotBlank(message = "活动类型不能为空")
|
||||
private String activityType;
|
||||
@NotNull()
|
||||
private PromotionEnum activityType;
|
||||
|
||||
/**
|
||||
* 折扣/积分奖励 根据活动类型,这里可以是折扣率(如0.8代表8折)
|
||||
|
@ -59,7 +63,7 @@ public class PromotionDto {
|
|||
/**
|
||||
* 适用会员等级 可选字段,用于指定哪些会员等级可以享受此活动(可以用逗号分隔的会员等级ID)
|
||||
*/
|
||||
private String memberLevelId;
|
||||
private String memberLevelIds;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -23,4 +23,7 @@ public class UserMemberDto {
|
|||
@NotBlank(message = "支付方式不能为空")
|
||||
private String paymentMethod;
|
||||
|
||||
// 活动ID
|
||||
private Long promotionId;
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,20 @@ public enum PromotionEnum {
|
|||
/**
|
||||
* 过期
|
||||
*/
|
||||
EXPIRED("expired", "过期");
|
||||
EXPIRED("expired", "过期"),
|
||||
// /**
|
||||
// * 订阅/续订会员
|
||||
// */
|
||||
// SUBSCRIBE("subscribe", "订阅/续订会员"),
|
||||
|
||||
/**
|
||||
* 限时折扣
|
||||
*/
|
||||
DISCOUNT("discount", "限时折扣"),
|
||||
/**
|
||||
* 积分奖励
|
||||
*/
|
||||
POINTS("points", "积分奖励");
|
||||
|
||||
private final String name;
|
||||
@EnumValue
|
||||
|
|
|
@ -12,9 +12,11 @@ public interface MemberService extends IService<Member> {
|
|||
*
|
||||
* @param userId 用户id
|
||||
* @param memberLevelId 会员等级id
|
||||
* @param paymentMethod 支付方式
|
||||
* @param promotionId 活动id
|
||||
* @return 用户会员
|
||||
*/
|
||||
Member createUserMember(Long userId, Long memberLevelId, String paymentMethod);
|
||||
Member createUserMember(Long userId, Long memberLevelId, String paymentMethod, Long promotionId);
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -31,4 +33,6 @@ public interface MemberService extends IService<Member> {
|
|||
|
||||
|
||||
Member rechargePoints(Long userId, Double points);
|
||||
|
||||
Member latestSubscription(Long userId);
|
||||
}
|
||||
|
|
|
@ -7,13 +7,17 @@ import com.mcwl.common.exception.ServiceException;
|
|||
import com.mcwl.memberCenter.domain.MemberBenefit;
|
||||
import com.mcwl.memberCenter.domain.MemberLevel;
|
||||
import com.mcwl.memberCenter.domain.Member;
|
||||
import com.mcwl.memberCenter.domain.Promotion;
|
||||
import com.mcwl.memberCenter.enums.MemberBenefitTypeEnum;
|
||||
import com.mcwl.memberCenter.enums.MemberEnum;
|
||||
import com.mcwl.memberCenter.enums.MemberPeriodicEnum;
|
||||
import com.mcwl.memberCenter.enums.PromotionEnum;
|
||||
import com.mcwl.memberCenter.mapper.MemberMapper;
|
||||
import com.mcwl.memberCenter.mapper.PromotionMapper;
|
||||
import com.mcwl.memberCenter.service.MemberBenefitService;
|
||||
import com.mcwl.memberCenter.service.MemberLevelService;
|
||||
import com.mcwl.memberCenter.service.MemberService;
|
||||
import com.mcwl.memberCenter.service.PromotionService;
|
||||
import com.mcwl.system.service.ISysUserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
@ -31,8 +35,10 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
|||
|
||||
private final MemberBenefitService memberBenefitService;
|
||||
|
||||
private final PromotionMapper promotionMapper;
|
||||
|
||||
@Override
|
||||
public Member createUserMember(Long userId, Long memberLevelId, String paymentMethod) {
|
||||
public Member createUserMember(Long userId, Long memberLevelId, String paymentMethod, Long promotionId) {
|
||||
if (userId == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -79,7 +85,15 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
|||
.eq(MemberBenefit::getBenefitType, MemberBenefitTypeEnum.POINTS)
|
||||
.one();
|
||||
if (memberBenefit != null) {
|
||||
member.setPoints(memberBenefit.getBenefitDiscount());
|
||||
Double points = memberBenefit.getBenefitDiscount();
|
||||
// 根据活动id查询活动类型,如果为积分,则积分加成
|
||||
if (promotionId != null) {
|
||||
Promotion promotion = promotionMapper.selectById(promotionId);
|
||||
if (promotion.getActivityType() == PromotionEnum.POINTS) {
|
||||
points = points + promotion.getActivityValue();
|
||||
}
|
||||
}
|
||||
member.setPoints(points);
|
||||
}
|
||||
|
||||
// 设置订阅状态
|
||||
|
@ -143,6 +157,21 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Member latestSubscription(Long userId) {
|
||||
// 根据userId 查询会员,按创建时间降序,获取最新的会员
|
||||
LambdaQueryWrapper<Member> qw = new LambdaQueryWrapper<>();
|
||||
qw.eq(Member::getUserId, userId)
|
||||
.ne(Member::getSubscriptionStatus, MemberEnum.MEMBER_CENTER_EXPIRED)
|
||||
.ne(Member::getSubscriptionStatus, MemberEnum.MEMBER_CENTER_PENDING)
|
||||
.orderByDesc(Member::getCreateTime);
|
||||
List<Member> memberList = baseMapper.selectList(qw);
|
||||
if (memberList != null && !memberList.isEmpty()) {
|
||||
return memberList.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<Member> getUseUserMember(Long userId) {
|
||||
// startDate 小于等于当前时间、endDate 大于等于当前时间
|
||||
// subscriptionStatus 不为 "过期" 或 "待支付"
|
||||
|
@ -160,8 +189,9 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
|
|||
|
||||
/**
|
||||
* 根据订阅周期和开始时间 计算结束时间
|
||||
*
|
||||
* @param subscriptionPeriod 订阅周期
|
||||
* @param calendar 结束时间(日历)
|
||||
* @param calendar 结束时间(日历)
|
||||
* @return 结束时间
|
||||
*/
|
||||
private Date getEndDate(MemberPeriodicEnum subscriptionPeriod, Calendar calendar) {
|
||||
|
|
Loading…
Reference in New Issue