You've already forked FrameTour-BE
feat(order): 增加重复购买检查功能
- 为VLOG_VIDEO、RECORDING_SET 和 PHOTO_SET 类型的产品添加重复购买检查 - 使用 sourceMapper 和 videoMapper 查询用户已购买的产品数量- 根据查询结果设置产品数量,避免重复购买 -优化了价格计算流程,先检查缓存再进行重复购买检查
This commit is contained in:
@@ -2,7 +2,16 @@ package com.ycwl.basic.controller.mobile;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.ycwl.basic.constant.BaseContextHandler;
|
||||
import com.ycwl.basic.mapper.SourceMapper;
|
||||
import com.ycwl.basic.mapper.VideoMapper;
|
||||
import com.ycwl.basic.model.pc.order.req.CreateOrderReqVO;
|
||||
import com.ycwl.basic.model.pc.source.entity.MemberSourceEntity;
|
||||
import com.ycwl.basic.model.pc.source.req.SourceReqQuery;
|
||||
import com.ycwl.basic.model.pc.task.entity.TaskEntity;
|
||||
import com.ycwl.basic.model.pc.video.entity.MemberVideoEntity;
|
||||
import com.ycwl.basic.pricing.enums.ProductType;
|
||||
import com.ycwl.basic.repository.TemplateRepository;
|
||||
import com.ycwl.basic.repository.VideoTaskRepository;
|
||||
import com.ycwl.basic.service.pc.OrderService;
|
||||
import com.ycwl.basic.utils.ApiResponse;
|
||||
import com.ycwl.basic.pricing.dto.*;
|
||||
@@ -18,12 +27,17 @@ import com.ycwl.basic.order.dto.OrderV2PageRequest;
|
||||
import com.ycwl.basic.order.dto.PaymentParamsRequest;
|
||||
import com.ycwl.basic.order.dto.PaymentParamsResponse;
|
||||
import com.ycwl.basic.order.dto.PaymentCallbackResponse;
|
||||
import com.ycwl.basic.utils.JacksonUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* 移动端订单控制器V2
|
||||
@@ -40,7 +54,11 @@ public class AppOrderV2Controller {
|
||||
private final PriceCacheService priceCacheService;
|
||||
private final IOrderService orderService;
|
||||
private final OrderService oldOrderService;
|
||||
|
||||
private final SourceMapper sourceMapper;
|
||||
private final VideoMapper videoMapper;
|
||||
private final VideoTaskRepository videoTaskRepository;
|
||||
private final TemplateRepository templateRepository;
|
||||
|
||||
/**
|
||||
* 移动端价格计算
|
||||
* 包含权限验证:验证人脸所属景区与当前用户匹配
|
||||
@@ -76,14 +94,60 @@ public class AppOrderV2Controller {
|
||||
Long scenicId = face.getScenicId();
|
||||
|
||||
// 先尝试从Redis缓存获取价格计算结果
|
||||
// PriceCalculationResult cachedResult = priceCacheService.getCachedPriceResult(
|
||||
// currentUserId, scenicId, request.getProducts());
|
||||
//
|
||||
// if (cachedResult != null) {
|
||||
// log.info("命中价格缓存: userId={}, scenicId={}, finalAmount={}",
|
||||
// currentUserId, scenicId, cachedResult.getFinalAmount());
|
||||
// return ApiResponse.success(cachedResult);
|
||||
// }
|
||||
PriceCalculationResult cachedResult = priceCacheService.getCachedPriceResult(
|
||||
currentUserId, scenicId, request.getProducts());
|
||||
|
||||
if (cachedResult != null) {
|
||||
log.info("命中价格缓存: userId={}, scenicId={}, finalAmount={}",
|
||||
currentUserId, scenicId, cachedResult.getFinalAmount());
|
||||
return ApiResponse.success(cachedResult);
|
||||
}
|
||||
|
||||
request.getProducts().forEach(product -> {
|
||||
switch (product.getProductType()) {
|
||||
case VLOG_VIDEO:
|
||||
AtomicInteger deviceCount = new AtomicInteger();
|
||||
List<MemberVideoEntity> videoEntities = videoMapper.listRelationByFaceAndTemplate(face.getId(), Long.valueOf(product.getProductId()));
|
||||
if (videoEntities != null && !videoEntities.isEmpty()) {
|
||||
TaskEntity task = videoTaskRepository.getTaskById(videoEntities.getFirst().getTaskId());
|
||||
if (task != null) {
|
||||
Map<String, Object> paramJson = JacksonUtil.parseObject(task.getTaskParams(), Map.class);
|
||||
if (paramJson == null) {
|
||||
deviceCount.set(1);
|
||||
} else {
|
||||
List<String> templatePlaceholder = templateRepository.getTemplatePlaceholder(task.getTemplateId());
|
||||
paramJson.entrySet().stream()
|
||||
.filter(entry -> StringUtils.isNumeric(entry.getKey()))
|
||||
.forEach(entry -> {
|
||||
List<Object> jsonArray = JacksonUtil.parseArray(JacksonUtil.toJSONString(entry.getValue()), Object.class);
|
||||
if (jsonArray != null && !jsonArray.isEmpty()) {
|
||||
for (Object ignored : jsonArray) {
|
||||
if (templatePlaceholder.contains(entry.getKey())) {
|
||||
deviceCount.getAndIncrement();
|
||||
templatePlaceholder.remove(entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
product.setQuantity(deviceCount.get());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RECORDING_SET:
|
||||
case PHOTO_SET:
|
||||
SourceReqQuery sourceReqQuery = new SourceReqQuery();
|
||||
sourceReqQuery.setMemberId(currentUserId);
|
||||
sourceReqQuery.setType(product.getProductType() == ProductType.RECORDING_SET ? 1 : 2);
|
||||
sourceReqQuery.setFaceId(face.getId());
|
||||
Integer count = sourceMapper.countUser(sourceReqQuery);
|
||||
product.setQuantity(count);
|
||||
break;
|
||||
default:
|
||||
log.warn("未知的商品类型,跳过重复购买检查: productType={}", product.getProductType());
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// 转换为标准价格计算请求
|
||||
PriceCalculationRequest standardRequest = request.toStandardRequest(currentUserId, scenicId);
|
||||
|
Reference in New Issue
Block a user