From 4fc9909191e67b4a3c1794c7bb505688fbb5399a Mon Sep 17 00:00:00 2001 From: yang <2119157836@qq.com> Date: Sun, 5 Jan 2025 18:35:08 +0800 Subject: [PATCH] =?UTF-8?q?feat(memberCenter):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E4=BC=9A=E5=91=98=E4=BF=83=E9=94=80=E6=B4=BB=E5=8A=A8=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增积分奖励活动类型 - 实现活动期间内订阅或续订会员的积分加成 - 增加活动参与记录和状态管理 - 优化活动列表展示逻辑 - 修复活动开始时间不能大于结束时间的问题 --- .../memberCenter/MemberController.java | 9 ++- .../memberCenter/PromotionController.java | 71 ++++++++++++++++--- .../mcwl/memberCenter/MemberCenterTest.java | 2 +- .../memberCenter/domain/MemberPromotion.java | 4 +- .../mcwl/memberCenter/domain/Promotion.java | 7 +- .../memberCenter/domain/dto/PromotionDto.java | 10 ++- .../domain/dto/UserMemberDto.java | 3 + .../memberCenter/enums/PromotionEnum.java | 15 +++- .../memberCenter/service/MemberService.java | 6 +- .../service/impl/MemberServiceImpl.java | 36 +++++++++- 10 files changed, 137 insertions(+), 26 deletions(-) diff --git a/mcwl-admin/src/main/java/com/mcwl/web/controller/memberCenter/MemberController.java b/mcwl-admin/src/main/java/com/mcwl/web/controller/memberCenter/MemberController.java index c2ea63f..d4c51fd 100644 --- a/mcwl-admin/src/main/java/com/mcwl/web/controller/memberCenter/MemberController.java +++ b/mcwl-admin/src/main/java/com/mcwl/web/controller/memberCenter/MemberController.java @@ -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(); diff --git a/mcwl-admin/src/main/java/com/mcwl/web/controller/memberCenter/PromotionController.java b/mcwl-admin/src/main/java/com/mcwl/web/controller/memberCenter/PromotionController.java index 8073e89..59e120e 100644 --- a/mcwl-admin/src/main/java/com/mcwl/web/controller/memberCenter/PromotionController.java +++ b/mcwl-admin/src/main/java/com/mcwl/web/controller/memberCenter/PromotionController.java @@ -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 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 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; + } + } diff --git a/mcwl-admin/src/test/java/com/mcwl/memberCenter/MemberCenterTest.java b/mcwl-admin/src/test/java/com/mcwl/memberCenter/MemberCenterTest.java index a36da35..fb6dc69 100644 --- a/mcwl-admin/src/test/java/com/mcwl/memberCenter/MemberCenterTest.java +++ b/mcwl-admin/src/test/java/com/mcwl/memberCenter/MemberCenterTest.java @@ -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 diff --git a/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/domain/MemberPromotion.java b/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/domain/MemberPromotion.java index 62e24d7..fe4c049 100644 --- a/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/domain/MemberPromotion.java +++ b/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/domain/MemberPromotion.java @@ -20,9 +20,9 @@ public class MemberPromotion extends BaseEntity { private Long id; /** - * 会员ID + * 用户ID */ - private Long memberId; + private Long userId; /** * 优惠活动ID diff --git a/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/domain/Promotion.java b/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/domain/Promotion.java index bdf59e5..8d1a358 100644 --- a/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/domain/Promotion.java +++ b/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/domain/Promotion.java @@ -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; diff --git a/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/domain/dto/PromotionDto.java b/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/domain/dto/PromotionDto.java index 62c727d..57a81cb 100644 --- a/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/domain/dto/PromotionDto.java +++ b/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/domain/dto/PromotionDto.java @@ -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; diff --git a/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/domain/dto/UserMemberDto.java b/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/domain/dto/UserMemberDto.java index 5f3af1b..a5080e6 100644 --- a/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/domain/dto/UserMemberDto.java +++ b/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/domain/dto/UserMemberDto.java @@ -23,4 +23,7 @@ public class UserMemberDto { @NotBlank(message = "支付方式不能为空") private String paymentMethod; + // 活动ID + private Long promotionId; + } diff --git a/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/enums/PromotionEnum.java b/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/enums/PromotionEnum.java index 1885065..b51e031 100644 --- a/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/enums/PromotionEnum.java +++ b/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/enums/PromotionEnum.java @@ -18,7 +18,20 @@ public enum PromotionEnum { /** * 过期 */ - EXPIRED("expired", "过期"); + EXPIRED("expired", "过期"), +// /** +// * 订阅/续订会员 +// */ +// SUBSCRIBE("subscribe", "订阅/续订会员"), + + /** + * 限时折扣 + */ + DISCOUNT("discount", "限时折扣"), + /** + * 积分奖励 + */ + POINTS("points", "积分奖励"); private final String name; @EnumValue diff --git a/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/service/MemberService.java b/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/service/MemberService.java index 59783f6..1074264 100644 --- a/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/service/MemberService.java +++ b/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/service/MemberService.java @@ -12,9 +12,11 @@ public interface MemberService extends IService { * * @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 rechargePoints(Long userId, Double points); + + Member latestSubscription(Long userId); } diff --git a/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/service/impl/MemberServiceImpl.java b/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/service/impl/MemberServiceImpl.java index 5411b11..a5bd52c 100644 --- a/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/service/impl/MemberServiceImpl.java +++ b/mcwl-memberCenter/src/main/java/com/mcwl/memberCenter/service/impl/MemberServiceImpl.java @@ -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 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 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 impleme return null; } + @Override + public Member latestSubscription(Long userId) { + // 根据userId 查询会员,按创建时间降序,获取最新的会员 + LambdaQueryWrapper 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 memberList = baseMapper.selectList(qw); + if (memberList != null && !memberList.isEmpty()) { + return memberList.get(0); + } + return null; + } + private List getUseUserMember(Long userId) { // startDate 小于等于当前时间、endDate 大于等于当前时间 // subscriptionStatus 不为 "过期" 或 "待支付" @@ -160,8 +189,9 @@ public class MemberServiceImpl extends ServiceImpl impleme /** * 根据订阅周期和开始时间 计算结束时间 + * * @param subscriptionPeriod 订阅周期 - * @param calendar 结束时间(日历) + * @param calendar 结束时间(日历) * @return 结束时间 */ private Date getEndDate(MemberPeriodicEnum subscriptionPeriod, Calendar calendar) {