zhangchen 3 mesiacov pred
rodič
commit
e2a86c3433

+ 21 - 0
alien-store/src/main/java/shop/alien/store/controller/StoreInfoController.java

@@ -917,6 +917,27 @@ public class StoreInfoController {
 
     }
 
+    @ApiOperation(value = "根据店铺ID获取推荐店铺列表(用户端)")
+    @GetMapping("/getRecommendedStoresByStoreId")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "storeId", value = "店铺ID", dataType = "Integer", paramType = "query", required = true)
+    })
+    public R<List<StoreInfoVo>> getRecommendedStoresByStoreId(@RequestParam Integer storeId) {
+        log.info("StoreInfoController.getRecommendedStoresByStoreId?storeId={}", storeId);
+        try {
+            if (storeId == null || storeId <= 0) {
+                log.warn("获取推荐店铺列表失败,店铺ID无效:{}", storeId);
+                return R.fail("店铺ID不能为空且必须大于0");
+            }
+            List<StoreInfoVo> result = storeInfoService.getRecommendedStoresByStoreId(storeId);
+            log.info("获取推荐店铺列表成功,storeId={},返回店铺数量:{}", storeId, result != null ? result.size() : 0);
+            return R.data(result);
+        } catch (Exception e) {
+            log.error("获取推荐店铺列表异常,storeId={},异常信息:{}", storeId, e.getMessage(), e);
+            return R.fail("获取推荐店铺列表失败:" + e.getMessage());
+        }
+    }
+
     @ApiOperation(value = "AI服务-门头识别")
     @ApiOperationSupport(order = 16)
     @ApiImplicitParams({

+ 11 - 0
alien-store/src/main/java/shop/alien/store/service/StoreInfoService.java

@@ -355,6 +355,17 @@ public interface StoreInfoService extends IService<StoreInfo> {
      */
     List<StoreInfoVo> getMoreRecommendedStores(Double lon , Double lat, String businessSection, String businessTypes, String businessClassify);
 
+    /**
+     * 根据店铺ID获取推荐店铺列表(用户端)
+     * <p>
+     * 只使用store_id查询,不包含其他筛选条件(经营板块、经营分类、分类、经纬度等)
+     * </p>
+     *
+     * @param storeId 店铺ID,必填,必须大于0
+     * @return 推荐店铺列表
+     */
+    List<StoreInfoVo> getRecommendedStoresByStoreId(Integer storeId);
+
 
     /**
      * 根据门店及图片地址查询最新OCR识别数据

+ 175 - 0
alien-store/src/main/java/shop/alien/store/service/impl/StoreInfoServiceImpl.java

@@ -4834,6 +4834,181 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
         // SQL已经实现了距离过滤和排序,直接返回结果
         return storeInfoVoList;
     }
+
+    /**
+     * 根据店铺ID获取推荐店铺列表(用户端)
+     * <p>
+     * 只使用store_id查询,不包含其他筛选条件(经营板块、经营分类、分类、经纬度等)
+     * </p>
+     *
+     * @param storeId 店铺ID,必填,必须大于0
+     * @return 推荐店铺列表
+     */
+    @Override
+    public List<StoreInfoVo> getRecommendedStoresByStoreId(Integer storeId) {
+        log.info("根据店铺ID获取推荐店铺列表,storeId={}", storeId);
+        
+        // 参数校验
+        if (storeId == null || storeId <= 0) {
+            log.warn("获取推荐店铺列表失败,店铺ID无效:{}", storeId);
+            return Collections.emptyList();
+        }
+        
+        try {
+            QueryWrapper<StoreInfoVo> queryWrapper = new QueryWrapper<>();
+            // 基础条件:未删除、已启用
+            queryWrapper.eq("a.delete_flag", 0)
+                    .eq("b.delete_flag", 0)
+                    .ne("a.business_status", 99) // 过滤永久关门的店铺
+                    .ne("a.store_status", 0); // 过滤禁用的店铺
+            
+            // 排除当前店铺
+            queryWrapper.ne("a.id", storeId);
+            
+            // 过期时间判断
+            Date currentDate = new Date();
+            // 如果 expiration_time 为空则不做过期判断;如果不为空则要求大于当前时间
+            queryWrapper.and(w -> w.isNull("a.expiration_time")
+                    .or()
+                    .gt("a.expiration_time", currentDate));
+            
+            // 如果 food_licence_expiration_time 为空则不做过期判断;如果不为空则要求大于当前时间
+            queryWrapper.and(w -> w.isNull("a.food_licence_expiration_time")
+                    .or()
+                    .gt("a.food_licence_expiration_time", currentDate));
+            
+            // 查询店铺列表(限制20条)
+            queryWrapper.last("limit 20");
+            
+            List<StoreInfoVo> storeInfoVoList = storeInfoMapper.getStoreInfoVoList(queryWrapper);
+            
+            if (CollectionUtils.isEmpty(storeInfoVoList)) {
+                return Collections.emptyList();
+            }
+            
+            // 提前查询所有需要的字典数据
+            List<StoreInfoVo> collect = storeInfoVoList.stream()
+                    .filter(record -> StringUtils.isNotEmpty(record.getStoreType()))
+                    .collect(Collectors.toList());
+            Set<String> allTypes = collect.stream()
+                    .map(StoreInfoVo::getStoreType)
+                    .flatMap(type -> Arrays.stream(type.split(",")))
+                    .collect(Collectors.toSet());
+            
+            List<StoreDictionary> storeDictionaries = storeDictionaryMapper.selectList(
+                    new LambdaQueryWrapper<StoreDictionary>()
+                            .eq(StoreDictionary::getTypeName, "storeType")
+                            .isNull(StoreDictionary::getParentId)
+                            .in(!allTypes.isEmpty(), StoreDictionary::getDictId, allTypes));
+            Map<String, String> typeMap = storeDictionaries.stream()
+                    .collect(Collectors.toMap(StoreDictionary::getDictId, StoreDictionary::getDictDetail));
+            
+            // 计算平均分和评价
+            Map<String, List<Map<String, Object>>> avgScoreMap = new HashMap<>();
+            Map<Integer, List<StoreComment>> commentMap = new HashMap<>();
+            
+            // 注意:需要将store_id转换为String类型,与后续containsKey判断保持一致
+            avgScoreMap = storeEvaluationMapper.allStoreAvgScore().stream()
+                    .collect(Collectors.groupingBy(o -> o.get("store_id").toString()));
+            List<StoreComment> storeComments = storeCommentMapper.selectList(
+                    new QueryWrapper<StoreComment>()
+                            .eq("business_type", "5")
+                            .eq("delete_flag", 0));
+            commentMap = storeComments.stream()
+                    .filter(comment -> comment.getStoreId() != null)
+                    .collect(Collectors.groupingBy(StoreComment::getStoreId));
+            
+            // 查询入口头图
+            List<Integer> storeIds = storeInfoVoList.stream()
+                    .map(StoreInfoVo::getId)
+                    .collect(Collectors.toList());
+            
+            List<StoreImg> storeImgList = storeImgMapper.selectList(
+                    new QueryWrapper<StoreImg>()
+                            .in("store_id", storeIds)
+                            .eq("img_type", 1));
+            Map<Integer, List<StoreImg>> storeCollect = storeImgList.stream()
+                    .collect(Collectors.groupingBy(StoreImg::getStoreId));
+            
+            // 处理每个店铺的数据
+            for (StoreInfoVo record : storeInfoVoList) {
+                // 处理类型
+                if (StringUtils.isNotEmpty(record.getStoreType())) {
+                    String[] types = record.getStoreType().split(",");
+                    List<String> typeDetails = Arrays.stream(types)
+                            .map(typeMap::get)
+                            .filter(Objects::nonNull)
+                            .collect(Collectors.toList());
+                    record.setStoreTypeStr(String.join(",", typeDetails));
+                    record.setStoreTypeList(Arrays.asList(types));
+                }
+                
+                // 加入头图
+                if (!CollectionUtils.isEmpty(storeCollect) && storeCollect.containsKey(record.getId())) {
+                    List<StoreImg> storeImgs = storeCollect.get(record.getId());
+                    if (!CollectionUtils.isEmpty(storeImgs)) {
+                        record.setEntranceImage(storeImgs.get(0).getImgUrl());
+                    }
+                }
+                
+                // 处理经纬度
+                if (StringUtils.isNotEmpty(record.getStorePosition())) {
+                    String[] split = record.getStorePosition().split(",");
+                    if (split.length >= 2) {
+                        record.setStorePositionLongitude(split[0]);
+                        record.setStorePositionLatitude(split[1]);
+                    }
+                }
+                
+                // 处理到期状态
+                Date expirationTime = record.getExpirationTime();
+                if (expirationTime != null) {
+                    Calendar now = Calendar.getInstance();
+                    Date nowCurrentDate = now.getTime();
+                    now.add(Calendar.DAY_OF_YEAR, 30);
+                    Date thirtyDaysLater = now.getTime();
+                    
+                    if (expirationTime.after(currentDate)) {
+                        record.setExpiredState("0");
+                        if ((expirationTime.after(nowCurrentDate) || expirationTime.equals(nowCurrentDate))
+                                && expirationTime.before(thirtyDaysLater)) {
+                            record.setExpiredState("1");
+                        }
+                    } else {
+                        record.setExpiredState("2");
+                    }
+                    
+                    LocalDate nowLocal = LocalDate.now();
+                    LocalDate expDate = expirationTime.toInstant()
+                            .atZone(ZoneId.systemDefault())
+                            .toLocalDate();
+                    long daysToExpire = ChronoUnit.DAYS.between(nowLocal, expDate);
+                    record.setDaysToExpire(daysToExpire);
+                }
+                
+                // 设置店铺得分
+                if (!CollectionUtils.isEmpty(avgScoreMap) && avgScoreMap.containsKey(String.valueOf(record.getId()))) {
+                    record.setAvgScore(String.valueOf(avgScoreMap.get(String.valueOf(record.getId())).get(0).get("avg_score")));
+                } else {
+                    record.setAvgScore("0");
+                }
+                
+                // 设置总评论数
+                if (!CollectionUtils.isEmpty(commentMap) && commentMap.containsKey(record.getId())) {
+                    record.setTotalNum(String.valueOf(commentMap.get(record.getId()).size()));
+                } else {
+                    record.setTotalNum("0");
+                }
+            }
+            
+            log.info("根据店铺ID获取推荐店铺列表成功,storeId={},返回店铺数量:{}", storeId, storeInfoVoList.size());
+            return storeInfoVoList;
+        } catch (Exception e) {
+            log.error("根据店铺ID获取推荐店铺列表异常,storeId={},异常信息:{}", storeId, e.getMessage(), e);
+            throw new RuntimeException("获取推荐店铺列表失败:" + e.getMessage(), e);
+        }
+    }
+
     @Override
     public int uploadEntertainmentLicence(StoreImg storeImg) {
         storeImgMapper.delete(new LambdaQueryWrapper<StoreImg>().eq(StoreImg::getImgType, 24).eq(StoreImg::getStoreId, storeImg.getStoreId()));