'优惠券功能改版'

This commit is contained in:
Chopper711 2022-12-23 14:51:06 +08:00
parent 602678e2b9
commit 8543a228fd
21 changed files with 387 additions and 124 deletions

View File

@ -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<List<MemberCoupon>> 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<IPage<CouponVO>> getCouponList(CouponSearchParams queryParam, PageVO page) {

View File

@ -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<CouponActivity> couponActivities = couponActivityService.list(new QueryWrapper<CouponActivity>()
.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());
}
}
}

View File

@ -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) {

View File

@ -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"),
/**
* 其他促销

View File

@ -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 {

View File

@ -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);
}
}
}
}

View File

@ -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;

View File

@ -246,7 +246,17 @@ public class ConnectServiceImpl extends ServiceImpl<ConnectMapper, Connect> 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);

View File

@ -241,12 +241,7 @@ public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> i
}
}
UpdateWrapper<Category> 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();
}

View File

@ -287,6 +287,8 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> impleme
member.setId(SnowFlake.getIdStr());
//保存会员
this.save(member);
// 发送会员注册信息
applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("new member register", rocketmqCustomProperties.getMemberTopic(), MemberTagsEnum.MEMBER_REGISTER.name(), member));
}

View File

@ -42,6 +42,9 @@ public class PriceDetailDTO implements Serializable {
@ApiModelProperty(value = "优惠金额")
private Double discountPrice;
@ApiModelProperty(value = "优惠金额")
private String discountPriceDetail;
@ApiModelProperty(value = "优惠券金额")
private Double couponPrice;

View File

@ -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;

View File

@ -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;
}

View File

@ -13,7 +13,15 @@ public enum CouponActivityTypeEnum {
*/
REGISTERED("新人赠券"),
/**
* "精确发券"
* "邀新赠券"
*/
INVITE_NEW("邀新赠券"),
/**
* "自动赠券"
*/
AUTO_COUPON("自动赠券"),
/**
* "定向发券"
*/
SPECIFY("精确发券");

View File

@ -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;
}
}

View File

@ -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<CouponA
/**
* 精准发券
*
* @param couponActivityId 优惠券活动ID
* @param couponActivity 精准发券
*/
void specify(String couponActivityId);
void specify(CouponActivity couponActivity);
/**
* 注册赠券
* 用户优惠券活动触发
*
* @param couponActivityList 优惠券活动
* @param member 会员
* @return 优惠券列表
*/
void registered(List<CouponActivity> couponActivityList, Member member);
List<MemberCoupon> trigger(CouponActivityTrigger couponActivityTrigger);
}

View File

@ -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<Cou
@Autowired
private MemberService memberService;
@Autowired
private Cache<List<CouponActivityVO>> cache;
@Override
public CouponActivityVO getCouponActivityVO(String couponActivityId) {
CouponActivity couponActivity = this.getById(couponActivityId);
@ -55,12 +65,13 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl<Cou
@Override
@Transactional(rollbackFor = Exception.class)
public void specify(String couponActivityId) {
//获取优惠券
CouponActivity couponActivity = this.getById(couponActivityId);
public void specify(CouponActivity couponActivity) {
//获取活动优惠券发送范围
List<Map<String, Object>> member = this.getMemberList(couponActivity);
//如果指定会员发券则当下直接进行发送如果是全体会员发券则变更为用户登录首页进行请求发券
//PS:即不主动发券需要用户在活动时间内登录自动领取优惠券类似美团饿了么 的发放方式
if (couponActivity.getActivityScope().equals(CouponActivitySendTypeEnum.DESIGNATED.name())) {
//会员拆成多个小组进行发送
List<List<Map<String, Object>>> memberGroup = new ArrayList<>();
@ -76,28 +87,9 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl<Cou
for (List<Map<String, Object>> memberList : memberGroup) {
sendCoupon(memberList, couponActivityItems);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void registered(List<CouponActivity> couponActivityList, Member member) {
for (CouponActivity couponActivity : couponActivityList) {
//获取会员信息
List<Map<String, Object>> memberList = new ArrayList<>();
Map<String, Object> map = new HashMap<>(2);
map.put("id", member.getId());
map.put("nick_name", member.getNickName());
memberList.add(map);
//优惠优惠券活动的优惠券列表
List<CouponActivityItem> couponActivityItems = couponActivityItemService.getCouponActivityList(couponActivity.getId());
//发送优惠券
sendCoupon(memberList, couponActivityItems);
}
}
/**
* 初始化促销字段
*
@ -146,9 +138,7 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl<Cou
@Transactional(rollbackFor = {Exception.class})
public boolean updatePromotionsGoods(CouponActivity couponActivity) {
boolean result = super.updatePromotionsGoods(couponActivity);
if (couponActivity instanceof CouponActivityDTO
&& !PromotionsStatusEnum.CLOSE.name().equals(couponActivity.getPromotionStatus())
&& PromotionsScopeTypeEnum.PORTION_GOODS.name().equals(couponActivity.getScopeType())) {
if (couponActivity instanceof CouponActivityDTO && !PromotionsStatusEnum.CLOSE.name().equals(couponActivity.getPromotionStatus()) && PromotionsScopeTypeEnum.PORTION_GOODS.name().equals(couponActivity.getScopeType())) {
CouponActivityDTO couponActivityDTO = (CouponActivityDTO) couponActivity;
//创建优惠券活动子列表
for (CouponActivityItem couponActivityItem : couponActivityDTO.getCouponActivityItems()) {
@ -168,12 +158,43 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl<Cou
@Override
@Transactional(rollbackFor = Exception.class)
public void updateEsGoodsIndex(CouponActivity couponActivity) {
//如果是精准发券进行发送优惠券
if (!PromotionsStatusEnum.CLOSE.name().equals(couponActivity.getPromotionStatus()) && couponActivity.getCouponActivityType().equals(CouponActivityTypeEnum.SPECIFY.name())) {
this.specify(couponActivity.getId());
switch (CouponActivityTypeEnum.valueOf(couponActivity.getCouponActivityType())) {
// 精准发券 则立即发放
case SPECIFY:
this.specify(couponActivity);
break;
//其他活动则是缓存模块根据缓存中的优惠券活动信息来确认发放优惠券测略
case INVITE_NEW:
case AUTO_COUPON:
case REGISTERED:
this.resetCache(couponActivity.getCouponActivityType());
break;
}
}
@Override
public List<MemberCoupon> trigger(CouponActivityTrigger couponActivityTrigger) {
//获取当前正在进行的优惠券活动
List<CouponActivityVO> couponActivities = currentCouponActivity(couponActivityTrigger.getCouponActivityTypeEnum().name());
//优惠券发放列表
List<CouponActivityItemVO> 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<Cou
}
/**
* 发送优惠券
* 1.循环优惠券列表
* 2.判断优惠券每个会员发送数量
* 3.循环会员列表发送优惠券
* 4.记录优惠券发送数量
* 缓存key生成策略
*
* @param couponActivityType 优惠券活动类型
* @return 缓存key
*/
private String cacheKey(String couponActivityType) {
return CachePrefix.CURRENT_COUPON_ACTIVITY.getPrefix() + couponActivityType;
}
/**
* 当前进行的活动
*
* @return 当前进行的活动列表
*/
private List<CouponActivityVO> currentCouponActivity() {
return currentCouponActivity(CouponActivityTypeEnum.AUTO_COUPON.name());
}
/**
* 当前进行的活动
*
* @return 当前进行的活动列表
*/
private List<CouponActivityVO> currentCouponActivity(String couponActivityTypeEnum) {
//获取缓存中的活动
List<CouponActivityVO> couponActivityList = cache.get(cacheKey(couponActivityTypeEnum));
if (couponActivityList == null) {
return ongoingActivities(resetCache(couponActivityTypeEnum));
}
return ongoingActivities(couponActivityList);
}
/**
* 从生效的活动优惠券中过滤出正在进行的活动列表
*
* @param activityVOS
* @return
*/
private List<CouponActivityVO> ongoingActivities(List<CouponActivityVO> 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<CouponActivityVO> resetCache(String couponActivityType) {
LambdaQueryWrapper<CouponActivity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//如果结束时间大于当前时间则表示有效
lambdaQueryWrapper.gt(CouponActivity::getEndTime, new Date());
//发送策略
lambdaQueryWrapper.eq(CouponActivity::getActivityScope, CouponActivitySendTypeEnum.ALL);
//活动类型
lambdaQueryWrapper.eq(CouponActivity::getCouponActivityType, couponActivityType);
//查询出结果缓存后返回
List<CouponActivity> couponActivities = list(lambdaQueryWrapper);
List<CouponActivityVO> 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<Map<String, Object>> memberList, List<CouponActivityItem> couponActivityItems) {
private void sendCoupon(List<Map<String, Object>> memberList, List<CouponActivityItem> couponActivityItems) {
for (Map<String, Object> 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<MemberCoupon> sendCoupon(AuthUser authUser, List<? extends CouponActivityItem> couponActivityItems) {
//循环优惠券赠送列表
for (CouponActivityItem couponActivityItem : couponActivityItems) {
//获取优惠券
Coupon coupon = couponService.getById(couponActivityItem.getCouponId());
@ -203,18 +315,16 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl<Cou
if (coupon != null) {
List<MemberCoupon> memberCouponList = new LinkedList<>();
//循环优惠券的领取数量
int j = couponActivityItem.getNum();
for (int i = 1; i <= j; i++) {
//循环会员列表添加优惠券
for (Map<String, Object> map : memberList) {
int activitySendNum = couponActivityItem.getNum();
for (int i = 1; i <= activitySendNum; i++) {
MemberCoupon memberCoupon = new MemberCoupon(coupon);
memberCoupon.setMemberId(map.get("id").toString());
memberCoupon.setMemberName(map.get("nick_name").toString());
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<Cou
log.error("赠送优惠券失败,当前优惠券不存在:" + couponActivityItem.getCouponId());
}
}
return new ArrayList<>();
}
@ -235,9 +346,7 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl<Cou
*/
private List<Map<String, Object>> getMemberList(CouponActivity couponActivity) {
//判断优惠券的发送范围获取会员列表
if ("ALL".equals(couponActivity.getActivityScope())) {
return this.memberService.listFieldsByMemberIds("id,nick_name", null);
} else {
List<String> ids = new ArrayList<>();
if (JSONUtil.isJsonArray(couponActivity.getActivityScopeInfo())) {
JSONArray array = JSONUtil.parseArray(couponActivity.getActivityScopeInfo());
@ -245,7 +354,6 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl<Cou
}
return memberService.listFieldsByMemberIds("id,nick_name", ids);
}
}
/**
* 检查优惠券
@ -263,6 +371,9 @@ public class CouponActivityServiceImpl extends AbstractPromotionsServiceImpl<Cou
if (item.getNum() == null || item.getNum() <= 0) {
throw new ServiceException(ResultCode.COUPON_ACTIVITY_ITEM_NUM_ERROR);
}
if (item.getNum() > 2) {
throw new ServiceException(ResultCode.COUPON_ACTIVITY_ITEM_NUM_MAX_VALUE_2);
}
}
}
}

View File

@ -176,36 +176,52 @@ public class CouponServiceImpl extends AbstractPromotionsServiceImpl<CouponMappe
}
@Override
public void checkPromotions(Coupon promotions) {
if (promotions.getRangeDayType() == null) {
super.checkPromotions(promotions);
public void checkPromotions(Coupon coupon) {
if (coupon.getRangeDayType() == null) {
super.checkPromotions(coupon);
}
//优惠券限制领取数量
if (promotions.getCouponLimitNum() < 0) {
if (coupon.getCouponLimitNum() < 0) {
throw new ServiceException(ResultCode.COUPON_LIMIT_NUM_LESS_THAN_0);
}
//如果发行数量是0则判断领取限制数量
if (promotions.getPublishNum() != 0 && promotions.getCouponLimitNum() > 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())) {
//如果优惠券使用时间类型不合法抛出异常抛出异常
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 (promotions.getEndTime().getTime() < nowTime) {
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

View File

@ -111,10 +111,12 @@ public class MemberCouponServiceImpl extends ServiceImpl<MemberCouponMapper, Mem
public IPage<MemberCoupon> getMemberCoupons(MemberCouponSearchParams param, PageVO pageVo) {
QueryWrapper<MemberCoupon> queryWrapper = param.queryWrapper();
Page<MemberCoupon> page = 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;
}

View File

@ -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<SeckillMap
}
/**
<<<<<<< HEAD
=======
<<<<<<< HEAD
>>>>>>> origin/master
* <<<<<<< HEAD
* =======
* <<<<<<< HEAD
* >>>>>>> origin/master
* 通用促销更新
* 调用顺序:
* 1. checkStatus 检查促销状态
@ -154,11 +155,16 @@ public class SeckillServiceImpl extends AbstractPromotionsServiceImpl<SeckillMap
public boolean updatePromotions(Seckill promotions) {
this.checkStatus(promotions);
this.checkPromotions(promotions);
//如果申请结束时间在当前时间之前
if (promotions.getApplyEndTime().before(new Date()) || promotions.getApplyEndTime().after(promotions.getStartTime())) {
throw new ServiceException(ResultCode.STORE_NAME_EXIST_ERROR);
}
boolean result = this.updateById(promotions);
seckillApplyService.updateSeckillApplyTime(promotions);
return result;
}
/**
* 更新商品索引限时抢购信息
*

View File

@ -37,8 +37,8 @@ public class CouponActivityManagerController {
@ApiOperation(value = "获取优惠券活动分页")
@GetMapping
public ResultMessage<IPage<CouponActivity>> getCouponActivityPage(PageVO page) {
return ResultUtil.data(couponActivityService.page(PageUtil.initPage(page)));
public ResultMessage<IPage<CouponActivity>> 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<CouponActivity> 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<CouponActivity> updateStatus(@PathVariable String id) {
if (couponActivityService.updateStatus(Collections.singletonList(id), null, null)) {