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.github.pagehelper.PageInfo;
|
||||||
import com.ycwl.basic.constant.BaseContextHandler;
|
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.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.service.pc.OrderService;
|
||||||
import com.ycwl.basic.utils.ApiResponse;
|
import com.ycwl.basic.utils.ApiResponse;
|
||||||
import com.ycwl.basic.pricing.dto.*;
|
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.PaymentParamsRequest;
|
||||||
import com.ycwl.basic.order.dto.PaymentParamsResponse;
|
import com.ycwl.basic.order.dto.PaymentParamsResponse;
|
||||||
import com.ycwl.basic.order.dto.PaymentCallbackResponse;
|
import com.ycwl.basic.order.dto.PaymentCallbackResponse;
|
||||||
|
import com.ycwl.basic.utils.JacksonUtil;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 移动端订单控制器V2
|
* 移动端订单控制器V2
|
||||||
@@ -40,7 +54,11 @@ public class AppOrderV2Controller {
|
|||||||
private final PriceCacheService priceCacheService;
|
private final PriceCacheService priceCacheService;
|
||||||
private final IOrderService orderService;
|
private final IOrderService orderService;
|
||||||
private final OrderService oldOrderService;
|
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();
|
Long scenicId = face.getScenicId();
|
||||||
|
|
||||||
// 先尝试从Redis缓存获取价格计算结果
|
// 先尝试从Redis缓存获取价格计算结果
|
||||||
// PriceCalculationResult cachedResult = priceCacheService.getCachedPriceResult(
|
PriceCalculationResult cachedResult = priceCacheService.getCachedPriceResult(
|
||||||
// currentUserId, scenicId, request.getProducts());
|
currentUserId, scenicId, request.getProducts());
|
||||||
//
|
|
||||||
// if (cachedResult != null) {
|
if (cachedResult != null) {
|
||||||
// log.info("命中价格缓存: userId={}, scenicId={}, finalAmount={}",
|
log.info("命中价格缓存: userId={}, scenicId={}, finalAmount={}",
|
||||||
// currentUserId, scenicId, cachedResult.getFinalAmount());
|
currentUserId, scenicId, cachedResult.getFinalAmount());
|
||||||
// return ApiResponse.success(cachedResult);
|
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);
|
PriceCalculationRequest standardRequest = request.toStandardRequest(currentUserId, scenicId);
|
||||||
|
Reference in New Issue
Block a user