You've already forked FrameTour-BE
feat(service): 优化商品查询逻辑并新增分组查询接口
- 在 SourceMapper 中新增 queryGroupedByFaceAndType 方法,支持按 faceId 和 type 分组查询 - 调整 orderBiz.isBuy 方法的参数顺序,统一调用格式 - 修改 GoodsServiceImpl 中源素材查询逻辑,使用新分组方法减少循环嵌套 - 简化源素材去重及过滤禁用类型的处理流程 - 提前获取景区配置信息,避免重复查询 - 优化代码结构,提升可读性和维护性
This commit is contained in:
@@ -67,6 +67,13 @@ public interface SourceMapper {
|
||||
|
||||
List<SourceRespVO> queryByRelation(SourceReqQuery sourceReqQuery);
|
||||
|
||||
/**
|
||||
* 按 faceId 和 type 分组查询源素材,每组返回最新的一条记录
|
||||
* @param sourceReqQuery 查询参数
|
||||
* @return 分组后的素材列表
|
||||
*/
|
||||
List<SourceRespVO> queryGroupedByFaceAndType(SourceReqQuery sourceReqQuery);
|
||||
|
||||
SourceEntity querySameVideo(Long faceSampleId, Long deviceId);
|
||||
|
||||
int hasRelationTo(Long memberId, Long sourceId, int type);
|
||||
|
||||
@@ -310,7 +310,7 @@ public class GoodsServiceImpl implements GoodsService {
|
||||
goodsDetailVO.setFaceId(entity.getFaceId());
|
||||
goodsDetailVO.setIsBuy(entity.getIsBuy());
|
||||
if (Integer.valueOf(0).equals(entity.getIsBuy())) {
|
||||
IsBuyRespVO buy = orderBiz.isBuy(userId, videoRespVO.getScenicId(), 0, videoId);
|
||||
IsBuyRespVO buy = orderBiz.isBuy(videoRespVO.getScenicId(), userId, entity.getFaceId(), 0, videoId);
|
||||
if (!buy.isBuy()) {
|
||||
PriceObj priceObj = orderBiz.queryPrice(videoRespVO.getScenicId(), 0, videoId);
|
||||
if (priceObj.isFree()) {
|
||||
@@ -584,7 +584,7 @@ public class GoodsServiceImpl implements GoodsService {
|
||||
goodsUrlVO.setCreateTime(source.getCreateTime());
|
||||
return goodsUrlVO;
|
||||
}).collect(Collectors.toList());
|
||||
IsBuyRespVO isBuy = orderBiz.isBuy(face.getMemberId(), face.getScenicId(), query.getSourceType(), face.getId());
|
||||
IsBuyRespVO isBuy = orderBiz.isBuy(face.getScenicId(), face.getMemberId(), face.getId(), query.getSourceType(), face.getId());
|
||||
if (!isBuy.isBuy()) {
|
||||
ScenicConfigEntity scenicConfig = scenicRepository.getScenicConfig(face.getScenicId());
|
||||
if (scenicConfig != null && ((scenicConfig.getAntiScreenRecordType() & 2) == 0)) {
|
||||
@@ -676,7 +676,7 @@ public class GoodsServiceImpl implements GoodsService {
|
||||
}
|
||||
return true;
|
||||
}).count();
|
||||
IsBuyRespVO isBuy = orderBiz.isBuy(face.getMemberId(), face.getScenicId(), query.getSourceType(), face.getId());
|
||||
IsBuyRespVO isBuy = orderBiz.isBuy(face.getScenicId(), face.getMemberId(), face.getId(), query.getSourceType(), face.getId());
|
||||
if (count > 0) {
|
||||
if (!isBuy.isBuy()) {
|
||||
return Collections.emptyList();
|
||||
@@ -842,17 +842,14 @@ public class GoodsServiceImpl implements GoodsService {
|
||||
return ApiResponse.success(Collections.emptyList());
|
||||
}
|
||||
|
||||
// 获取景区配置
|
||||
ScenicConfigManager scenicConfig = scenicRepository.getScenicConfigManager(scenicId);
|
||||
|
||||
// 使用 LinkedHashMap 按 goodsType-goodsId 去重
|
||||
Map<String, GoodsPageVO> goodsMap = new LinkedHashMap<>();
|
||||
|
||||
// 循环查询每个 faceId 的商品
|
||||
for (Long faceId : faceIds) {
|
||||
// 构造查询参数
|
||||
GoodsReqQuery query = new GoodsReqQuery();
|
||||
query.setFaceId(faceId);
|
||||
query.setIsBuy(isBuy);
|
||||
query.setScenicId(scenicId);
|
||||
|
||||
// 查询成片 vlog (goodsType = 0)
|
||||
VideoReqQuery videoReqQuery = new VideoReqQuery();
|
||||
videoReqQuery.setScenicId(scenicId);
|
||||
@@ -880,55 +877,52 @@ public class GoodsServiceImpl implements GoodsService {
|
||||
goodsMap.put(key, goodsPageVO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 查询源素材 (goodsType = 1/2)
|
||||
SourceReqQuery sourceReqQuery = new SourceReqQuery();
|
||||
sourceReqQuery.setScenicId(scenicId);
|
||||
sourceReqQuery.setIsBuy(isBuy);
|
||||
sourceReqQuery.setFaceId(faceId);
|
||||
// 查询源素材 (goodsType = 1/2) - 使用新的 GROUP BY 方法
|
||||
SourceReqQuery sourceReqQuery = new SourceReqQuery();
|
||||
sourceReqQuery.setScenicId(scenicId);
|
||||
sourceReqQuery.setIsBuy(isBuy);
|
||||
sourceReqQuery.setFaceIds(faceIds);
|
||||
|
||||
List<SourceRespVO> sourceList = sourceMapper.queryByRelation(sourceReqQuery);
|
||||
ScenicConfigManager scenicConfig = scenicRepository.getScenicConfigManager(scenicId);
|
||||
// 使用 queryGroupedByFaceAndType 方法,数据库已经按 faceId+type 分组
|
||||
List<SourceRespVO> sourceList = sourceMapper.queryGroupedByFaceAndType(sourceReqQuery);
|
||||
|
||||
// 按 faceId 和 type 分组处理
|
||||
sourceList.stream()
|
||||
.collect(Collectors.groupingBy(SourceRespVO::getFaceId))
|
||||
.forEach((sourceFaceId, goods) -> {
|
||||
goods.stream()
|
||||
.collect(Collectors.groupingBy(SourceRespVO::getType))
|
||||
.forEach((type, sourcesByType) -> {
|
||||
// 根据景区配置过滤禁用的素材类型
|
||||
boolean isDisabled = false;
|
||||
if (Integer.valueOf(1).equals(type)) {
|
||||
isDisabled = Boolean.TRUE.equals(scenicConfig.getBoolean("disable_source_video"));
|
||||
} else if (Integer.valueOf(2).equals(type)) {
|
||||
isDisabled = Boolean.TRUE.equals(scenicConfig.getBoolean("disable_source_image"));
|
||||
}
|
||||
// 遍历分组后的结果,每个 faceId+type 组合只有一条记录
|
||||
for (SourceRespVO source : sourceList) {
|
||||
Integer type = source.getType();
|
||||
Long sourceFaceId = source.getFaceId();
|
||||
|
||||
if (!isDisabled) {
|
||||
String key = type + "-" + sourceFaceId; // goodsType=type, goodsId=faceId(源素材用faceId作为ID)
|
||||
if (!goodsMap.containsKey(key)) {
|
||||
GoodsPageVO goodsPageVO = new GoodsPageVO();
|
||||
goodsPageVO.setFaceId(sourceFaceId);
|
||||
goodsPageVO.setGoodsType(type);
|
||||
if (type == 1) {
|
||||
goodsPageVO.setGoodsName("录像集");
|
||||
goodsPageVO.setTemplateCoverUrl(scenicConfig.getString("video_cover_url"));
|
||||
} else if (type == 2) {
|
||||
goodsPageVO.setGoodsName("照片集");
|
||||
goodsPageVO.setTemplateCoverUrl(scenicConfig.getString("photo_cover_url"));
|
||||
} else {
|
||||
goodsPageVO.setGoodsName("未知商品");
|
||||
}
|
||||
if (StringUtils.isBlank(goodsPageVO.getTemplateCoverUrl())) {
|
||||
goodsPageVO.setTemplateCoverUrl(sourcesByType.getFirst().getUrl());
|
||||
}
|
||||
goodsPageVO.setScenicId(scenicId);
|
||||
goodsMap.put(key, goodsPageVO);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
// 根据景区配置过滤禁用的素材类型
|
||||
boolean isDisabled = false;
|
||||
if (Integer.valueOf(1).equals(type)) {
|
||||
isDisabled = Boolean.TRUE.equals(scenicConfig.getBoolean("disable_source_video"));
|
||||
} else if (Integer.valueOf(2).equals(type)) {
|
||||
isDisabled = Boolean.TRUE.equals(scenicConfig.getBoolean("disable_source_image"));
|
||||
}
|
||||
|
||||
if (!isDisabled) {
|
||||
String key = type + "-" + sourceFaceId; // goodsType=type, goodsId=faceId(源素材用faceId作为ID)
|
||||
if (!goodsMap.containsKey(key)) {
|
||||
GoodsPageVO goodsPageVO = new GoodsPageVO();
|
||||
goodsPageVO.setFaceId(sourceFaceId);
|
||||
goodsPageVO.setGoodsType(type);
|
||||
if (type == 1) {
|
||||
goodsPageVO.setGoodsName("录像集");
|
||||
goodsPageVO.setTemplateCoverUrl(scenicConfig.getString("video_cover_url"));
|
||||
} else if (type == 2) {
|
||||
goodsPageVO.setGoodsName("照片集");
|
||||
goodsPageVO.setTemplateCoverUrl(scenicConfig.getString("photo_cover_url"));
|
||||
} else {
|
||||
goodsPageVO.setGoodsName("未知商品");
|
||||
}
|
||||
if (StringUtils.isBlank(goodsPageVO.getTemplateCoverUrl())) {
|
||||
goodsPageVO.setTemplateCoverUrl(source.getUrl());
|
||||
}
|
||||
goodsPageVO.setScenicId(scenicId);
|
||||
goodsMap.put(key, goodsPageVO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 返回去重后的商品列表
|
||||
|
||||
Reference in New Issue
Block a user