code review:积分、优惠劵、佣金等逻辑

This commit is contained in:
YunaiV 2023-10-01 23:31:07 +08:00
parent 057952bdeb
commit d4417d2474
27 changed files with 47 additions and 74 deletions

View File

@ -1,11 +0,0 @@
-- 查询上级菜单排序
SELECT parent_id, sort
INTO @parentId, @sort
FROM system_menu
WHERE name = '用户等级修改'
LIMIT 1;
-- 新增 按钮权限
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('用户积分修改', 'member:user:update-point', 3, @sort + 1, @parentId, '', '', '', 0);
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('用户余额修改', 'member:user:update-balance', 3, @sort + 2, @parentId, '', '', '', 0);

View File

@ -1,3 +0,0 @@
-- 增加字段
ALTER TABLE trade_order
ADD COLUMN brokerage_user_id bigint NULL COMMENT '推广人编号' AFTER comment_status;

View File

@ -146,9 +146,7 @@ public class LocalDateTimeUtils {
* @return 月份的开始时间
*/
public static LocalDateTime beginOfMonth(LocalDateTime date) {
return date
.with(TemporalAdjusters.firstDayOfMonth())
.with(LocalTime.MIN);
return date.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
}
/**
@ -159,8 +157,7 @@ public class LocalDateTimeUtils {
* @return 月份的结束时间
*/
public static LocalDateTime endOfMonth(LocalDateTime date) {
return date
.with(TemporalAdjusters.lastDayOfMonth())
.with(LocalTime.MAX);
return date.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
}
}

View File

@ -22,12 +22,16 @@ public interface ProductSpuApi {
List<ProductSpuRespDTO> getSpuList(Collection<Long> ids);
/**
* 批量查询 SPU 数组并且校验是否 SPU 是否有效
* 批量查询 SPU 数组并且校验是否 SPU 是否有效
*
* 如下情况视为无效
* 1. 商品编号不存在
* 2. 商品被禁用
*
* @param ids SPU 编号列表
* @return SPU 数组
*/
List<ProductSpuRespDTO> getSpuListAndValidate(Collection<Long> ids);
List<ProductSpuRespDTO> validateSpuList(Collection<Long> ids);
/**
* 获得 SPU
@ -36,12 +40,4 @@ public interface ProductSpuApi {
*/
ProductSpuRespDTO getSpu(Long id);
/**
* 校验商品是否有效如下情况视为无效
* 1. 商品编号不存在
* 2. 商品被禁用
*
* @param ids 商品编号数组
*/
void validateSpuList(Collection<Long> ids);
}

View File

@ -34,7 +34,7 @@ public interface ErrorCodeConstants {
// ========== 商品 SPU 1-008-005-000 ==========
ErrorCode SPU_NOT_EXISTS = new ErrorCode(1_008_005_000, "商品 SPU 不存在");
ErrorCode SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR = new ErrorCode(1_008_005_001, "商品分类不正确,原因:必须使用第二级的商品分类及以下");
ErrorCode SPU_NOT_ENABLE = new ErrorCode(1_008_005_002, "商品 SPU【[]】不处于上架状态");
ErrorCode SPU_NOT_ENABLE = new ErrorCode(1_008_005_002, "商品 SPU【{}】不处于上架状态");
ErrorCode SPU_NOT_RECYCLE = new ErrorCode(1_008_005_003, "商品 SPU 不处于回收站状态");
// ========== 商品 SKU 1-008-006-000 ==========

View File

@ -34,7 +34,7 @@ public class ProductSpuApiImpl implements ProductSpuApi {
}
@Override
public List<ProductSpuRespDTO> getSpuListAndValidate(Collection<Long> ids) {
public List<ProductSpuRespDTO> validateSpuList(Collection<Long> ids) {
return ProductSpuConvert.INSTANCE.convertList2(spuService.validateSpuList(ids));
}
@ -43,9 +43,4 @@ public class ProductSpuApiImpl implements ProductSpuApi {
return ProductSpuConvert.INSTANCE.convert02(spuService.getSpu(id));
}
@Override
public void validateSpuList(Collection<Long> ids) {
spuService.validateSpuList(ids);
}
}

View File

@ -109,8 +109,8 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
return;
}
// 获得商品分类信息
List<ProductCategoryDO> categoryList = productCategoryMapper.selectBatchIds(ids);
Map<Long, ProductCategoryDO> categoryMap = CollectionUtils.convertMap(categoryList, ProductCategoryDO::getId);
List<ProductCategoryDO> list = productCategoryMapper.selectBatchIds(ids);
Map<Long, ProductCategoryDO> categoryMap = CollectionUtils.convertMap(list, ProductCategoryDO::getId);
// 校验
ids.forEach(id -> {
ProductCategoryDO category = categoryMap.get(id);

View File

@ -146,8 +146,8 @@ public class ProductSpuServiceImpl implements ProductSpuService {
return Collections.emptyList();
}
// 获得商品信息
List<ProductSpuDO> spuList = productSpuMapper.selectBatchIds(ids);
Map<Long, ProductSpuDO> spuMap = CollectionUtils.convertMap(spuList, ProductSpuDO::getId);
List<ProductSpuDO> list = productSpuMapper.selectBatchIds(ids);
Map<Long, ProductSpuDO> spuMap = CollectionUtils.convertMap(list, ProductSpuDO::getId);
// 校验
ids.forEach(id -> {
ProductSpuDO spu = spuMap.get(id);
@ -158,8 +158,7 @@ public class ProductSpuServiceImpl implements ProductSpuService {
throw exception(SPU_NOT_ENABLE, spu.getName());
}
});
return spuList;
return list;
}
@Override

View File

@ -178,8 +178,9 @@ public class CouponServiceImpl implements CouponService {
}
@Override
// TODO @疯狂搞个事务
public void takeCouponByRegister(Long userId) {
List<CouponTemplateDO> templates = couponTemplateService.getCouponTemplateByTakeType(CouponTakeTypeEnum.REGISTER);
List<CouponTemplateDO> templates = couponTemplateService.getCouponTemplateListByTakeType(CouponTakeTypeEnum.REGISTER);
for (CouponTemplateDO template : templates) {
takeCoupon(template.getId(), CollUtil.newHashSet(userId), CouponTakeTypeEnum.REGISTER);
}
@ -226,16 +227,15 @@ public class CouponServiceImpl implements CouponService {
@Override
public Map<Long, Boolean> getUserCanCanTakeMap(Long userId, List<CouponTemplateDO> templates) {
// 1. 未登录时都显示可以领取
Map<Long, Boolean> userCanTakeMap = convertMap(templates, CouponTemplateDO::getId, templateId -> true);
// 未登录时都显示可以领取
if (userId == null) {
return userCanTakeMap;
}
// 过滤领取数量无限制的
// 2.1 过滤领取数量无限制的
Set<Long> templateIds = convertSet(templates, CouponTemplateDO::getId, template -> template.getTakeLimitCount() != -1);
// 检查用户领取的数量是否超过限制
// 2.2 检查用户领取的数量是否超过限制
if (CollUtil.isNotEmpty(templateIds)) {
Map<Long, Integer> couponTakeCountMap = this.getTakeCountMapByTemplateIds(templateIds, userId);
for (CouponTemplateDO template : templates) {
@ -243,7 +243,6 @@ public class CouponServiceImpl implements CouponService {
userCanTakeMap.put(template.getId(), takeCount == null || takeCount < template.getTakeLimitCount());
}
}
return userCanTakeMap;
}

View File

@ -77,7 +77,7 @@ public interface CouponTemplateService {
* @param takeType 领取方式
* @return 优惠券模板列表
*/
List<CouponTemplateDO> getCouponTemplateByTakeType(CouponTakeTypeEnum takeType);
List<CouponTemplateDO> getCouponTemplateListByTakeType(CouponTakeTypeEnum takeType);
/**
* 获得优惠券模板列表

View File

@ -116,7 +116,7 @@ public class CouponTemplateServiceImpl implements CouponTemplateService {
}
@Override
public List<CouponTemplateDO> getCouponTemplateByTakeType(CouponTakeTypeEnum takeType) {
public List<CouponTemplateDO> getCouponTemplateListByTakeType(CouponTakeTypeEnum takeType) {
return couponTemplateMapper.selectListByTakeType(takeType.getValue());
}

View File

@ -109,8 +109,8 @@ public class TradeOrderDO extends BaseDO {
/**
* 推广人编号
* {@link BrokerageUserDO#getId()}
* {@link MemberUserRespDTO#getId()}
*
* 关联 {@link BrokerageUserDO#getId()} 字段 {@link MemberUserRespDTO#getId()} 字段
*/
private Long brokerageUserId;

View File

@ -229,6 +229,10 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
// 生成推广员编号列表
List<Long> bindUserIds = buildBindUserIdsByLevel(userId, pageReqVO.getLevel());
// TODO @疯狂情况一和情况二可以合并哈
// 如果有 nickname 的时候相当于提前查询 users然后 nickname 过滤掉 bindUserIds
// 之后继续使用 selectSummaryPageByUserId 里面 in bindUserIds 查询
// 情况一没有昵称过滤条件时直接使用数据库的分页查询
if (StrUtil.isBlank(pageReqVO.getNickname())) {
// 1.1 分页查询

View File

@ -236,6 +236,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
order.setReceiverName(createReqVO.getReceiverName()).setReceiverMobile(createReqVO.getReceiverMobile());
order.setPickUpVerifyCode(RandomUtil.randomNumbers(8)); // 随机一个核销码长度为 8
}
// TODO @疯狂是不是可以在这里设置下推广人哈
tradeOrderMapper.insert(order);
return order;
}

View File

@ -82,7 +82,7 @@ public class TradePriceServiceImpl implements TradePriceService {
private List<ProductSpuRespDTO> checkSpuList(List<ProductSkuRespDTO> skuList) {
// 获得商品 SPU 数组
return productSpuApi.getSpuListAndValidate(convertSet(skuList, ProductSkuRespDTO::getSpuId));
return productSpuApi.validateSpuList(convertSet(skuList, ProductSkuRespDTO::getSpuId));
}
}

View File

@ -17,6 +17,7 @@ import static java.util.Arrays.asList;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
// TODO 芋艿晚点 review
/**
* {@link TradePointGiveCalculator} 的单元测试类
*
@ -95,4 +96,4 @@ public class TradePointGiveCalculatorTest extends BaseMockitoUnitTest {
assertEquals(orderItem04.getPrice(), 60);
assertEquals(orderItem04.getGivePoint(), 100); // 全局积分 + SKU 积分但是未选中
}
}
}

View File

@ -21,6 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.when;
// TODO 芋艿晚点 review
/**
* {@link TradePointUsePriceCalculator } 的单元测试类
*
@ -329,4 +330,4 @@ public class TradePointUsePriceCalculatorTest extends BaseMockitoUnitTest {
// 断言Promotion 部分
assertEquals(result.getPromotions().size(), 0);
}
}
}

View File

@ -22,11 +22,13 @@
<artifactId>yudao-common</artifactId>
</dependency>
<!-- TODO @疯狂biz 引入哈api 保持低依赖 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-mq</artifactId>
<scope>compile</scope>
</dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@ -38,6 +38,7 @@ public interface ErrorCodeConstants {
//========== 签到配置 1-004-009-000 ==========
ErrorCode SIGN_IN_CONFIG_NOT_EXISTS = new ErrorCode(1_004_009_000, "签到天数规则不存在");
ErrorCode SIGN_IN_CONFIG_EXISTS = new ErrorCode(1_004_009_001, "签到天数规则已存在");
// TODO @疯狂这个可以用 validator 去做通过在 BaseVO 增加一个 @AssertTrue 注解的方式
ErrorCode SIGN_IN_CONFIG_AWARD_EMPTY = new ErrorCode(1_004_009_002, "签到奖励积分和经验不能同时为空");
//========== 签到配置 1-004-010-000 ==========

View File

@ -7,7 +7,7 @@ import lombok.ToString;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - 会员用户 修改等级 Request VO")
@Schema(description = "管理后台 - 用户修改等级 Request VO")
@Data
@ToString(callSuper = true)
public class MemberUserUpdateLevelReqVO {

View File

@ -6,7 +6,7 @@ import lombok.ToString;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - 会员用户 修改积分 Request VO")
@Schema(description = "管理后台 - 用户修改积分 Request VO")
@Data
@ToString(callSuper = true)
public class MemberUserUpdatePointReqVO {

View File

@ -7,6 +7,7 @@ import org.springframework.stereotype.Component;
import javax.annotation.Resource;
// TODO @疯狂 UserCreateMessage解耦然后优惠劵监听到去发卷
/**
* 新人券发放 Producer
*

View File

@ -95,6 +95,7 @@ public class MemberUserServiceImpl implements MemberUserService {
memberUserMapper.insert(user);
// 发送 MQ 消息发放新人券
// TODO @疯狂事务结束后在发送 MQ 消息避免出现消息已经发了事务没提交或者回滚了
registerCouponProducer.sendMailSendMessage(user.getId());
return user;
}

View File

@ -29,11 +29,12 @@ public class PayWalletController {
@Resource
private PayWalletService payWalletService;
@GetMapping("/user-wallet")
@GetMapping("/get")
@PreAuthorize("@ss.hasPermission('pay:wallet:query')")
@Operation(summary = "获得用户钱包明细")
public CommonResult<PayWalletRespVO> getByUser(PayWalletUserReqVO reqVO) {
PayWalletDO wallet = payWalletService.getWalletByUserIdAndType(reqVO.getUserId(), reqVO.getUserType());
public CommonResult<PayWalletRespVO> getWallet(PayWalletUserReqVO reqVO) {
PayWalletDO wallet = payWalletService.getOrCreateWallet(reqVO.getUserId(), reqVO.getUserType());
return success(PayWalletConvert.INSTANCE.convert02(wallet));
}
}

View File

@ -19,4 +19,5 @@ public class PayWalletUserReqVO {
@NotNull(message = "用户类型不能为空")
@InEnum(value = UserTypeEnum.class, message = "用户类型必须是 {value}")
private Integer userType;
}

View File

@ -87,12 +87,4 @@ public interface PayWalletService {
*/
void unFreezePrice(Long id, Integer price);
/**
* 获得用户的钱包明细
*
* @param userId 用户编号
* @param userType 用户类型
* @return 用户的钱包明细
*/
PayWalletDO getWalletByUserIdAndType(Long userId, Integer userType);
}

View File

@ -195,9 +195,4 @@ public class PayWalletServiceImpl implements PayWalletService {
}
}
@Override
public PayWalletDO getWalletByUserIdAndType(Long userId, Integer userType) {
return walletMapper.selectByUserIdAndType(userId, userType);
}
}