合并代码
This commit is contained in:
@@ -144,6 +144,10 @@ public class PlayCouponInfoController {
|
|||||||
}
|
}
|
||||||
entity.setDiscountContent(discountContent);
|
entity.setDiscountContent(discountContent);
|
||||||
entity.setCouponOnLineState("1");
|
entity.setCouponOnLineState("1");
|
||||||
|
// 领取白名单校验:当为2时必须配置白名单
|
||||||
|
if ("2".equals(vo.getClaimConditionType()) && (vo.getCustomWhitelist() == null || vo.getCustomWhitelist().isEmpty())) {
|
||||||
|
throw new CustomException("领取条件为白名单时,必须设置领取白名单");
|
||||||
|
}
|
||||||
boolean success = playCouponInfoService.create(entity);
|
boolean success = playCouponInfoService.create(entity);
|
||||||
if (success) {
|
if (success) {
|
||||||
return R.ok();
|
return R.ok();
|
||||||
|
|||||||
@@ -118,10 +118,16 @@ public class PlayCouponInfoEntity extends BaseEntity<PlayCouponInfoEntity> {
|
|||||||
private Integer clerkObtainedMaxQuantity;
|
private Integer clerkObtainedMaxQuantity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 领取条件类型(0:所有人可领取,1:指定条件领取)
|
* 领取条件类型:0=所有人可领取;1=按条件领取;2=仅白名单可领取。
|
||||||
*/
|
*/
|
||||||
private String claimConditionType;
|
private String claimConditionType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 领取白名单(claimConditionType=2 生效)。JSON存储用户ID列表。
|
||||||
|
*/
|
||||||
|
@TableField(typeHandler = StringTypeHandler.class)
|
||||||
|
private List<String> customWhitelist;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 顾客等级选择状态(0:未选择,1:选择)
|
* 顾客等级选择状态(0:未选择,1:选择)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.starry.admin.modules.shop.module.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠券领取条件类型
|
||||||
|
*/
|
||||||
|
public enum CouponClaimConditionType {
|
||||||
|
ALL("0"),
|
||||||
|
FILTER("1"),
|
||||||
|
WHITELIST("2");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
|
||||||
|
CouponClaimConditionType(String code) {
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String code() { return code; }
|
||||||
|
|
||||||
|
public static CouponClaimConditionType of(String code) {
|
||||||
|
for (CouponClaimConditionType t : values()) {
|
||||||
|
if (t.code.equals(code)) return t;
|
||||||
|
}
|
||||||
|
return ALL;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -120,12 +120,17 @@ public class PlayCouponInfoAddVo {
|
|||||||
private Integer clerkObtainedMaxQuantity;
|
private Integer clerkObtainedMaxQuantity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 领取条件类型(0:所有人可领取,1:指定条件领取)
|
* 领取条件类型:0=所有人;1=按条件;2=白名单。
|
||||||
*/
|
*/
|
||||||
@NotNull(message = "领取条件类型不能为空")
|
@NotNull(message = "领取条件类型不能为空")
|
||||||
@Pattern(regexp = "[0|1]", message = "店员范围只能为0或者1")
|
@Pattern(regexp = "^(0|1|2)$", message = "领取条件类型只能为0或1或2")
|
||||||
private String claimConditionType;
|
private String claimConditionType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 领取白名单(claimConditionType=2 时校验):用户ID列表
|
||||||
|
*/
|
||||||
|
private List<String> customWhitelist;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 顾客等级选择状态(0:未选择,1:选择)
|
* 顾客等级选择状态(0:未选择,1:选择)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -109,10 +109,16 @@ public class PlayCouponInfoReturnVo {
|
|||||||
private Integer clerkObtainedMaxQuantity;
|
private Integer clerkObtainedMaxQuantity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 领取条件类型(0:所有人可领取,1:指定条件领取)
|
* 领取条件类型:0=所有人;1=按条件;2=白名单。
|
||||||
*/
|
*/
|
||||||
private String claimConditionType;
|
private String claimConditionType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 领取白名单(claimConditionType=2 生效)
|
||||||
|
*/
|
||||||
|
@TableField(typeHandler = StringTypeHandler.class)
|
||||||
|
private List<String> customWhitelist;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 顾客等级选择状态(0:未选择,1:选择)
|
* 顾客等级选择状态(0:未选择,1:选择)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import com.starry.admin.common.exception.CustomException;
|
|||||||
import com.starry.admin.modules.custom.module.entity.PlayCustomUserInfoEntity;
|
import com.starry.admin.modules.custom.module.entity.PlayCustomUserInfoEntity;
|
||||||
import com.starry.admin.modules.shop.mapper.PlayCouponInfoMapper;
|
import com.starry.admin.modules.shop.mapper.PlayCouponInfoMapper;
|
||||||
import com.starry.admin.modules.shop.module.entity.PlayCouponInfoEntity;
|
import com.starry.admin.modules.shop.module.entity.PlayCouponInfoEntity;
|
||||||
|
import com.starry.admin.modules.shop.module.enums.CouponClaimConditionType;
|
||||||
import com.starry.admin.modules.shop.module.vo.PlayCouponInfoQueryVo;
|
import com.starry.admin.modules.shop.module.vo.PlayCouponInfoQueryVo;
|
||||||
import com.starry.admin.modules.shop.module.vo.PlayCouponInfoReturnVo;
|
import com.starry.admin.modules.shop.module.vo.PlayCouponInfoReturnVo;
|
||||||
import com.starry.admin.modules.shop.service.IPlayCouponInfoService;
|
import com.starry.admin.modules.shop.service.IPlayCouponInfoService;
|
||||||
@@ -84,26 +85,32 @@ public class PlayCouponInfoServiceImpl extends ServiceImpl<PlayCouponInfoMapper,
|
|||||||
@Override
|
@Override
|
||||||
public String getReasonForNotObtainingCoupons(PlayCouponInfoEntity entity,
|
public String getReasonForNotObtainingCoupons(PlayCouponInfoEntity entity,
|
||||||
PlayCustomUserInfoEntity customUserInfo) {
|
PlayCustomUserInfoEntity customUserInfo) {
|
||||||
// 优惠券是否设置指定条件领取
|
CouponClaimConditionType type = CouponClaimConditionType.of(entity.getClaimConditionType());
|
||||||
if ("0".equals(entity.getClaimConditionType())) {
|
switch (type) {
|
||||||
return "";
|
case ALL:
|
||||||
|
return "";
|
||||||
|
case WHITELIST:
|
||||||
|
if (entity.getCustomWhitelist() == null || entity.getCustomWhitelist().isEmpty()) {
|
||||||
|
return "未配置白名单";
|
||||||
|
}
|
||||||
|
return entity.getCustomWhitelist().contains(customUserInfo.getId()) ? "" : "非指定用户";
|
||||||
|
case FILTER:
|
||||||
|
default:
|
||||||
|
// 顾客等级判断
|
||||||
|
String msg = reasonForNotObtainingCoupons(entity.getCustomLevelCheckType(), entity.getCustomLevel(),
|
||||||
|
customUserInfo.getLevelId(), "0");
|
||||||
|
if (StrUtil.isNotEmpty(msg)) {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
// 顾客性别判断
|
||||||
|
msg = reasonForNotObtainingCoupons(entity.getCustomSexCheckType(), entity.getCustomSex(),
|
||||||
|
String.valueOf(customUserInfo.getSex()), "1");
|
||||||
|
if (StrUtil.isNotEmpty(msg)) {
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
// TODO: 关注状态、新用户等其他条件可在此扩展
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
// 顾客等级判断
|
|
||||||
String msg = reasonForNotObtainingCoupons(entity.getCustomLevelCheckType(), entity.getCustomLevel(),
|
|
||||||
customUserInfo.getLevelId(), "0");
|
|
||||||
if (StrUtil.isNotEmpty(msg)) {
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
// 顾客性别判断
|
|
||||||
msg = reasonForNotObtainingCoupons(entity.getCustomSexCheckType(), entity.getCustomSex(),
|
|
||||||
customUserInfo.getSex().toString(), "`1");
|
|
||||||
if (StrUtil.isNotEmpty(msg)) {
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
// 顾客关注公众号状态判断
|
|
||||||
|
|
||||||
// 顾客是否是新用户判断
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import com.starry.admin.modules.clerk.module.entity.PlayClerkUserInfoEntity;
|
|||||||
import com.starry.admin.modules.clerk.service.IPlayClerkUserInfoService;
|
import com.starry.admin.modules.clerk.service.IPlayClerkUserInfoService;
|
||||||
import com.starry.admin.modules.custom.module.entity.PlayCustomUserInfoEntity;
|
import com.starry.admin.modules.custom.module.entity.PlayCustomUserInfoEntity;
|
||||||
import com.starry.admin.modules.shop.module.entity.PlayCouponInfoEntity;
|
import com.starry.admin.modules.shop.module.entity.PlayCouponInfoEntity;
|
||||||
|
import com.starry.admin.modules.shop.module.enums.CouponClaimConditionType;
|
||||||
import com.starry.admin.modules.shop.module.vo.PlayCommodityInfoVo;
|
import com.starry.admin.modules.shop.module.vo.PlayCommodityInfoVo;
|
||||||
import com.starry.admin.modules.shop.module.vo.PlayCouponDetailsReturnVo;
|
import com.starry.admin.modules.shop.module.vo.PlayCouponDetailsReturnVo;
|
||||||
import com.starry.admin.modules.shop.service.IPlayCommodityInfoService;
|
import com.starry.admin.modules.shop.service.IPlayCommodityInfoService;
|
||||||
@@ -94,14 +95,22 @@ public class WxCouponController {
|
|||||||
@CustomUserLogin
|
@CustomUserLogin
|
||||||
@PostMapping("/custom/queryAll")
|
@PostMapping("/custom/queryAll")
|
||||||
public R queryAll() {
|
public R queryAll() {
|
||||||
|
String currentCustomId = ThreadLocalRequestDetail.getCustomUserInfo().getId();
|
||||||
List<PlayCouponDetailsReturnVo> obtainedCoupons = couponDetailsService
|
List<PlayCouponDetailsReturnVo> obtainedCoupons = couponDetailsService
|
||||||
.selectByCustomId(ThreadLocalRequestDetail.getCustomUserInfo().getId());
|
.selectByCustomId(currentCustomId);
|
||||||
List<PlayCouponInfoEntity> couponInfoEntities = couponInfoService.queryAll();
|
List<PlayCouponInfoEntity> couponInfoEntities = couponInfoService.queryAll();
|
||||||
List<WxCouponReceiveReturnVo> returnVos = new ArrayList<>(couponInfoEntities.size());
|
List<WxCouponReceiveReturnVo> returnVos = new ArrayList<>(couponInfoEntities.size());
|
||||||
for (PlayCouponInfoEntity couponInfoEntity : couponInfoEntities) {
|
for (PlayCouponInfoEntity couponInfoEntity : couponInfoEntities) {
|
||||||
if ("0".equals(couponInfoEntity.getCouponOnLineState())) {
|
if ("0".equals(couponInfoEntity.getCouponOnLineState())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// 领取白名单:非白名单用户不可见
|
||||||
|
if (CouponClaimConditionType.WHITELIST.code().equals(couponInfoEntity.getClaimConditionType())) {
|
||||||
|
List<String> wl = couponInfoEntity.getCustomWhitelist();
|
||||||
|
if (wl == null || !wl.contains(currentCustomId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
WxCouponReceiveReturnVo vo = ConvertUtil.entityToVo(couponInfoEntity, WxCouponReceiveReturnVo.class);
|
WxCouponReceiveReturnVo vo = ConvertUtil.entityToVo(couponInfoEntity, WxCouponReceiveReturnVo.class);
|
||||||
for (PlayCouponDetailsReturnVo obtainedCoupon : obtainedCoupons) {
|
for (PlayCouponDetailsReturnVo obtainedCoupon : obtainedCoupons) {
|
||||||
if (obtainedCoupon.getCouponId().equals(couponInfoEntity.getId())) {
|
if (obtainedCoupon.getCouponId().equals(couponInfoEntity.getId())) {
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
-- Add whitelist for coupon self-claim restriction (specific users only)
|
||||||
|
-- MySQL dialect
|
||||||
|
ALTER TABLE `play_coupon_info`
|
||||||
|
ADD COLUMN `custom_whitelist` TEXT NULL COMMENT '领取白名单用户ID(JSON)';
|
||||||
|
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
package com.starry.admin.modules.shop.service;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
import com.starry.admin.common.conf.ThreadLocalRequestDetail;
|
||||||
|
import com.starry.admin.modules.custom.module.entity.PlayCustomUserInfoEntity;
|
||||||
|
import com.starry.admin.modules.shop.module.entity.PlayCouponInfoEntity;
|
||||||
|
import com.starry.admin.modules.shop.service.IPlayCommodityInfoService;
|
||||||
|
import com.starry.admin.modules.shop.service.IPlayCouponDetailsService;
|
||||||
|
import com.starry.admin.modules.shop.service.IPlayCouponInfoService;
|
||||||
|
import com.starry.admin.modules.shop.service.impl.PlayCouponInfoServiceImpl;
|
||||||
|
import com.starry.admin.modules.weichat.controller.WxCouponController;
|
||||||
|
import com.starry.admin.modules.weichat.entity.WxCouponReceiveReturnVo;
|
||||||
|
import com.starry.common.result.R;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
public class CouponWhitelistTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("领取校验-白名单:白名单用户可领,非白名单被拒")
|
||||||
|
void testWhitelistCheckInService() {
|
||||||
|
PlayCouponInfoServiceImpl service = new PlayCouponInfoServiceImpl();
|
||||||
|
|
||||||
|
PlayCouponInfoEntity coupon = new PlayCouponInfoEntity();
|
||||||
|
coupon.setClaimConditionType("2");
|
||||||
|
coupon.setCustomWhitelist(Arrays.asList("userA", "userB"));
|
||||||
|
|
||||||
|
PlayCustomUserInfoEntity userA = new PlayCustomUserInfoEntity();
|
||||||
|
userA.setId("userA");
|
||||||
|
|
||||||
|
PlayCustomUserInfoEntity userX = new PlayCustomUserInfoEntity();
|
||||||
|
userX.setId("userX");
|
||||||
|
|
||||||
|
String ok = service.getReasonForNotObtainingCoupons(coupon, userA);
|
||||||
|
String deny = service.getReasonForNotObtainingCoupons(coupon, userX);
|
||||||
|
|
||||||
|
assertEquals("", ok, "白名单用户应允许领取");
|
||||||
|
assertEquals("非指定用户", deny, "非白名单用户应被拒绝");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private IPlayCouponDetailsService couponDetailsService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private IPlayCouponInfoService couponInfoService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private IPlayCommodityInfoService commodityInfoService;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private WxCouponController wxCouponController;
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void clearTL() { ThreadLocalRequestDetail.remove(); }
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("列表过滤-白名单:非白名单用户不可见")
|
||||||
|
void testWhitelistHiddenInQueryAll() {
|
||||||
|
// 当前用户
|
||||||
|
PlayCustomUserInfoEntity current = new PlayCustomUserInfoEntity();
|
||||||
|
current.setId("uid-1");
|
||||||
|
ThreadLocalRequestDetail.setRequestDetail(current);
|
||||||
|
|
||||||
|
// 构造两张券:一张白名单包含uid-1,一张不包含
|
||||||
|
PlayCouponInfoEntity visible = new PlayCouponInfoEntity();
|
||||||
|
visible.setId("c1");
|
||||||
|
visible.setCouponOnLineState("1");
|
||||||
|
visible.setClaimConditionType("2");
|
||||||
|
visible.setCustomWhitelist(Collections.singletonList("uid-1"));
|
||||||
|
|
||||||
|
PlayCouponInfoEntity hidden = new PlayCouponInfoEntity();
|
||||||
|
hidden.setId("c2");
|
||||||
|
hidden.setCouponOnLineState("1");
|
||||||
|
hidden.setClaimConditionType("2");
|
||||||
|
hidden.setCustomWhitelist(Collections.singletonList("other"));
|
||||||
|
|
||||||
|
when(couponDetailsService.selectByCustomId("uid-1")).thenReturn(new ArrayList<>());
|
||||||
|
when(couponInfoService.queryAll()).thenReturn(Arrays.asList(visible, hidden));
|
||||||
|
|
||||||
|
R resp = wxCouponController.queryAll();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<WxCouponReceiveReturnVo> list = (List<WxCouponReceiveReturnVo>) resp.getData();
|
||||||
|
|
||||||
|
assertNotNull(list);
|
||||||
|
assertEquals(1, list.size(), "非白名单券应被过滤不可见");
|
||||||
|
assertEquals("c1", list.get(0).getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user