Files
FrameTour-BE/src/main/java/com/ycwl/basic/biz/OrderBiz.java
Jerry Yan 3f6f1508c5 feat(order): 增加faceId校验的订单购买检查功能
- 新增checkUserBuyFaceItem方法,支持校验用户购买商品时的人脸ID匹配
- 修改PriceBiz中商品类型设置,从13改为5
- 更新FaceServiceImpl中的购买检查逻辑,使用新的带faceId校验的方法
- 调整OrderServiceImpl中订单项的goodsType和goodsId设置逻辑
- 移除旧的checkUserBuyItem方法及相关缓存逻辑
- 新增ORDER_USER_FACE_TYPE_BUY_ITEM_CACHE_KEY缓存键定义
2025-12-13 19:00:25 +08:00

328 lines
15 KiB
Java

package com.ycwl.basic.biz;
import com.ycwl.basic.enums.StatisticEnum;
import com.ycwl.basic.integration.common.manager.ScenicConfigManager;
import com.ycwl.basic.mapper.OrderMapper;
import com.ycwl.basic.mapper.SourceMapper;
import com.ycwl.basic.mapper.StatisticsMapper;
import com.ycwl.basic.mapper.VideoMapper;
import com.ycwl.basic.model.mobile.order.IsBuyBatchRespVO;
import com.ycwl.basic.model.mobile.order.IsBuyRespVO;
import com.ycwl.basic.model.mobile.order.PriceObj;
import com.ycwl.basic.model.mobile.statistic.req.StatisticsRecordAddReq;
import com.ycwl.basic.model.pc.coupon.entity.CouponEntity;
import com.ycwl.basic.model.pc.couponRecord.resp.CouponRecordQueryResp;
import com.ycwl.basic.model.pc.face.entity.FaceEntity;
import com.ycwl.basic.model.pc.order.entity.OrderEntity;
import com.ycwl.basic.model.pc.order.entity.OrderItemEntity;
import com.ycwl.basic.model.pc.order.resp.OrderAppRespVO;
import com.ycwl.basic.model.pc.order.resp.OrderItemVO;
import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity;
import com.ycwl.basic.model.pc.source.entity.SourceEntity;
import com.ycwl.basic.model.pc.task.entity.TaskEntity;
import com.ycwl.basic.model.pc.template.resp.TemplateRespVO;
import com.ycwl.basic.model.pc.video.entity.VideoEntity;
import com.ycwl.basic.pricing.dto.PriceCalculationRequest;
import com.ycwl.basic.pricing.dto.PriceCalculationResult;
import com.ycwl.basic.pricing.dto.ProductItem;
import com.ycwl.basic.pricing.enums.ProductType;
import com.ycwl.basic.pricing.service.IPriceCalculationService;
import com.ycwl.basic.profitsharing.biz.ProfitSharingBiz;
import com.ycwl.basic.repository.FaceRepository;
import com.ycwl.basic.repository.OrderRepository;
import com.ycwl.basic.repository.ScenicRepository;
import com.ycwl.basic.repository.SourceRepository;
import com.ycwl.basic.repository.TemplateRepository;
import com.ycwl.basic.repository.VideoRepository;
import com.ycwl.basic.repository.VideoTaskRepository;
import com.ycwl.basic.service.printer.PrinterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Optional;
@Component
public class OrderBiz {
@Autowired
private VideoMapper videoMapper;
@Autowired
private ScenicRepository scenicRepository;
@Autowired
private TemplateRepository templateRepository;
@Autowired
private OrderRepository orderRepository;
@Autowired
private FaceRepository faceRepository;
@Autowired
private SourceRepository sourceRepository;
@Autowired
private VideoRepository videoRepository;
@Autowired
private StatisticsMapper statisticsMapper;
@Autowired
private OrderMapper orderMapper;
@Autowired
private SourceMapper sourceMapper;
@Autowired
private ProfitSharingBiz profitSharingBiz;
@Autowired
private VideoTaskRepository videoTaskRepository;
@Autowired
private BrokerBiz brokerBiz;
@Autowired
private CouponBiz couponBiz;
@Autowired
@Lazy
private PrinterService printerService;
@Autowired
private IPriceCalculationService iPriceCalculationService;
public PriceObj queryPrice(Long scenicId, int goodsType, Long goodsId) {
PriceObj priceObj = new PriceObj();
priceObj.setGoodsType(goodsType);
priceObj.setGoodsId(goodsId);
ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(scenicId);
if (scenicConfig != null) {
if (Boolean.TRUE.equals(scenicConfig.getAllFree())) {
// 景区全免
priceObj.setFree(true);
priceObj.setPrice(BigDecimal.ZERO);
priceObj.setSlashPrice(BigDecimal.ZERO);
return priceObj;
}
}
switch (goodsType) {
case 0: // video
VideoEntity video = videoRepository.getVideo(goodsId);
if (video == null) {
return null;
}
TaskEntity task = videoTaskRepository.getTaskById(video.getTaskId());
if (task != null) {
priceObj.setFaceId(task.getFaceId());
}
TemplateRespVO template = templateRepository.getTemplate(video.getTemplateId());
if (template == null) {
return priceObj;
}
PriceCalculationRequest vlogCalculationRequest = new PriceCalculationRequest();
ProductItem vlogProductItem = new ProductItem();
vlogProductItem.setProductType(ProductType.VLOG_VIDEO);
vlogProductItem.setProductId(template.getId().toString());
vlogProductItem.setQuantity(videoTaskRepository.getTaskLensNum(video.getTaskId()));
vlogProductItem.setScenicId(scenicId.toString());
vlogCalculationRequest.setProducts(Collections.singletonList(vlogProductItem));
vlogCalculationRequest.setFaceId(priceObj.getFaceId());
vlogCalculationRequest.setPreviewOnly(true); // 仅查询价格,不实际使用优惠
PriceCalculationResult vlogCalculationResult = iPriceCalculationService.calculatePrice(vlogCalculationRequest);
priceObj.setPrice(vlogCalculationResult.getFinalAmount());
priceObj.setSlashPrice(vlogCalculationResult.getOriginalAmount());
priceObj.setFaceId(goodsId);
priceObj.setScenicId(video.getScenicId());
break;
case 1: // source
case 2: // source
FaceEntity face = faceRepository.getFace(goodsId);
PriceCalculationRequest calculationRequest = new PriceCalculationRequest();
ProductItem productItem = new ProductItem();
productItem.setProductType(goodsType == 1 ? ProductType.RECORDING_SET : ProductType.PHOTO_SET);
productItem.setProductId(scenicId.toString());
productItem.setPurchaseCount(1);
productItem.setScenicId(scenicId.toString());
calculationRequest.setProducts(Collections.singletonList(productItem));
if (face != null) {
calculationRequest.setUserId(face.getMemberId());
}
calculationRequest.setFaceId(goodsId);
calculationRequest.setPreviewOnly(true); // 仅查询价格,不实际使用优惠
PriceCalculationResult priceCalculationResult = iPriceCalculationService.calculatePrice(calculationRequest);
priceObj.setPrice(priceCalculationResult.getFinalAmount());
priceObj.setSlashPrice(priceCalculationResult.getOriginalAmount());
priceObj.setFaceId(goodsId);
break;
case 13:
PriceCalculationRequest aiCamCalculationRequest = new PriceCalculationRequest();
ProductItem aiCamProductItem = new ProductItem();
aiCamProductItem.setProductType(ProductType.AI_CAM_PHOTO_SET);
aiCamProductItem.setProductId(scenicId.toString());
aiCamProductItem.setPurchaseCount(1);
aiCamProductItem.setScenicId(scenicId.toString());
aiCamCalculationRequest.setProducts(Collections.singletonList(aiCamProductItem));
aiCamCalculationRequest.setPreviewOnly(true); // 仅查询价格,不实际使用优惠
PriceCalculationResult aiCamPriceCalculationResult = iPriceCalculationService.calculatePrice(aiCamCalculationRequest);
priceObj.setPrice(aiCamPriceCalculationResult.getFinalAmount());
priceObj.setSlashPrice(aiCamPriceCalculationResult.getOriginalAmount());
priceObj.setFaceId(goodsId);
priceObj.setScenicId(scenicId);
break;
}
return priceObj;
}
public OrderEntity hasTypeOrder(Long userId, Long faceId, Long scenicId, int orderType, Integer configId) {
OrderEntity orderEntity = orderMapper.queryTypeOrder(userId, faceId, scenicId, orderType, configId);
if (orderEntity == null) {
return null;
}
if (Integer.valueOf(1).equals(orderEntity.getStatus())) {
return orderEntity;
} else {
return null;
}
}
public IsBuyRespVO isBuy(Long scenicId, Long memberId, Long faceId, int goodsType, Long goodsId) {
IsBuyRespVO respVO = new IsBuyRespVO();
respVO.setGoodsType(goodsType);
respVO.setGoodsId(goodsId);
OrderEntity orderEntity = orderMapper.getUserBuyFaceItem(memberId, faceId, goodsType, goodsId);
if (orderEntity != null) {
respVO.setOrderId(orderEntity.getId());
respVO.setBuy(true);
respVO.setFree(false);
return respVO;
}
ScenicConfigManager scenicConfig = scenicRepository.getScenicConfigManager(scenicId);
if (Boolean.TRUE.equals(scenicConfig.getBoolean("all_free"))) {
// 景区全免
respVO.setFree(true);
respVO.setOrigPrice(BigDecimal.ZERO);
respVO.setSlashPrice(BigDecimal.ZERO);
return respVO;
}
// 未来模板一口价
if (goodsType == 0) {
// 视频,可以买断模板
VideoEntity video = videoRepository.getVideo(goodsId);
if (video != null && video.getTemplateId() != null) {
OrderEntity templateBuy = orderMapper.getUserBuyFaceItem(memberId, faceId, -1, video.getTemplateId());
if (templateBuy != null) {
respVO.setOrderId(templateBuy.getId());
respVO.setBuy(true);
respVO.setFree(false);
return respVO;
}
}
}
PriceObj priceObj = queryPrice(scenicId, goodsType, goodsId);
if (priceObj == null) {
return respVO;
}
respVO.setBuy(false);
respVO.setOrigPrice(priceObj.getPrice());
respVO.setSlashPrice(priceObj.getSlashPrice());
return respVO;
}
public void paidOrder(Long orderId) {
orderRepository.clearOrderCache(orderId); // 检查支付呢,还缓存
OrderEntity order = orderRepository.getOrder(orderId);
List<OrderItemEntity> orderItems = orderRepository.getOrderItems(orderId);
OrderEntity orderUpdate = new OrderEntity();
orderUpdate.setPayAt(new Date());
orderUpdate.setStatus(1);
orderRepository.updateOrder(orderId, orderUpdate);
orderItems.forEach(item -> {
switch (item.getGoodsType()) {
case -1: // vlog视频模板
videoRepository.setUserIsBuyTemplate(order.getMemberId(), item.getGoodsId(), order.getId(), order.getFaceId());
break;
case 0: // vlog视频
videoRepository.setUserIsBuyItem(order.getMemberId(), item.getGoodsId(), order.getId());
break;
case 1: // 视频原素材
case 2: // 照片原素材
case 13: // AI微单
sourceRepository.setUserIsBuyItem(order.getMemberId(), item.getGoodsType(), item.getGoodsId(), order.getId());
break;
case 3:
printerService.setUserIsBuyItem(order.getMemberId(), item.getGoodsId(), order.getId());
break;
}
});
orderRepository.clearOrderCache(orderId); // 更新完了,清理下
Integer couponRecordId = order.getCouponRecordId();
if (couponRecordId != null) {
couponBiz.userUseCoupon(order.getMemberId(), order.getFaceId(), couponRecordId, orderId);
}
StatisticsRecordAddReq statisticsRecordAddReq = new StatisticsRecordAddReq();
statisticsRecordAddReq.setMemberId(order.getMemberId());
Long enterType = statisticsMapper.getUserRecentEnterType(order.getMemberId(), order.getCreateAt());
if(!Long.valueOf(1014).equals(enterType)){//
statisticsRecordAddReq.setType(StatisticEnum.ON_SITE_PAYMENT.code);
}else {
statisticsRecordAddReq.setType(StatisticEnum.POST_PAYMENT.code);
}
statisticsRecordAddReq.setScenicId(order.getScenicId());
statisticsRecordAddReq.setMorphId(orderId);
statisticsMapper.addStatisticsRecord(statisticsRecordAddReq);
profitSharingBiz.processProfitSharing(order.getScenicId(), orderId, order.getPayPrice());
brokerBiz.processOrder(orderId);
}
public void cancelOrder(Long orderId) {
orderRepository.clearOrderCache(orderId); // 检查支付呢,还缓存
OrderEntity order = orderRepository.getOrder(orderId);
List<OrderItemEntity> orderItems = orderRepository.getOrderItems(orderId);
OrderEntity orderUpdate = new OrderEntity();
orderUpdate.setCancelAt(new Date());
orderUpdate.setStatus(9);
orderRepository.updateOrder(orderId, orderUpdate);
orderItems.forEach(item -> {
switch (item.getGoodsType()) {
case 0: // vlog视频
videoRepository.setUserNotBuyItem(order.getMemberId(), item.getGoodsId());
break;
case 1: // 视频原素材
case 2: // 照片原素材
sourceRepository.setUserNotBuyItem(order.getMemberId(), item.getGoodsType(), item.getGoodsId());
break;
}
});
orderRepository.clearOrderCache(orderId); // 更新完了,清理下
profitSharingBiz.revokeProfitSharing(order.getScenicId(), orderId, "订单被取消");
}
public void refundOrder(Long orderId) {
orderRepository.clearOrderCache(orderId);
OrderEntity order = orderRepository.getOrder(orderId);
List<OrderItemEntity> orderItems = orderRepository.getOrderItems(orderId);
OrderEntity orderUpdate = new OrderEntity();
orderUpdate.setRefundAt(new Date());
orderUpdate.setStatus(2);
orderUpdate.setRefundStatus(1);
orderRepository.updateOrder(orderId, orderUpdate);
orderItems.forEach(item -> {
switch (item.getGoodsType()) {
case 0: // vlog视频
videoRepository.setUserNotBuyItem(order.getMemberId(), item.getGoodsId());
break;
case 1: // 视频原素材
case 2: // 照片原素材
sourceRepository.setUserNotBuyItem(order.getMemberId(), item.getGoodsType(), item.getGoodsId());
break;
}
});
orderRepository.clearOrderCache(orderId); // 更新完了,清理下
profitSharingBiz.revokeProfitSharing(order.getScenicId(), orderId, "订单已退款");
}
/**
* 检查用户是否购买了指定商品,并额外校验订单的faceId是否匹配
* @param userId 用户ID
* @param faceId 人脸ID
* @param goodsType 商品类型
* @param goodsId 商品ID
* @return 是否已购买且faceId匹配
*/
public boolean checkUserBuyFaceItem(Long userId, Long faceId, int goodsType, Long goodsId) {
return orderRepository.checkUserBuyFaceItem(userId, faceId, goodsType, goodsId);
}
}