feat(order): 增加faceId校验的订单购买检查功能

- 新增checkUserBuyFaceItem方法,支持校验用户购买商品时的人脸ID匹配
- 修改PriceBiz中商品类型设置,从13改为5
- 更新FaceServiceImpl中的购买检查逻辑,使用新的带faceId校验的方法
- 调整OrderServiceImpl中订单项的goodsType和goodsId设置逻辑
- 移除旧的checkUserBuyItem方法及相关缓存逻辑
- 新增ORDER_USER_FACE_TYPE_BUY_ITEM_CACHE_KEY缓存键定义
This commit is contained in:
2025-12-13 19:00:25 +08:00
parent dbee1d9709
commit 3f6f1508c5
5 changed files with 54 additions and 47 deletions

View File

@@ -314,10 +314,14 @@ public class OrderBiz {
} }
/** /**
* 检查用户是否购买了指定商品 * 检查用户是否购买了指定商品,并额外校验订单的faceId是否匹配
* 提供给PriceBiz使用,避免循环调用 * @param userId 用户ID
* @param faceId 人脸ID
* @param goodsType 商品类型
* @param goodsId 商品ID
* @return 是否已购买且faceId匹配
*/ */
public boolean checkUserBuyItem(Long userId, int goodsType, Long goodsId) { public boolean checkUserBuyFaceItem(Long userId, Long faceId, int goodsType, Long goodsId) {
return orderRepository.checkUserBuyItem(userId, goodsType, goodsId); return orderRepository.checkUserBuyFaceItem(userId, faceId, goodsType, goodsId);
} }
} }

View File

@@ -81,7 +81,7 @@ public class PriceBiz {
GoodsListRespVO goods = new GoodsListRespVO(); GoodsListRespVO goods = new GoodsListRespVO();
goods.setGoodsId(puzzleTemplate.getId()); goods.setGoodsId(puzzleTemplate.getId());
goods.setGoodsName(puzzleTemplate.getName()); goods.setGoodsName(puzzleTemplate.getName());
goods.setGoodsType(13); goods.setGoodsType(5);
goodsList.add(goods); goodsList.add(goods);
}); });
return goodsList; return goodsList;
@@ -280,7 +280,7 @@ public class PriceBiz {
allContentsPurchased = false; allContentsPurchased = false;
break; break;
} }
boolean hasPurchasedTemplate = orderBiz.checkUserBuyItem(userId, -1, videoEntities.getFirst().getVideoId()); boolean hasPurchasedTemplate = orderBiz.checkUserBuyFaceItem(userId, faceId, -1, videoEntities.getFirst().getVideoId());
if (!hasPurchasedTemplate) { if (!hasPurchasedTemplate) {
allContentsPurchased = false; allContentsPurchased = false;
break; break;
@@ -292,7 +292,7 @@ public class PriceBiz {
if (scenicConfig != null) { if (scenicConfig != null) {
// 检查录像集 // 检查录像集
if (!Boolean.TRUE.equals(scenicConfig.getDisableSourceVideo())) { if (!Boolean.TRUE.equals(scenicConfig.getDisableSourceVideo())) {
boolean hasPurchasedRecording = orderBiz.checkUserBuyItem(userId, 1, faceId); boolean hasPurchasedRecording = orderBiz.checkUserBuyFaceItem(userId, faceId, 1, faceId);
if (!hasPurchasedRecording) { if (!hasPurchasedRecording) {
allContentsPurchased = false; allContentsPurchased = false;
} }
@@ -300,7 +300,7 @@ public class PriceBiz {
// 检查照片集 // 检查照片集
if (allContentsPurchased && !Boolean.TRUE.equals(scenicConfig.getDisableSourceImage())) { if (allContentsPurchased && !Boolean.TRUE.equals(scenicConfig.getDisableSourceImage())) {
boolean hasPurchasedPhoto = orderBiz.checkUserBuyItem(userId, 2, faceId); boolean hasPurchasedPhoto = orderBiz.checkUserBuyFaceItem(userId, faceId, 2, faceId);
if (!hasPurchasedPhoto) { if (!hasPurchasedPhoto) {
allContentsPurchased = false; allContentsPurchased = false;
} }

View File

@@ -23,7 +23,7 @@ public class OrderRepository {
public static final String ORDER_CACHE_KEY = "order:%s"; public static final String ORDER_CACHE_KEY = "order:%s";
public static final String ORDER_ITEMS_CACHE_KEY = "order:%s:items"; public static final String ORDER_ITEMS_CACHE_KEY = "order:%s:items";
public static final String ORDER_ITEM_CACHE_KEY = "order:item:%s"; public static final String ORDER_ITEM_CACHE_KEY = "order:item:%s";
public static final String ORDER_USER_TYPE_BUY_ITEM_CACHE_KEY = "order:user:%s:type:%s:id:%s"; public static final String ORDER_USER_FACE_TYPE_BUY_ITEM_CACHE_KEY = "order:user:%s:face:%s:type:%s:id:%s";
public OrderEntity getOrder(Long orderId) { public OrderEntity getOrder(Long orderId) {
if (redisTemplate.hasKey(String.format(ORDER_CACHE_KEY, orderId))) { if (redisTemplate.hasKey(String.format(ORDER_CACHE_KEY, orderId))) {
@@ -62,40 +62,12 @@ public class OrderRepository {
return orderItemEntity; return orderItemEntity;
} }
public boolean checkUserBuyItem(Long userId, int goodsType, Long goodsId) {
synchronized (this) {
if (redisTemplate.hasKey(String.format(ORDER_USER_TYPE_BUY_ITEM_CACHE_KEY, userId, goodsType, goodsId))) {
return "1".equals(redisTemplate.opsForValue().get(String.format(ORDER_USER_TYPE_BUY_ITEM_CACHE_KEY, userId, goodsType, goodsId)));
}
OrderEntity orderEntity = orderMapper.getUserBuyItem(userId, goodsType, goodsId);
if (orderEntity == null) {
redisTemplate.opsForValue().set(String.format(ORDER_USER_TYPE_BUY_ITEM_CACHE_KEY, userId, goodsType, goodsId), "0", 60, TimeUnit.SECONDS);
return false;
}
if (Integer.valueOf(1).equals(orderEntity.getStatus())) {
redisTemplate.opsForValue().set(String.format(ORDER_USER_TYPE_BUY_ITEM_CACHE_KEY, userId, goodsType, goodsId), "1");
return true;
} else {
redisTemplate.opsForValue().set(String.format(ORDER_USER_TYPE_BUY_ITEM_CACHE_KEY, userId, goodsType, goodsId), "0", 60, TimeUnit.SECONDS);
return false;
}
}
}
public OrderEntity getUserBuyItem(Long userId, int goodsType, Long goodsId) {
return orderMapper.getUserBuyItem(userId, goodsType, goodsId);
}
public void clearUserBuyItemCache(Long userId, int goodsType, Long goodsId) {
redisTemplate.delete(String.format(ORDER_USER_TYPE_BUY_ITEM_CACHE_KEY, userId, goodsType, goodsId));
}
public void clearOrderCache(Long orderId) { public void clearOrderCache(Long orderId) {
OrderEntity order = getOrder(orderId); OrderEntity order = getOrder(orderId);
redisTemplate.delete(String.format(ORDER_CACHE_KEY, orderId)); redisTemplate.delete(String.format(ORDER_CACHE_KEY, orderId));
getOrderItems(orderId).forEach(orderItem -> { getOrderItems(orderId).forEach(orderItem -> {
redisTemplate.delete(String.format(ORDER_ITEM_CACHE_KEY, orderItem.getId())); redisTemplate.delete(String.format(ORDER_ITEM_CACHE_KEY, orderItem.getId()));
clearUserBuyItemCache(order.getMemberId(), orderItem.getGoodsType(), orderItem.getGoodsId()); clearUserBuyFaceItemCache(order.getMemberId(), order.getFaceId(), orderItem.getGoodsType(), orderItem.getGoodsId());
}); });
redisTemplate.delete(String.format(ORDER_ITEMS_CACHE_KEY, orderId)); redisTemplate.delete(String.format(ORDER_ITEMS_CACHE_KEY, orderId));
} }
@@ -105,4 +77,37 @@ public class OrderRepository {
orderMapper.updateOrder(updateEntity); orderMapper.updateOrder(updateEntity);
clearOrderCache(orderId); clearOrderCache(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) {
synchronized (this) {
String cacheKey = String.format(ORDER_USER_FACE_TYPE_BUY_ITEM_CACHE_KEY, userId, faceId, goodsType, goodsId);
if (redisTemplate.hasKey(cacheKey)) {
return "1".equals(redisTemplate.opsForValue().get(cacheKey));
}
OrderEntity orderEntity = orderMapper.getUserBuyFaceItem(userId, faceId, goodsType, goodsId);
if (orderEntity == null) {
redisTemplate.opsForValue().set(cacheKey, "0", 60, TimeUnit.SECONDS);
return false;
}
if (Integer.valueOf(1).equals(orderEntity.getStatus())) {
redisTemplate.opsForValue().set(cacheKey, "1");
return true;
} else {
redisTemplate.opsForValue().set(cacheKey, "0", 60, TimeUnit.SECONDS);
return false;
}
}
}
public void clearUserBuyFaceItemCache(Long userId, Long faceId, int goodsType, Long goodsId) {
redisTemplate.delete(String.format(ORDER_USER_FACE_TYPE_BUY_ITEM_CACHE_KEY, userId, faceId, goodsType, goodsId));
}
} }

View File

@@ -473,9 +473,9 @@ public class FaceServiceImpl implements FaceService {
contentPageVO.setLockType(1); contentPageVO.setLockType(1);
} }
} }
boolean buy = orderBiz.checkUserBuyItem(userId, contentPageVO.getGoodsType(), contentPageVO.getContentId()); boolean buy = orderBiz.checkUserBuyFaceItem(userId, faceId, contentPageVO.getGoodsType(), contentPageVO.getContentId());
if (!buy) { if (!buy) {
buy = orderBiz.checkUserBuyItem(userId, -1, contentPageVO.getTemplateId()); buy = orderBiz.checkUserBuyFaceItem(userId, faceId, -1, contentPageVO.getTemplateId());
} }
if (buy) { if (buy) {
contentPageVO.setIsBuy(1); contentPageVO.setIsBuy(1);

View File

@@ -916,15 +916,13 @@ public class OrderServiceImpl implements OrderService {
List<OrderItemEntity> orderItems = goodsList.stream().map(goods -> { List<OrderItemEntity> orderItems = goodsList.stream().map(goods -> {
OrderItemEntity orderItem = new OrderItemEntity(); OrderItemEntity orderItem = new OrderItemEntity();
orderItem.setOrderId(orderId); orderItem.setOrderId(orderId);
if (Long.valueOf(1L).equals(goods.getGoodsId())) {
orderItem.setGoodsId(batchOrderReqVO.getFaceId());
orderItem.setGoodsType(1);
} else if (Long.valueOf(2L).equals(goods.getGoodsId())) {
orderItem.setGoodsId(batchOrderReqVO.getFaceId());
orderItem.setGoodsType(2);
} else {
// templateId
orderItem.setGoodsId(goods.getGoodsId()); orderItem.setGoodsId(goods.getGoodsId());
orderItem.setGoodsType(goods.getGoodsType());
if (Integer.valueOf(1).equals(goods.getGoodsType())) {
orderItem.setGoodsId(batchOrderReqVO.getFaceId());
} else if (Integer.valueOf(2).equals(goods.getGoodsType())) {
orderItem.setGoodsId(batchOrderReqVO.getFaceId());
} else if (Integer.valueOf(0).equals(goods.getGoodsType())) {
orderItem.setGoodsType(-1); orderItem.setGoodsType(-1);
} }
return orderItem; return orderItem;