refactor: 盲盒功能代码优化和完善

修复和改进:
- 修复字段映射:blind_box_gift_id -> blind_box_id
- 移除不必要的 @Version 乐观锁字段
- 优化 Mapper 方法:统一使用 listActiveEntries,简化查询逻辑
- 新增客户端接口:盲盒购买、奖励查询和兑现
- 增强权限校验:奖励兑现时验证客户身份
- 完善单元测试:增加客户身份验证测试用例
- 代码格式化:调整 import 顺序,优化代码结构

客户端 API:
- GET /wx/blind-box/config/list - 查询可用盲盒列表
- POST /wx/blind-box/order/purchase - 购买盲盒
- GET /wx/blind-box/reward/list - 查询我的盲盒奖励
- POST /wx/blind-box/reward/{id}/dispatch - 兑现盲盒奖励

其他优化:
- 增强 SQL 查询安全性,添加 deleted 字段过滤
- 优化店员提成计算逻辑
- 改进参数可选性(levelId 参数改为可选)
This commit is contained in:
irving
2025-10-31 02:48:03 -04:00
parent 422e781c60
commit e7ccadaea0
17 changed files with 480 additions and 30 deletions

View File

@@ -4,8 +4,8 @@ import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.starry.admin.common.exception.CustomException;
import com.starry.admin.modules.blindbox.module.entity.BlindBoxConfigEntity;
import com.starry.admin.modules.blindbox.module.constant.BlindBoxConfigStatus;
import com.starry.admin.modules.blindbox.module.entity.BlindBoxConfigEntity;
import com.starry.admin.modules.blindbox.service.BlindBoxConfigService;
import com.starry.admin.utils.SecurityUtils;
import com.starry.common.result.R;

View File

@@ -3,7 +3,6 @@ package com.starry.admin.modules.blindbox.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.starry.admin.modules.blindbox.module.dto.BlindBoxCandidate;
import com.starry.admin.modules.blindbox.module.entity.BlindBoxPoolEntity;
import com.starry.admin.modules.blindbox.module.constant.BlindBoxPoolStatus;
import java.time.LocalDateTime;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
@@ -17,24 +16,24 @@ public interface BlindBoxPoolMapper extends BaseMapper<BlindBoxPoolEntity> {
@Select({
"SELECT id AS poolId,",
" tenant_id AS tenantId,",
" blind_box_gift_id AS blindBoxId,",
" blind_box_id AS blindBoxId,",
" reward_gift_id AS rewardGiftId,",
" reward_price AS rewardPrice,",
" weight,",
" remaining_stock AS remainingStock",
"FROM blind_box_pool",
"WHERE tenant_id = #{tenantId}",
" AND blind_box_gift_id = #{blindBoxId}",
" AND status = #{enabledStatus}",
" AND blind_box_id = #{blindBoxId}",
" AND status = 1",
" AND deleted = 0",
" AND (valid_from IS NULL OR valid_from <= #{now})",
" AND (valid_to IS NULL OR valid_to >= #{now})",
" AND (remaining_stock IS NULL OR remaining_stock > 0)"
})
List<BlindBoxCandidate> listEntries(
List<BlindBoxCandidate> listActiveEntries(
@Param("tenantId") String tenantId,
@Param("blindBoxId") String blindBoxId,
@Param("now") LocalDateTime now,
@Param("enabledStatus") int enabledStatus);
@Param("now") LocalDateTime now);
@Update({
"UPDATE blind_box_pool",
@@ -45,6 +44,7 @@ public interface BlindBoxPoolMapper extends BaseMapper<BlindBoxPoolEntity> {
"WHERE tenant_id = #{tenantId}",
" AND id = #{poolId}",
" AND reward_gift_id = #{rewardGiftId}",
" AND deleted = 0",
" AND (remaining_stock IS NULL OR remaining_stock > 0)"
})
int consumeRewardStock(

View File

@@ -3,6 +3,7 @@ package com.starry.admin.modules.blindbox.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.starry.admin.modules.blindbox.module.entity.BlindBoxRewardEntity;
import java.time.LocalDateTime;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
@@ -29,4 +30,17 @@ public interface BlindBoxRewardMapper extends BaseMapper<BlindBoxRewardEntity> {
@Param("clerkId") String clerkId,
@Param("orderId") String orderId,
@Param("usedTime") LocalDateTime usedTime);
@Select({
"SELECT * FROM blind_box_reward",
"WHERE tenant_id = #{tenantId}",
" AND customer_id = #{customerId}",
" AND deleted = 0",
" AND (#{status} IS NULL OR status = #{status})",
"ORDER BY created_time DESC"
})
List<BlindBoxRewardEntity> listByCustomer(
@Param("tenantId") String tenantId,
@Param("customerId") String customerId,
@Param("status") String status);
}

View File

@@ -2,7 +2,6 @@ package com.starry.admin.modules.blindbox.module.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.Version;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.starry.common.domain.BaseEntity;
import java.math.BigDecimal;
@@ -20,7 +19,7 @@ public class BlindBoxRewardEntity extends BaseEntity<BlindBoxRewardEntity> {
private String tenantId;
private String customerId;
@TableField("blind_box_gift_id")
@TableField("blind_box_id")
private String blindBoxId;
private String rewardGiftId;
private BigDecimal rewardPrice;
@@ -42,6 +41,4 @@ public class BlindBoxRewardEntity extends BaseEntity<BlindBoxRewardEntity> {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime usedTime;
@Version
private Integer version;
}

View File

@@ -11,6 +11,7 @@ import com.starry.admin.modules.order.module.dto.PaymentInfo;
import com.starry.admin.modules.order.service.IOrderLifecycleService;
import com.starry.admin.modules.order.service.IPlayOrderInfoService;
import com.starry.admin.modules.shop.module.entity.PlayGiftInfoEntity;
import com.starry.admin.modules.shop.service.IPlayClerkGiftInfoService;
import com.starry.admin.modules.shop.service.IPlayGiftInfoService;
import com.starry.common.utils.IdUtils;
import java.math.BigDecimal;
@@ -26,6 +27,7 @@ public class BlindBoxDispatchService {
private final IOrderLifecycleService orderLifecycleService;
private final IPlayOrderInfoService orderInfoService;
private final IPlayGiftInfoService giftInfoService;
private final IPlayClerkGiftInfoService clerkGiftInfoService;
@Transactional(rollbackFor = Exception.class)
public OrderPlacementResult dispatchRewardOrder(BlindBoxRewardEntity reward, String clerkId) {
@@ -71,9 +73,13 @@ public class BlindBoxDispatchService {
.remark("盲盒奖励兑现")
.build();
return orderLifecycleService.placeOrder(OrderPlacementCommand.builder()
OrderPlacementResult result = orderLifecycleService.placeOrder(OrderPlacementCommand.builder()
.orderContext(context)
.balanceOperationAction("盲盒奖励兑现")
.build());
if (clerkId != null) {
clerkGiftInfoService.incrementGiftCount(clerkId, giftInfo.getId(), reward.getTenantId(), 1);
}
return result;
}
}

View File

@@ -25,7 +25,6 @@ import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;

View File

@@ -3,7 +3,6 @@ package com.starry.admin.modules.blindbox.service;
import com.starry.admin.common.exception.CustomException;
import com.starry.admin.modules.blindbox.mapper.BlindBoxPoolMapper;
import com.starry.admin.modules.blindbox.mapper.BlindBoxRewardMapper;
import com.starry.admin.modules.blindbox.module.constant.BlindBoxPoolStatus;
import com.starry.admin.modules.blindbox.module.constant.BlindBoxRewardStatus;
import com.starry.admin.modules.blindbox.module.dto.BlindBoxCandidate;
import com.starry.admin.modules.blindbox.module.entity.BlindBoxConfigEntity;
@@ -76,11 +75,7 @@ public class BlindBoxService {
if (!tenantId.equals(config.getTenantId())) {
throw new CustomException("盲盒不存在或已下架");
}
List<BlindBoxCandidate> candidates = poolMapper.listEntries(
tenantId,
blindBoxId,
now,
BlindBoxPoolStatus.ENABLED.getCode());
List<BlindBoxCandidate> candidates = poolMapper.listActiveEntries(tenantId, blindBoxId, now);
if (CollectionUtils.isEmpty(candidates)) {
throw new CustomException("盲盒奖池暂无可用奖励");
}
@@ -111,15 +106,18 @@ public class BlindBoxService {
}
@Transactional(rollbackFor = Exception.class)
public OrderPlacementResult dispatchReward(String rewardId, String clerkId) {
public OrderPlacementResult dispatchReward(String rewardId, String clerkId, String customerId) {
BlindBoxRewardEntity reward = rewardMapper.lockByIdForUpdate(rewardId);
if (reward == null) {
throw new CustomException("盲盒奖励不存在");
}
if (customerId != null && !customerId.equals(reward.getCustomerId())) {
throw new CustomException("无权操作该盲盒奖励");
}
LocalDateTime now = LocalDateTime.now(clock);
if (!BlindBoxRewardStatus.UNUSED.getCode().equals(reward.getStatus())) {
throw new CustomException("盲盒奖励已使用");
}
LocalDateTime now = LocalDateTime.now(clock);
if (reward.getExpiresAt() != null && reward.getExpiresAt().isBefore(now)) {
throw new CustomException("盲盒奖励已过期");
}
@@ -160,6 +158,10 @@ public class BlindBoxService {
: value.setScale(2, RoundingMode.HALF_UP);
}
public java.util.List<BlindBoxRewardEntity> listRewards(String tenantId, String customerId, String status) {
return rewardMapper.listByCustomer(tenantId, customerId, status);
}
public interface RandomAdapter {
double nextDouble();
}

View File

@@ -3,10 +3,10 @@ package com.starry.admin.modules.blindbox.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.starry.admin.common.exception.CustomException;
import com.starry.admin.modules.blindbox.mapper.BlindBoxConfigMapper;
import com.starry.admin.modules.blindbox.module.constant.BlindBoxConfigStatus;
import com.starry.admin.modules.blindbox.module.entity.BlindBoxConfigEntity;
import com.starry.admin.modules.blindbox.service.BlindBoxConfigService;
import java.util.List;
import com.starry.admin.modules.blindbox.module.constant.BlindBoxConfigStatus;
import org.springframework.stereotype.Service;
@Service

View File

@@ -0,0 +1,89 @@
package com.starry.admin.modules.weichat.controller;
import cn.hutool.core.collection.CollUtil;
import com.starry.admin.common.aspect.CustomUserLogin;
import com.starry.admin.common.conf.ThreadLocalRequestDetail;
import com.starry.admin.common.exception.CustomException;
import com.starry.admin.modules.blindbox.module.entity.BlindBoxConfigEntity;
import com.starry.admin.modules.blindbox.service.BlindBoxConfigService;
import com.starry.admin.modules.custom.module.entity.PlayCustomUserInfoEntity;
import com.starry.admin.modules.weichat.entity.blindbox.BlindBoxConfigView;
import com.starry.admin.modules.weichat.entity.blindbox.BlindBoxPurchaseRequest;
import com.starry.admin.modules.weichat.entity.blindbox.BlindBoxPurchaseResult;
import com.starry.admin.modules.weichat.entity.blindbox.BlindBoxRewardDispatchRequest;
import com.starry.admin.modules.weichat.entity.blindbox.BlindBoxRewardView;
import com.starry.admin.modules.weichat.service.WxBlindBoxOrderService;
import com.starry.common.result.R;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.validation.Valid;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/wx/blind-box")
@Validated
public class WxBlindBoxController {
@Resource
private BlindBoxConfigService blindBoxConfigService;
@Resource
private WxBlindBoxOrderService wxBlindBoxOrderService;
@CustomUserLogin
@GetMapping("/config/list")
public R listConfigs() {
PlayCustomUserInfoEntity user = ThreadLocalRequestDetail.getCustomUserInfo();
if (user == null) {
throw new CustomException("用户未登录");
}
List<BlindBoxConfigEntity> configs = blindBoxConfigService.listActiveByTenant(user.getTenantId());
List<BlindBoxConfigView> views = CollUtil.emptyIfNull(configs).stream()
.map(this::toConfigView)
.collect(Collectors.toList());
return R.ok(views);
}
@CustomUserLogin
@PostMapping("/order/purchase")
public R purchase(@Valid @RequestBody BlindBoxPurchaseRequest request) {
BlindBoxPurchaseResult result = wxBlindBoxOrderService.purchase(request);
return R.ok(result);
}
@CustomUserLogin
@PostMapping("/reward/{id}/dispatch")
public R dispatch(@PathVariable("id") String rewardId, @Valid @RequestBody BlindBoxRewardDispatchRequest body) {
BlindBoxRewardView view = wxBlindBoxOrderService.dispatchReward(rewardId, body.getClerkId());
return R.ok(view);
}
@CustomUserLogin
@GetMapping("/reward/list")
public R listRewards(@RequestParam(value = "status", required = false) String status) {
PlayCustomUserInfoEntity user = ThreadLocalRequestDetail.getCustomUserInfo();
if (user == null) {
throw new CustomException("用户未登录");
}
List<BlindBoxRewardView> rewards = wxBlindBoxOrderService.listRewards(user.getTenantId(), user.getId(), status);
return R.ok(rewards);
}
private BlindBoxConfigView toConfigView(BlindBoxConfigEntity entity) {
BlindBoxConfigView view = new BlindBoxConfigView();
view.setId(entity.getId());
view.setName(entity.getName());
view.setCoverUrl(entity.getCoverUrl());
view.setDescription(entity.getDescription());
view.setPrice(entity.getPrice());
return view;
}
}

View File

@@ -57,7 +57,7 @@ public class WxClerkCommodityController {
@ApiResponses({
@ApiResponse(code = 200, message = "操作成功", response = PlayCommodityReturnVo.class, responseContainer = "List")})
@GetMapping("/custom/queryClerkAllCommodityByLevel")
public R queryClerkAllCommodityByLevel(@RequestParam("id") String levelId) {
public R queryClerkAllCommodityByLevel(@RequestParam(value = "id", required = false) String levelId) {
List<PlayCommodityAndLevelInfoEntity> levelInfoEntities = iPlayCommodityAndLevelInfoService.selectAll();
List<PlayCommodityReturnVo> tree = playCommodityInfoService.selectTree();
if (levelId == null || levelId.isEmpty()) {

View File

@@ -0,0 +1,21 @@
package com.starry.admin.modules.weichat.entity.blindbox;
import java.math.BigDecimal;
import lombok.Data;
/**
* 盲盒配置前端视图。
*/
@Data
public class BlindBoxConfigView {
private String id;
private String name;
private String coverUrl;
private String description;
private BigDecimal price;
}

View File

@@ -0,0 +1,18 @@
package com.starry.admin.modules.weichat.entity.blindbox;
import javax.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class BlindBoxPurchaseRequest {
@NotBlank(message = "盲盒ID不能为空")
private String blindBoxId;
@NotBlank(message = "店员ID不能为空")
private String clerkId;
private String weiChatCode;
private String remark;
}

View File

@@ -0,0 +1,42 @@
package com.starry.admin.modules.weichat.entity.blindbox;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class BlindBoxPurchaseResult {
private String orderId;
private BlindBoxRewardInfo reward;
@Data
@Builder
public static class BlindBoxRewardInfo {
private String rewardId;
private String blindBoxId;
private String blindBoxName;
private String blindBoxCover;
private String rewardGiftId;
private String rewardGiftName;
private String rewardGiftImage;
private BigDecimal rewardGiftPrice;
private BigDecimal boxPrice;
private LocalDateTime expiresAt;
private String status;
}
}

View File

@@ -0,0 +1,11 @@
package com.starry.admin.modules.weichat.entity.blindbox;
import javax.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class BlindBoxRewardDispatchRequest {
@NotBlank(message = "店员ID不能为空")
private String clerkId;
}

View File

@@ -0,0 +1,33 @@
package com.starry.admin.modules.weichat.entity.blindbox;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class BlindBoxRewardView {
private String id;
private String blindBoxId;
private String blindBoxName;
private String blindBoxCover;
private String rewardGiftId;
private String rewardGiftName;
private String rewardGiftImage;
private BigDecimal rewardGiftPrice;
private BigDecimal boxPrice;
private LocalDateTime expiresAt;
private String status;
}

View File

@@ -0,0 +1,207 @@
package com.starry.admin.modules.weichat.service;
import com.starry.admin.common.conf.ThreadLocalRequestDetail;
import com.starry.admin.common.exception.CustomException;
import com.starry.admin.modules.blindbox.mapper.BlindBoxRewardMapper;
import com.starry.admin.modules.blindbox.module.entity.BlindBoxConfigEntity;
import com.starry.admin.modules.blindbox.module.entity.BlindBoxRewardEntity;
import com.starry.admin.modules.blindbox.service.BlindBoxConfigService;
import com.starry.admin.modules.blindbox.service.BlindBoxService;
import com.starry.admin.modules.custom.module.entity.PlayCustomUserInfoEntity;
import com.starry.admin.modules.custom.service.IPlayCustomUserInfoService;
import com.starry.admin.modules.order.module.constant.OrderConstant;
import com.starry.admin.modules.order.module.constant.OrderConstant.OrderActor;
import com.starry.admin.modules.order.module.constant.OrderConstant.RewardType;
import com.starry.admin.modules.order.module.dto.CommodityInfo;
import com.starry.admin.modules.order.module.dto.OrderCreationContext;
import com.starry.admin.modules.order.module.dto.OrderPlacementCommand;
import com.starry.admin.modules.order.module.dto.OrderPlacementResult;
import com.starry.admin.modules.order.module.dto.PaymentInfo;
import com.starry.admin.modules.order.module.entity.PlayOrderInfoEntity;
import com.starry.admin.modules.order.service.IOrderLifecycleService;
import com.starry.admin.modules.order.service.IPlayOrderInfoService;
import com.starry.admin.modules.shop.mapper.PlayGiftInfoMapper;
import com.starry.admin.modules.shop.module.entity.PlayGiftInfoEntity;
import com.starry.admin.modules.weichat.entity.blindbox.BlindBoxPurchaseRequest;
import com.starry.admin.modules.weichat.entity.blindbox.BlindBoxPurchaseResult;
import com.starry.admin.modules.weichat.entity.blindbox.BlindBoxPurchaseResult.BlindBoxRewardInfo;
import com.starry.admin.modules.weichat.entity.blindbox.BlindBoxRewardView;
import com.starry.common.utils.IdUtils;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class WxBlindBoxOrderService {
@Resource
private BlindBoxConfigService blindBoxConfigService;
@Resource
private BlindBoxService blindBoxService;
@Resource
private IOrderLifecycleService orderLifecycleService;
@Resource
private IPlayOrderInfoService playOrderInfoService;
@Resource
private IPlayCustomUserInfoService customUserInfoService;
@Resource
private PlayGiftInfoMapper playGiftInfoMapper;
@Resource
private BlindBoxRewardMapper blindBoxRewardMapper;
@Transactional(rollbackFor = Exception.class)
public BlindBoxPurchaseResult purchase(BlindBoxPurchaseRequest request) {
PlayCustomUserInfoEntity sessionUser = ThreadLocalRequestDetail.getCustomUserInfo();
if (sessionUser == null || sessionUser.getId() == null) {
throw new CustomException("用户未登录");
}
PlayCustomUserInfoEntity customer = customUserInfoService.selectById(sessionUser.getId());
if (customer == null) {
throw new CustomException("用户不存在");
}
BlindBoxConfigEntity config = blindBoxConfigService.requireById(request.getBlindBoxId());
if (!Objects.equals(config.getTenantId(), customer.getTenantId())) {
throw new CustomException("盲盒不存在或已下架");
}
if (!Objects.equals(config.getStatus(), 1)) {
throw new CustomException("盲盒已下架");
}
BigDecimal boxPrice = Objects.requireNonNull(config.getPrice(), "盲盒价格未配置");
if (boxPrice.compareTo(BigDecimal.ZERO) <= 0) {
throw new CustomException("盲盒价格异常");
}
String orderId = IdUtils.getUuid();
OrderCreationContext orderRequest = buildOrderRequest(orderId, request, customer, config, boxPrice);
OrderPlacementResult result = orderLifecycleService.placeOrder(OrderPlacementCommand.builder()
.orderContext(orderRequest)
.balanceOperationAction("购买盲盒")
.build());
PlayOrderInfoEntity order = result.getOrder();
BlindBoxRewardEntity reward = blindBoxService.drawReward(
customer.getTenantId(),
orderId,
customer.getId(),
config.getId(),
UUID.randomUUID().toString());
PlayGiftInfoEntity giftInfo = playGiftInfoMapper.selectById(reward.getRewardGiftId());
return BlindBoxPurchaseResult.builder()
.orderId(order.getId())
.reward(buildRewardInfo(reward, config, giftInfo))
.build();
}
public List<BlindBoxRewardView> listRewards(String tenantId, String customerId, String status) {
return blindBoxService.listRewards(tenantId, customerId, status).stream()
.map(this::toRewardView)
.collect(Collectors.toList());
}
@Transactional(rollbackFor = Exception.class)
public BlindBoxRewardView dispatchReward(String rewardId, String clerkId) {
PlayCustomUserInfoEntity sessionUser = ThreadLocalRequestDetail.getCustomUserInfo();
if (sessionUser == null || sessionUser.getId() == null) {
throw new CustomException("用户未登录");
}
blindBoxService.dispatchReward(rewardId, clerkId, sessionUser.getId());
BlindBoxRewardEntity updated = blindBoxRewardMapper.selectById(rewardId);
if (updated == null) {
throw new CustomException("盲盒奖励不存在");
}
return toRewardView(updated);
}
public BlindBoxRewardView toRewardView(BlindBoxRewardEntity reward) {
BlindBoxConfigEntity config = blindBoxConfigService.getById(reward.getBlindBoxId());
PlayGiftInfoEntity gift = playGiftInfoMapper.selectById(reward.getRewardGiftId());
return BlindBoxRewardView.builder()
.id(reward.getId())
.blindBoxId(reward.getBlindBoxId())
.blindBoxName(config != null ? config.getName() : null)
.blindBoxCover(config != null ? config.getCoverUrl() : null)
.rewardGiftId(reward.getRewardGiftId())
.rewardGiftName(gift != null ? gift.getName() : reward.getRewardGiftId())
.rewardGiftImage(gift != null ? gift.getUrl() : null)
.rewardGiftPrice(reward.getRewardPrice())
.boxPrice(reward.getBoxPrice())
.expiresAt(reward.getExpiresAt())
.status(reward.getStatus())
.build();
}
private BlindBoxRewardInfo buildRewardInfo(
BlindBoxRewardEntity reward,
BlindBoxConfigEntity config,
PlayGiftInfoEntity giftInfo) {
return BlindBoxRewardInfo.builder()
.rewardId(reward.getId())
.blindBoxId(reward.getBlindBoxId())
.blindBoxName(config != null ? config.getName() : null)
.blindBoxCover(config != null ? config.getCoverUrl() : null)
.rewardGiftId(reward.getRewardGiftId())
.rewardGiftName(giftInfo != null ? giftInfo.getName() : reward.getRewardGiftId())
.rewardGiftImage(giftInfo != null ? giftInfo.getUrl() : null)
.rewardGiftPrice(reward.getRewardPrice())
.boxPrice(reward.getBoxPrice())
.expiresAt(reward.getExpiresAt())
.status(reward.getStatus())
.build();
}
private OrderCreationContext buildOrderRequest(
String orderId,
BlindBoxPurchaseRequest request,
PlayCustomUserInfoEntity customer,
BlindBoxConfigEntity config,
BigDecimal boxPrice) {
return OrderCreationContext.builder()
.orderId(orderId)
.orderNo(playOrderInfoService.getOrderNo())
.orderStatus(OrderConstant.OrderStatus.COMPLETED)
.orderType(OrderConstant.OrderType.BLIND_BOX_PURCHASE)
.placeType(OrderConstant.PlaceType.REWARD)
.rewardType(RewardType.GIFT)
.isFirstOrder(false)
.creatorActor(OrderActor.CUSTOMER)
.creatorId(customer.getId())
.commodityInfo(CommodityInfo.builder()
.commodityId(config.getId())
.commodityType(OrderConstant.CommodityType.GIFT)
.commodityPrice(config.getPrice())
.commodityName(config.getName())
.commodityNumber("1")
.serviceDuration("")
.build())
.paymentInfo(PaymentInfo.builder()
.orderMoney(boxPrice)
.finalAmount(boxPrice)
.discountAmount(BigDecimal.ZERO)
.couponIds(Collections.emptyList())
.payMethod(OrderConstant.PayMethod.BALANCE.getCode())
.paymentSource(OrderConstant.PaymentSource.BALANCE)
.build())
.purchaserBy(customer.getId())
.acceptBy(request.getClerkId())
.weiChatCode(request.getWeiChatCode())
.remark(request.getRemark())
.build();
}
}