From 8543a228fd0ee751a601cc81505cb5af19cb2338 Mon Sep 17 00:00:00 2001 From: Chopper711 Date: Fri, 23 Dec 2022 14:51:06 +0800 Subject: [PATCH] =?UTF-8?q?'=E4=BC=98=E6=83=A0=E5=88=B8=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E6=94=B9=E7=89=88'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../promotion/CouponBuyerController.java | 22 ++ .../impl/RegisteredCouponActivityExecute.java | 38 ++- .../main/java/cn/lili/cache/CachePrefix.java | 13 +- .../java/cn/lili/common/enums/ResultCode.java | 5 +- .../cn/lili/common/security/AuthUser.java | 4 +- .../common/security/context/UserContext.java | 18 ++ .../common/security/enums/SecurityEnum.java | 2 +- .../serviceimpl/ConnectServiceImpl.java | 10 + .../serviceimpl/CategoryServiceImpl.java | 7 +- .../member/serviceimpl/MemberServiceImpl.java | 2 + .../order/entity/dto/PriceDetailDTO.java | 3 + .../promotion/entity/dos/CouponActivity.java | 3 +- .../entity/dto/CouponActivityTrigger.java | 32 +++ .../entity/enums/CouponActivityTypeEnum.java | 10 +- .../entity/enums/CouponRangeDayEnum.java | 9 + .../service/CouponActivityService.java | 14 +- .../CouponActivityServiceImpl.java | 241 +++++++++++++----- .../serviceimpl/CouponServiceImpl.java | 46 ++-- .../serviceimpl/MemberCouponServiceImpl.java | 8 +- .../serviceimpl/SeckillServiceImpl.java | 14 +- .../CouponActivityManagerController.java | 10 +- 21 files changed, 387 insertions(+), 124 deletions(-) create mode 100644 framework/src/main/java/cn/lili/modules/promotion/entity/dto/CouponActivityTrigger.java diff --git a/buyer-api/src/main/java/cn/lili/controller/promotion/CouponBuyerController.java b/buyer-api/src/main/java/cn/lili/controller/promotion/CouponBuyerController.java index 4d0dfed4..e505cb58 100644 --- a/buyer-api/src/main/java/cn/lili/controller/promotion/CouponBuyerController.java +++ b/buyer-api/src/main/java/cn/lili/controller/promotion/CouponBuyerController.java @@ -7,11 +7,14 @@ import cn.lili.common.security.context.UserContext; import cn.lili.common.vo.PageVO; import cn.lili.common.vo.ResultMessage; import cn.lili.modules.promotion.entity.dos.MemberCoupon; +import cn.lili.modules.promotion.entity.dto.CouponActivityTrigger; import cn.lili.modules.promotion.entity.dto.search.CouponSearchParams; import cn.lili.modules.promotion.entity.dto.search.MemberCouponSearchParams; +import cn.lili.modules.promotion.entity.enums.CouponActivityTypeEnum; import cn.lili.modules.promotion.entity.enums.CouponGetEnum; import cn.lili.modules.promotion.entity.enums.PromotionsStatusEnum; import cn.lili.modules.promotion.entity.vos.CouponVO; +import cn.lili.modules.promotion.service.CouponActivityService; import cn.lili.modules.promotion.service.CouponService; import cn.lili.modules.promotion.service.MemberCouponService; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -26,6 +29,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.validation.constraints.NotNull; +import java.util.List; import java.util.Objects; /** @@ -45,12 +49,30 @@ public class CouponBuyerController { @Autowired private CouponService couponService; + /** + * 优惠券活动 + */ + @Autowired + private CouponActivityService couponActivityService; + /** * 会员优惠券 */ @Autowired private MemberCouponService memberCouponService; + @GetMapping("/activity") + @ApiOperation(value = "自动领取优惠券") + public ResultMessage> activity() { + return ResultUtil.data(couponActivityService.trigger( + CouponActivityTrigger.builder() + .couponActivityTypeEnum(CouponActivityTypeEnum.AUTO_COUPON) + .nickName(UserContext.getCurrentUser().getNickName()) + .userId(UserContext.getCurrentUser().getId()) + .build()) + ); + } + @GetMapping @ApiOperation(value = "获取可领取优惠券列表") public ResultMessage> getCouponList(CouponSearchParams queryParam, PageVO page) { diff --git a/consumer/src/main/java/cn/lili/event/impl/RegisteredCouponActivityExecute.java b/consumer/src/main/java/cn/lili/event/impl/RegisteredCouponActivityExecute.java index a103b767..96892d48 100644 --- a/consumer/src/main/java/cn/lili/event/impl/RegisteredCouponActivityExecute.java +++ b/consumer/src/main/java/cn/lili/event/impl/RegisteredCouponActivityExecute.java @@ -1,18 +1,17 @@ package cn.lili.event.impl; +import cn.lili.cache.Cache; +import cn.lili.cache.CachePrefix; +import cn.lili.common.utils.StringUtils; import cn.lili.event.MemberRegisterEvent; import cn.lili.modules.member.entity.dos.Member; -import cn.lili.modules.promotion.entity.dos.CouponActivity; +import cn.lili.modules.member.service.MemberService; +import cn.lili.modules.promotion.entity.dto.CouponActivityTrigger; import cn.lili.modules.promotion.entity.enums.CouponActivityTypeEnum; -import cn.lili.modules.promotion.entity.enums.PromotionsStatusEnum; import cn.lili.modules.promotion.service.CouponActivityService; -import cn.lili.modules.promotion.tools.PromotionTools; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.util.List; - /** * 注册赠券活动 * @@ -25,6 +24,12 @@ public class RegisteredCouponActivityExecute implements MemberRegisterEvent { @Autowired private CouponActivityService couponActivityService; + + @Autowired + private MemberService memberService; + @Autowired + private Cache cache; + /** * 获取进行中的注册赠券的优惠券活动 * 发送注册赠券 @@ -33,9 +38,22 @@ public class RegisteredCouponActivityExecute implements MemberRegisterEvent { */ @Override public void memberRegister(Member member) { - List couponActivities = couponActivityService.list(new QueryWrapper() - .eq("coupon_activity_type", CouponActivityTypeEnum.REGISTERED.name()) - .and(PromotionTools.queryPromotionStatus(PromotionsStatusEnum.START))); - couponActivityService.registered(couponActivities, member); + //用户注册赠券 + couponActivityService.trigger(CouponActivityTrigger.builder() + .nickName(member.getNickName()) + .userId(member.getId()) + .couponActivityTypeEnum(CouponActivityTypeEnum.REGISTERED) + .build()); + //邀请人赠券 + String memberId = (String) cache.get(CachePrefix.INVITER.getPrefix() + member.getId()); + if (StringUtils.isNotEmpty(memberId)) { + //邀请人 + Member inviter = memberService.getById(memberId); + couponActivityService.trigger(CouponActivityTrigger.builder() + .nickName(inviter.getNickName()) + .userId(inviter.getId()) + .couponActivityTypeEnum(CouponActivityTypeEnum.INVITE_NEW) + .build()); + } } } diff --git a/framework/src/main/java/cn/lili/cache/CachePrefix.java b/framework/src/main/java/cn/lili/cache/CachePrefix.java index bfa31f49..b110295c 100644 --- a/framework/src/main/java/cn/lili/cache/CachePrefix.java +++ b/framework/src/main/java/cn/lili/cache/CachePrefix.java @@ -208,6 +208,10 @@ public enum CachePrefix { * 促销活动 */ PROMOTION, + /** + * 当前优惠券活动 + */ + CURRENT_COUPON_ACTIVITY, /** * 促销活动 */ @@ -441,6 +445,10 @@ public enum CachePrefix { * 分销员 */ DISTRIBUTION, + /** + * 邀请人 + */ + INVITER, /** * 找回手机 @@ -503,12 +511,11 @@ public enum CachePrefix { /** * 扫码登录 + * * @param str * @return */ - QR_CODE_LOGIN_SESSION - - ; + QR_CODE_LOGIN_SESSION; public static String removePrefix(String str) { diff --git a/framework/src/main/java/cn/lili/common/enums/ResultCode.java b/framework/src/main/java/cn/lili/common/enums/ResultCode.java index 6acf99dd..7e7966c7 100644 --- a/framework/src/main/java/cn/lili/common/enums/ResultCode.java +++ b/framework/src/main/java/cn/lili/common/enums/ResultCode.java @@ -280,6 +280,7 @@ public enum ResultCode { PROMOTION_ACTIVITY_GOODS_ERROR(40009, "当前活动已经开始无法添加商品"), PROMOTION_ACTIVITY_ERROR(400010, "当前促销活动不存在"), PROMOTION_LOG_EXIST(40011, "活动已参加,已发重复参加"), + APPLY_END_TIME_ERROR(40012, "参与截至时间不能小于当前时间,不能大于活动开始时间"), /** * 优惠券 @@ -301,6 +302,7 @@ public enum ResultCode { COUPON_SCOPE_ERROR(41014, "指定商品范围关联id无效!"), COUPON_MEMBER_NOT_EXIST(41015, "没有当前会员优惠券"), COUPON_MEMBER_STATUS_ERROR(41016, "当前会员优惠券已过期/作废无法变更状态!"), + COUPON_RANGE_ERROR(41017, "优惠券使用时间范围错误"), SPECIAL_CANT_USE(41019, "特殊商品不能使用优惠券,不能使用"), @@ -308,7 +310,7 @@ public enum ResultCode { COUPON_DELETE_ERROR(41021, "删除优惠券失败"), COUPON_ACTIVITY_NOT_EXIST(41022, "当前优惠券活动不存在"), COUPON_ACTIVITY_SAVE_ERROR(41023, "保存优惠券活动失败"), - COUPON_ACTIVITY_MAX_NUM(41024, "优惠券活动赠券数量最多为3"), + COUPON_ACTIVITY_MAX_NUM(41024, "优惠券活动赠券数量最多为5"), COUPON_DO_NOT_RECEIVER(41030, "当前优惠券不允许主动领取"), @@ -373,6 +375,7 @@ public enum ResultCode { COUPON_ACTIVITY_ITEM_ERROR(46003, "优惠券活动必须指定优惠券,不能为空"), COUPON_ACTIVITY_ITEM_MUST_NUM_ERROR(46004, "优惠券活动最多指定10个优惠券"), COUPON_ACTIVITY_ITEM_NUM_ERROR(46005, "赠券数量必须大于0"), + COUPON_ACTIVITY_ITEM_NUM_MAX_VALUE_2(46006, "赠券数量最大为2"), /** * 其他促销 diff --git a/framework/src/main/java/cn/lili/common/security/AuthUser.java b/framework/src/main/java/cn/lili/common/security/AuthUser.java index f49f2051..95978ce3 100644 --- a/framework/src/main/java/cn/lili/common/security/AuthUser.java +++ b/framework/src/main/java/cn/lili/common/security/AuthUser.java @@ -3,6 +3,7 @@ package cn.lili.common.security; import cn.lili.common.security.enums.UserEnums; import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; import java.io.Serializable; @@ -10,6 +11,7 @@ import java.io.Serializable; * @author Chopper */ @Data +@NoArgsConstructor @AllArgsConstructor public class AuthUser implements Serializable { @@ -85,7 +87,7 @@ public class AuthUser implements Serializable { this.nickName = nickName; } - public AuthUser(String username, String id, UserEnums manager, String nickName, Boolean isSuper, String clerkId,String face) { + public AuthUser(String username, String id, UserEnums manager, String nickName, Boolean isSuper, String clerkId, String face) { this.username = username; this.id = id; this.role = manager; diff --git a/framework/src/main/java/cn/lili/common/security/context/UserContext.java b/framework/src/main/java/cn/lili/common/security/context/UserContext.java index 78d3e5a6..a1c86cae 100644 --- a/framework/src/main/java/cn/lili/common/security/context/UserContext.java +++ b/framework/src/main/java/cn/lili/common/security/context/UserContext.java @@ -7,6 +7,7 @@ import cn.lili.common.exception.ServiceException; import cn.lili.common.security.AuthUser; import cn.lili.common.security.enums.SecurityEnum; import cn.lili.common.security.token.SecretKeyUtil; +import cn.lili.common.utils.StringUtils; import com.google.gson.Gson; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; @@ -101,4 +102,21 @@ public class UserContext { return null; } } + + + /** + * 写入邀请人信息 + */ + public static void settingInviter(String memberId, Cache cache) { + if (RequestContextHolder.getRequestAttributes() != null) { + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + //邀请人id + String inviterId = request.getHeader(SecurityEnum.INVITER.getValue()); + if (StringUtils.isNotEmpty(inviterId)) { + cache.put(CachePrefix.INVITER.getPrefix() + memberId, inviterId); + } + } + } + + } diff --git a/framework/src/main/java/cn/lili/common/security/enums/SecurityEnum.java b/framework/src/main/java/cn/lili/common/security/enums/SecurityEnum.java index c89a3f4b..ad49e685 100644 --- a/framework/src/main/java/cn/lili/common/security/enums/SecurityEnum.java +++ b/framework/src/main/java/cn/lili/common/security/enums/SecurityEnum.java @@ -10,7 +10,7 @@ public enum SecurityEnum { /** * 存在与header中的token参数头 名 */ - HEADER_TOKEN("accessToken"), USER_CONTEXT("userContext"), JWT_SECRET("secret"), UUID("uuid"); + HEADER_TOKEN("accessToken"), USER_CONTEXT("userContext"), JWT_SECRET("secret"), UUID("uuid"), INVITER("inviter"); String value; diff --git a/framework/src/main/java/cn/lili/modules/connect/serviceimpl/ConnectServiceImpl.java b/framework/src/main/java/cn/lili/modules/connect/serviceimpl/ConnectServiceImpl.java index 942bf897..3b7a9577 100644 --- a/framework/src/main/java/cn/lili/modules/connect/serviceimpl/ConnectServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/connect/serviceimpl/ConnectServiceImpl.java @@ -246,7 +246,17 @@ public class ConnectServiceImpl extends ServiceImpl impl Member newMember = new Member("m" + phone, "111111", phone, params.getNickName(), params.getImage()); memberService.save(newMember); newMember = memberService.findByUsername(newMember.getUsername()); + + //判定有没有邀请人并且写入 + UserContext.settingInviter(newMember.getId(), cache); + bindMpMember(openId, unionId, newMember); + + + //判定有没有邀请人并且写入 + UserContext.settingInviter(newMember.getId(), cache); + + // 发送会员注册信息 applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("new member register", rocketmqCustomProperties.getMemberTopic(), MemberTagsEnum.MEMBER_REGISTER.name(), newMember)); return memberTokenGenerate.createToken(newMember, true); diff --git a/framework/src/main/java/cn/lili/modules/goods/serviceimpl/CategoryServiceImpl.java b/framework/src/main/java/cn/lili/modules/goods/serviceimpl/CategoryServiceImpl.java index c97c2d0d..8410e414 100644 --- a/framework/src/main/java/cn/lili/modules/goods/serviceimpl/CategoryServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/goods/serviceimpl/CategoryServiceImpl.java @@ -241,12 +241,7 @@ public class CategoryServiceImpl extends ServiceImpl i } } UpdateWrapper updateWrapper = new UpdateWrapper<>(); - updateWrapper.eq("id", category.getId()) - .set("name", category.getName()) - .set("image", category.getImage()) - .set("sort_order", category.getSortOrder()) - .set(DELETE_FLAG_COLUMN, category.getDeleteFlag()) - .set("commission_rate", category.getCommissionRate()); + updateWrapper.eq("id", category.getId()); this.baseMapper.update(category, updateWrapper); removeCache(); } diff --git a/framework/src/main/java/cn/lili/modules/member/serviceimpl/MemberServiceImpl.java b/framework/src/main/java/cn/lili/modules/member/serviceimpl/MemberServiceImpl.java index a21b89ad..30585133 100644 --- a/framework/src/main/java/cn/lili/modules/member/serviceimpl/MemberServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/member/serviceimpl/MemberServiceImpl.java @@ -287,6 +287,8 @@ public class MemberServiceImpl extends ServiceImpl impleme member.setId(SnowFlake.getIdStr()); //保存会员 this.save(member); + + // 发送会员注册信息 applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("new member register", rocketmqCustomProperties.getMemberTopic(), MemberTagsEnum.MEMBER_REGISTER.name(), member)); } diff --git a/framework/src/main/java/cn/lili/modules/order/order/entity/dto/PriceDetailDTO.java b/framework/src/main/java/cn/lili/modules/order/order/entity/dto/PriceDetailDTO.java index edf3cfc9..029ead8f 100644 --- a/framework/src/main/java/cn/lili/modules/order/order/entity/dto/PriceDetailDTO.java +++ b/framework/src/main/java/cn/lili/modules/order/order/entity/dto/PriceDetailDTO.java @@ -42,6 +42,9 @@ public class PriceDetailDTO implements Serializable { @ApiModelProperty(value = "优惠金额") private Double discountPrice; + @ApiModelProperty(value = "优惠金额") + private String discountPriceDetail; + @ApiModelProperty(value = "优惠券金额") private Double couponPrice; diff --git a/framework/src/main/java/cn/lili/modules/promotion/entity/dos/CouponActivity.java b/framework/src/main/java/cn/lili/modules/promotion/entity/dos/CouponActivity.java index fdc2615e..96218db3 100644 --- a/framework/src/main/java/cn/lili/modules/promotion/entity/dos/CouponActivity.java +++ b/framework/src/main/java/cn/lili/modules/promotion/entity/dos/CouponActivity.java @@ -26,12 +26,13 @@ public class CouponActivity extends BasePromotions { * @see CouponActivityTypeEnum */ @NotNull(message = "优惠券活动类型不能为空") - @ApiModelProperty(value = "优惠券活动类型", allowableValues = "REGISTERED:新人赠券,SPECIFY:精确发券") + @ApiModelProperty(value = "优惠券活动类型", allowableValues = "REGISTERED:新人赠券,INVITE_NEW:邀新赠券,AUTO_COUPON:自动赠券,SPECIFY:精确发券") private String couponActivityType; /** * @see CouponActivitySendTypeEnum */ + //目前仅在自动赠券模式下该参数会生效,日后如果完善发送测略则调整这里即可 @NotNull(message = "请选择活动范围") @ApiModelProperty(value = "活动范围", allowableValues = "ALL:全部会员,DESIGNATED:指定会员") private String activityScope; diff --git a/framework/src/main/java/cn/lili/modules/promotion/entity/dto/CouponActivityTrigger.java b/framework/src/main/java/cn/lili/modules/promotion/entity/dto/CouponActivityTrigger.java new file mode 100644 index 00000000..b5453457 --- /dev/null +++ b/framework/src/main/java/cn/lili/modules/promotion/entity/dto/CouponActivityTrigger.java @@ -0,0 +1,32 @@ +package cn.lili.modules.promotion.entity.dto; + +import cn.lili.modules.promotion.entity.enums.CouponActivityTypeEnum; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + + +/** + * 优惠券活动触发 + * + * @author paulG + * @since 2020/10/9 + **/ +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class CouponActivityTrigger { + + + @ApiModelProperty(value = "用户ID") + private String userId; + + @ApiModelProperty(value = "用户昵称") + private String nickName; + + @ApiModelProperty(value = "优惠券活动类型") + private CouponActivityTypeEnum couponActivityTypeEnum; +} diff --git a/framework/src/main/java/cn/lili/modules/promotion/entity/enums/CouponActivityTypeEnum.java b/framework/src/main/java/cn/lili/modules/promotion/entity/enums/CouponActivityTypeEnum.java index 15e98c24..1f215b05 100644 --- a/framework/src/main/java/cn/lili/modules/promotion/entity/enums/CouponActivityTypeEnum.java +++ b/framework/src/main/java/cn/lili/modules/promotion/entity/enums/CouponActivityTypeEnum.java @@ -13,7 +13,15 @@ public enum CouponActivityTypeEnum { */ REGISTERED("新人赠券"), /** - * "精确发券" + * "邀新赠券" + */ + INVITE_NEW("邀新赠券"), + /** + * "自动赠券" + */ + AUTO_COUPON("自动赠券"), + /** + * "定向发券" */ SPECIFY("精确发券"); diff --git a/framework/src/main/java/cn/lili/modules/promotion/entity/enums/CouponRangeDayEnum.java b/framework/src/main/java/cn/lili/modules/promotion/entity/enums/CouponRangeDayEnum.java index 0e2a4e93..7de99f7c 100644 --- a/framework/src/main/java/cn/lili/modules/promotion/entity/enums/CouponRangeDayEnum.java +++ b/framework/src/main/java/cn/lili/modules/promotion/entity/enums/CouponRangeDayEnum.java @@ -23,5 +23,14 @@ public enum CouponRangeDayEnum { return description; } + public static boolean exist(String name) { + try { + CouponRangeDayEnum.valueOf(name); + } catch (IllegalArgumentException e) { + return false; + } + return true; + } + } diff --git a/framework/src/main/java/cn/lili/modules/promotion/service/CouponActivityService.java b/framework/src/main/java/cn/lili/modules/promotion/service/CouponActivityService.java index b615dc5e..b9bf6820 100644 --- a/framework/src/main/java/cn/lili/modules/promotion/service/CouponActivityService.java +++ b/framework/src/main/java/cn/lili/modules/promotion/service/CouponActivityService.java @@ -1,7 +1,8 @@ package cn.lili.modules.promotion.service; -import cn.lili.modules.member.entity.dos.Member; import cn.lili.modules.promotion.entity.dos.CouponActivity; +import cn.lili.modules.promotion.entity.dos.MemberCoupon; +import cn.lili.modules.promotion.entity.dto.CouponActivityTrigger; import cn.lili.modules.promotion.entity.vos.CouponActivityVO; import java.util.List; @@ -27,16 +28,15 @@ public interface CouponActivityService extends AbstractPromotionsService couponActivityList, Member member); + List trigger(CouponActivityTrigger couponActivityTrigger); } diff --git a/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/CouponActivityServiceImpl.java b/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/CouponActivityServiceImpl.java index 46021f93..838b4e29 100644 --- a/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/CouponActivityServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/CouponActivityServiceImpl.java @@ -2,9 +2,12 @@ package cn.lili.modules.promotion.serviceimpl; import cn.hutool.json.JSONArray; import cn.hutool.json.JSONUtil; +import cn.lili.cache.Cache; +import cn.lili.cache.CachePrefix; import cn.lili.common.enums.PromotionTypeEnum; import cn.lili.common.enums.ResultCode; import cn.lili.common.exception.ServiceException; +import cn.lili.common.security.AuthUser; import cn.lili.modules.member.entity.dos.Member; import cn.lili.modules.member.service.MemberService; import cn.lili.modules.promotion.entity.dos.Coupon; @@ -12,7 +15,9 @@ import cn.lili.modules.promotion.entity.dos.CouponActivity; import cn.lili.modules.promotion.entity.dos.CouponActivityItem; import cn.lili.modules.promotion.entity.dos.MemberCoupon; import cn.lili.modules.promotion.entity.dto.CouponActivityDTO; +import cn.lili.modules.promotion.entity.dto.CouponActivityTrigger; import cn.lili.modules.promotion.entity.enums.*; +import cn.lili.modules.promotion.entity.vos.CouponActivityItemVO; import cn.lili.modules.promotion.entity.vos.CouponActivityVO; import cn.lili.modules.promotion.mapper.CouponActivityMapper; import cn.lili.modules.promotion.service.CouponActivityItemService; @@ -20,6 +25,7 @@ import cn.lili.modules.promotion.service.CouponActivityService; import cn.lili.modules.promotion.service.CouponService; import cn.lili.modules.promotion.service.MemberCouponService; import cn.lili.modules.promotion.tools.PromotionTools; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import groovy.util.logging.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -47,6 +53,10 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl> cache; + @Override public CouponActivityVO getCouponActivityVO(String couponActivityId) { CouponActivity couponActivity = this.getById(couponActivityId); @@ -55,49 +65,31 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl> member = this.getMemberList(couponActivity); - //会员拆成多个小组进行发送 - List>> memberGroup = new ArrayList<>(); + //如果指定会员发券,则当下直接进行发送,如果是全体会员发券,则变更为用户登录首页进行请求发券 + //PS:即不主动发券,需要用户在活动时间内登录自动领取优惠券,类似美团、饿了么 的发放方式 + if (couponActivity.getActivityScope().equals(CouponActivitySendTypeEnum.DESIGNATED.name())) { + //会员拆成多个小组进行发送 + List>> memberGroup = new ArrayList<>(); - //循环分组 - for (int i = 0; i < (member.size() / 100 + (member.size() % 100 == 0 ? 0 : 1)); i++) { - int endPoint = Math.min((100 + (i * 100)), member.size()); - memberGroup.add(member.subList((i * 100), endPoint)); - } - - //优惠优惠券活动的优惠券列表 - List couponActivityItems = couponActivityItemService.getCouponActivityList(couponActivity.getId()); - //发送优惠券 - for (List> memberList : memberGroup) { - sendCoupon(memberList, couponActivityItems); - } - - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void registered(List couponActivityList, Member member) { - for (CouponActivity couponActivity : couponActivityList) { - //获取会员信息 - List> memberList = new ArrayList<>(); - Map map = new HashMap<>(2); - map.put("id", member.getId()); - map.put("nick_name", member.getNickName()); - memberList.add(map); + //循环分组 + for (int i = 0; i < (member.size() / 100 + (member.size() % 100 == 0 ? 0 : 1)); i++) { + int endPoint = Math.min((100 + (i * 100)), member.size()); + memberGroup.add(member.subList((i * 100), endPoint)); + } //优惠优惠券活动的优惠券列表 List couponActivityItems = couponActivityItemService.getCouponActivityList(couponActivity.getId()); - //发送优惠券 - sendCoupon(memberList, couponActivityItems); + for (List> memberList : memberGroup) { + sendCoupon(memberList, couponActivityItems); + } } - } + } /** * 初始化促销字段 * @@ -146,9 +138,7 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl trigger(CouponActivityTrigger couponActivityTrigger) { + //获取当前正在进行的优惠券活动 + List couponActivities = currentCouponActivity(couponActivityTrigger.getCouponActivityTypeEnum().name()); + + //优惠券发放列表 + List couponActivityItemVOS = new ArrayList<>(); + + //准备发放优惠券活动的列表 + couponActivities.stream().forEach(item -> couponActivityItemVOS.addAll(item.getCouponActivityItems())); + + AuthUser authUser = new AuthUser(); + authUser.setId(couponActivityTrigger.getUserId()); + authUser.setNickName(couponActivityTrigger.getNickName()); + + return this.sendCoupon(authUser, couponActivityItemVOS); + } + + /** * 当前促销类型 * @@ -185,17 +206,108 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl currentCouponActivity() { + return currentCouponActivity(CouponActivityTypeEnum.AUTO_COUPON.name()); + } + + /** + * 当前进行的活动 + * + * @return 当前进行的活动列表 + */ + private List currentCouponActivity(String couponActivityTypeEnum) { + //获取缓存中的活动 + List couponActivityList = cache.get(cacheKey(couponActivityTypeEnum)); + if (couponActivityList == null) { + return ongoingActivities(resetCache(couponActivityTypeEnum)); + } + return ongoingActivities(couponActivityList); + } + + /** + * 从生效的活动优惠券中,过滤出正在进行的活动列表 + * + * @param activityVOS + * @return + */ + private List ongoingActivities(List activityVOS) { + if (activityVOS == null || activityVOS.size() == 0) { + return new ArrayList<>(); + } + return activityVOS.stream().filter(item -> { + return item.getPromotionStatus().equals(PromotionsStatusEnum.START.name()); + }).collect(Collectors.toList()); + } + + /** + * 重写缓存中的活动优惠券信息 + */ + private List resetCache(String couponActivityType) { + + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + + //如果结束时间大于当前时间,则表示有效 + lambdaQueryWrapper.gt(CouponActivity::getEndTime, new Date()); + //发送策略 + lambdaQueryWrapper.eq(CouponActivity::getActivityScope, CouponActivitySendTypeEnum.ALL); + //活动类型 + lambdaQueryWrapper.eq(CouponActivity::getCouponActivityType, couponActivityType); + + //查询出结果,缓存后返回 + List couponActivities = list(lambdaQueryWrapper); + + List couponActivityVOS = new ArrayList<>(); + for (CouponActivity couponActivity : couponActivities) { + couponActivityVOS.add(new CouponActivityVO(couponActivity, couponActivityItemService.getCouponActivityItemListVO(couponActivity.getId()))); + } + + cache.put(cacheKey(couponActivityType), couponActivityVOS); + return couponActivityVOS; + } + + /** + * 定向发送优惠券 * * @param memberList 用户列表 * @param couponActivityItems 优惠券列表 */ - void sendCoupon(List> memberList, List couponActivityItems) { + private void sendCoupon(List> memberList, List couponActivityItems) { + for (Map map : memberList) { + AuthUser authUser = new AuthUser(); + authUser.setId(map.get("id").toString()); + authUser.setNickName(map.get("nick_name").toString()); + + sendCoupon(authUser, couponActivityItems); + + } + } + + /** + * 给当前用户发送优惠券 + * 1.循环优惠券列表 + * 2.判断优惠券每个会员发送数量 + * 3.记录优惠券发送数量 + * + * @param authUser 发送目标用户 + * @param couponActivityItems 优惠券列表 + */ + private List sendCoupon(AuthUser authUser, List couponActivityItems) { + //循环优惠券赠送列表 for (CouponActivityItem couponActivityItem : couponActivityItems) { //获取优惠券 Coupon coupon = couponService.getById(couponActivityItem.getCouponId()); @@ -203,17 +315,15 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl memberCouponList = new LinkedList<>(); //循环优惠券的领取数量 - int j = couponActivityItem.getNum(); - for (int i = 1; i <= j; i++) { - //循环会员列表,添加优惠券 - for (Map map : memberList) { - MemberCoupon memberCoupon = new MemberCoupon(coupon); - memberCoupon.setMemberId(map.get("id").toString()); - memberCoupon.setMemberName(map.get("nick_name").toString()); - memberCoupon.setMemberCouponStatus(MemberCouponStatusEnum.NEW.name()); - memberCoupon.setPlatformFlag(PromotionTools.PLATFORM_ID.equals(coupon.getStoreId())); - memberCouponList.add(memberCoupon); - } + int activitySendNum = couponActivityItem.getNum(); + + for (int i = 1; i <= activitySendNum; i++) { + MemberCoupon memberCoupon = new MemberCoupon(coupon); + memberCoupon.setMemberId(authUser.getId()); + memberCoupon.setMemberName(authUser.getNickName()); + memberCoupon.setMemberCouponStatus(MemberCouponStatusEnum.NEW.name()); + memberCoupon.setPlatformFlag(PromotionTools.PLATFORM_ID.equals(coupon.getStoreId())); + memberCouponList.add(memberCoupon); } //批量添加优惠券 memberCouponService.saveBatch(memberCouponList); @@ -223,6 +333,7 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl(); } @@ -235,16 +346,13 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl> getMemberList(CouponActivity couponActivity) { //判断优惠券的发送范围,获取会员列表 - if ("ALL".equals(couponActivity.getActivityScope())) { - return this.memberService.listFieldsByMemberIds("id,nick_name", null); - } else { - List ids = new ArrayList<>(); - if (JSONUtil.isJsonArray(couponActivity.getActivityScopeInfo())) { - JSONArray array = JSONUtil.parseArray(couponActivity.getActivityScopeInfo()); - ids = array.toList(Map.class).stream().map(i -> i.get("id").toString()).collect(Collectors.toList()); - } - return memberService.listFieldsByMemberIds("id,nick_name", ids); + + List ids = new ArrayList<>(); + if (JSONUtil.isJsonArray(couponActivity.getActivityScopeInfo())) { + JSONArray array = JSONUtil.parseArray(couponActivity.getActivityScopeInfo()); + ids = array.toList(Map.class).stream().map(i -> i.get("id").toString()).collect(Collectors.toList()); } + return memberService.listFieldsByMemberIds("id,nick_name", ids); } /** @@ -263,6 +371,9 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl 2) { + throw new ServiceException(ResultCode.COUPON_ACTIVITY_ITEM_NUM_MAX_VALUE_2); + } } } } diff --git a/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/CouponServiceImpl.java b/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/CouponServiceImpl.java index 6fd34f3a..3f29131a 100644 --- a/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/CouponServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/CouponServiceImpl.java @@ -176,36 +176,52 @@ public class CouponServiceImpl extends AbstractPromotionsServiceImpl promotions.getPublishNum()) { + if (coupon.getPublishNum() != 0 && coupon.getCouponLimitNum() > coupon.getPublishNum()) { throw new ServiceException(ResultCode.COUPON_LIMIT_GREATER_THAN_PUBLISH); } //打折优惠券大于10折 - boolean discountCoupon = (promotions.getCouponType().equals(CouponTypeEnum.DISCOUNT.name()) - && (promotions.getCouponDiscount() < 0 || promotions.getCouponDiscount() > 10)); + boolean discountCoupon = (coupon.getCouponType().equals(CouponTypeEnum.DISCOUNT.name()) + && (coupon.getCouponDiscount() < 0 || coupon.getCouponDiscount() > 10)); if (discountCoupon) { throw new ServiceException(ResultCode.COUPON_DISCOUNT_ERROR); } - //优惠券为固定时间类型 - if (promotions.getRangeDayType() != null && promotions.getRangeDayType().equals(CouponRangeDayEnum.FIXEDTIME.name())) { - long nowTime = DateUtil.getDateline() * 1000; - //固定时间的优惠券不能小于当前时间 - if (promotions.getEndTime().getTime() < nowTime) { - throw new ServiceException(ResultCode.PROMOTION_END_TIME_ERROR); - } + //如果优惠券使用时间类型不合法,抛出异常,抛出异常 + if (CouponRangeDayEnum.exist(coupon.getRangeDayType())) { + throw new ServiceException(ResultCode.COUPON_RANGE_ERROR); + } + + switch (CouponRangeDayEnum.valueOf(coupon.getRangeDayType())) { + case FIXEDTIME: + //如果优惠券为固定时间,则开始结束时间不能为空 + if (coupon.getEndTime() == null || coupon.getStartTime() == null) { + throw new ServiceException(ResultCode.PROMOTION_TIME_ERROR); + } + long nowTime = DateUtil.getDateline() * 1000; + //固定时间的优惠券不能小于当前时间 + if (coupon.getEndTime().getTime() < nowTime) { + throw new ServiceException(ResultCode.PROMOTION_END_TIME_ERROR); + } + break; + case DYNAMICTIME: + //固定时间的优惠券不能小于当前时间 + if (coupon.getEffectiveDays() == null || coupon.getEffectiveDays() < 0) { + throw new ServiceException(ResultCode.PROMOTION_END_TIME_ERROR); + } + break; } - this.checkCouponScope((CouponVO) promotions); + this.checkCouponScope((CouponVO) coupon); } @Override diff --git a/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/MemberCouponServiceImpl.java b/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/MemberCouponServiceImpl.java index 415f45fa..6124b259 100644 --- a/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/MemberCouponServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/MemberCouponServiceImpl.java @@ -111,9 +111,11 @@ public class MemberCouponServiceImpl extends ServiceImpl getMemberCoupons(MemberCouponSearchParams param, PageVO pageVo) { QueryWrapper queryWrapper = param.queryWrapper(); Page page = this.page(PageUtil.initPage(pageVo), queryWrapper); - if (page.getRecords().stream().anyMatch(i -> i.getEndTime().before(new Date()))) { - this.expireInvalidMemberCoupon(param.getMemberId()); - return this.page(PageUtil.initPage(pageVo), queryWrapper); + if (page.getRecords() != null && page.getRecords().size() > 0) { + if (page.getRecords().stream().anyMatch(i -> i.getEndTime().before(new Date()))) { + this.expireInvalidMemberCoupon(param.getMemberId()); + return this.page(PageUtil.initPage(pageVo), queryWrapper); + } } return page; } diff --git a/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/SeckillServiceImpl.java b/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/SeckillServiceImpl.java index e0688b7b..14a386f7 100644 --- a/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/SeckillServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/SeckillServiceImpl.java @@ -40,6 +40,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.Arrays; +import java.util.Date; import java.util.List; import java.util.Map; @@ -134,10 +135,10 @@ public class SeckillServiceImpl extends AbstractPromotionsServiceImpl>>>>>> origin/master + * <<<<<<< HEAD + * ======= + * <<<<<<< HEAD + * >>>>>>> origin/master * 通用促销更新 * 调用顺序: * 1. checkStatus 检查促销状态 @@ -154,11 +155,16 @@ public class SeckillServiceImpl extends AbstractPromotionsServiceImpl> getCouponActivityPage(PageVO page) { - return ResultUtil.data(couponActivityService.page(PageUtil.initPage(page))); + public ResultMessage> getCouponActivityPage(PageVO page, CouponActivity couponActivity) { + return ResultUtil.data(couponActivityService.page(PageUtil.initPage(page), PageUtil.initWrapper(couponActivity))); } @ApiOperation(value = "获取优惠券活动") @@ -52,7 +52,7 @@ public class CouponActivityManagerController { @PostMapping public ResultMessage addCouponActivity(@RequestBody(required = false) CouponActivityDTO couponActivityDTO) { for (CouponActivityItem couponActivityItem : couponActivityDTO.getCouponActivityItems()) { - if (couponActivityItem.getNum() > 3) { + if (couponActivityItem.getNum() > 5) { throw new ServiceException(ResultCode.COUPON_ACTIVITY_MAX_NUM); } } @@ -63,9 +63,7 @@ public class CouponActivityManagerController { } @ApiOperation(value = "关闭优惠券活动") - @ApiImplicitParams({ - @ApiImplicitParam(name = "id", value = "优惠券活动ID", required = true, dataType = "String", paramType = "path") - }) + @ApiImplicitParams({@ApiImplicitParam(name = "id", value = "优惠券活动ID", required = true, dataType = "String", paramType = "path")}) @DeleteMapping("/{id}") public ResultMessage updateStatus(@PathVariable String id) { if (couponActivityService.updateStatus(Collections.singletonList(id), null, null)) {