浏览代码

点赞修改

zhangchen 4 月之前
父节点
当前提交
d13ee9467c

+ 22 - 0
alien-entity/src/main/java/shop/alien/mapper/StoreInfoMapper.java

@@ -130,4 +130,26 @@ public interface StoreInfoMapper extends BaseMapper<StoreInfo> {
             "from store_info where id = #{storeId}"
             )
     Double getStoreDistance(@Param("position") String position,@Param("storeId") Integer storeId);
+
+    /**
+     * 更多推荐(用户端)
+     *
+     * @param queryWrapper 查询条件
+     * @return List<StoreInfoVo>
+     */
+    @Select("select a.*, img.img_url entranceImage,img1.img_url foodLicenceImageUrl,b.name store_contact, b.phone store_phone, b.id_card idCard, b.password, c.dict_detail store_status_str, d.dict_detail business_status_str, e.dict_detail store_type_str,  " +
+            "( " +
+            " select ifnull(round(avg(score), 1), 0) " +
+            " from store_evaluation eval " +
+            " where eval.store_id = a.id and eval.delete_flag = 0 " +
+            ") score " +
+            "from store_info a " +
+            "left join store_user b on a.id = b.store_id and a.delete_flag = 0 and b.delete_flag = 0 " +
+            "left join store_img img on img.store_id = a.id and img.img_type = 1 and img.delete_flag = 0 " +
+            "left join store_img img1 on img1.store_id = a.id and img1.img_type = 24 and img1.delete_flag = 0 " +
+            "left join store_dictionary c on a.store_status = c.dict_id and c.type_name = 'storeState' and c.delete_flag = 0 " +
+            "left join store_dictionary d on a.business_status = d.dict_id and d.type_name = 'businessStatus' and d.delete_flag = 0 " +
+            "left join store_dictionary e on e.type_name = 'storeType' and e.dict_id = a.store_type and e.delete_flag = 0 " +
+            "${ew.customSqlSegment}")
+    List<StoreInfoVo> getMoreRecommendedStores(@Param(Constants.WRAPPER) QueryWrapper<StoreInfoVo> queryWrapper);
 }

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

@@ -754,4 +754,18 @@ public class StoreInfoController {
         return R.data(list);
     }
 
+
+    @ApiOperation(value = "更多推荐(用户端)")
+    @GetMapping("/getMoreRecommendedStores")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "lon", value = "经度", dataType = "double", paramType = "query", required = true),
+            @ApiImplicitParam(name = "lat", value = "纬度", dataType = "double", paramType = "query", required = true),
+            @ApiImplicitParam(name = "subcategory", value = "二级分类", dataType = "int", paramType = "query"),
+            @ApiImplicitParam(name = "threeLevelClassification", value = "三级分类", dataType = "int", paramType = "query")
+    })
+    public R<List<StoreInfoVo>> getMoreRecommendedStores(Double lon , Double lat, int subcategory, int threeLevelClassification) {
+        log.info("StoreInfoController.getMoreRecommendedStores?lon={},lat={},subcategory={},threeLevelClassification={}", lon,lat, subcategory, threeLevelClassification);
+        return R.data(storeInfoService.getMoreRecommendedStores(lon,lat, subcategory, threeLevelClassification));
+
+    }
 }

+ 3 - 0
alien-store/src/main/java/shop/alien/store/service/LifeCommentService.java

@@ -62,6 +62,9 @@ public class LifeCommentService {
             lifeLikeRecord.setDianzanId(userId);
             lifeLikeRecord.setType(type);
             lifeLikeRecordMapper.insert(lifeLikeRecord);
+        }  else {
+            //点赞过了,不点赞了
+            return 0;
         }
         if ("1".equals(type)) {
             LambdaUpdateWrapper<StoreComment> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();

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

@@ -279,4 +279,13 @@ public interface StoreInfoService extends IService<StoreInfo> {
      *
      */
     int foodLicenceType(int id);
+
+    /**
+     * web-分页查询店铺信息
+     *
+
+     * @return IPage<StoreInfoVo>
+     */
+    List<StoreInfoVo> getMoreRecommendedStores(Double lon , Double lat, int subcategory, int threeLevelClassification);
+
 }

+ 146 - 2
alien-store/src/main/java/shop/alien/store/service/impl/StoreInfoServiceImpl.java

@@ -12,6 +12,7 @@ import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -59,6 +60,7 @@ import java.text.SimpleDateFormat;
 import java.time.*;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.SignStyle;
 import java.time.temporal.ChronoField;
 import java.time.temporal.ChronoUnit;
 import java.util.*;
@@ -71,6 +73,7 @@ import java.util.stream.Collectors;
  * @author ssk
  * @since 2024-12-05
  */
+@Slf4j
 @Service
 @RequiredArgsConstructor
 @Transactional
@@ -1550,7 +1553,7 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
             List<String> storeIds = Arrays.asList(storeId.split(","));
             if (StringUtils.isNotEmpty(startTime) && StringUtils.isNotEmpty(endTime)) {
                 List<StoreBusinessInfo> storeBusinessInfos = storeBusinessInfoMapper.selectList(new LambdaQueryWrapper<StoreBusinessInfo>().in(StoreBusinessInfo::getStoreId, storeIds));
-                DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendValue(ChronoField.HOUR_OF_DAY, 1, 2, java.time.format.SignStyle.NOT_NEGATIVE).appendLiteral(':').appendValue(ChronoField.MINUTE_OF_HOUR, 2).toFormatter();
+                DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendValue(ChronoField.HOUR_OF_DAY, 1, 2, SignStyle.NOT_NEGATIVE).appendLiteral(':').appendValue(ChronoField.MINUTE_OF_HOUR, 2).toFormatter();
                 List<StoreBusinessInfo> list = storeBusinessInfos.stream().filter(item -> {
                     // 商家开门时间
                     LocalTime timeStart = LocalTime.parse(item.getEndTime(), formatter);
@@ -1630,7 +1633,7 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
             List<String> storeIds = Arrays.asList(storeId.split(","));
             if (StringUtils.isNotEmpty(startTime) && StringUtils.isNotEmpty(endTime)) {
                 List<StoreBusinessInfo> storeBusinessInfos = storeBusinessInfoMapper.selectList(new LambdaQueryWrapper<StoreBusinessInfo>().in(StoreBusinessInfo::getStoreId, storeIds));
-                DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendValue(ChronoField.HOUR_OF_DAY, 1, 2, java.time.format.SignStyle.NOT_NEGATIVE).appendLiteral(':').appendValue(ChronoField.MINUTE_OF_HOUR, 2).toFormatter();
+                DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendValue(ChronoField.HOUR_OF_DAY, 1, 2, SignStyle.NOT_NEGATIVE).appendLiteral(':').appendValue(ChronoField.MINUTE_OF_HOUR, 2).toFormatter();
                 List<StoreBusinessInfo> list = storeBusinessInfos.stream().filter(item -> {
                     // 商家开门时间
                     LocalTime timeStart = LocalTime.parse(item.getEndTime(), formatter);
@@ -2460,4 +2463,145 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
         }
         return result;
     }
+
+    /**
+     * web-分页查询店铺信息
+     *
+
+     * @return IPage<StoreInfoVo>
+     */
+    @Override
+    public List<StoreInfoVo> getMoreRecommendedStores(Double lon , Double lat, int subcategory, int threeLevelClassification) {
+        QueryWrapper<StoreInfoVo> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("a.delete_flag", 0).eq("b.delete_flag", 0).orderByDesc("a.created_time");
+        //如果查询未过期
+        // 获取当前时刻
+        Date currentDate = new Date();
+        // 获取当前日期和时间
+        Calendar calendar = Calendar.getInstance();
+        // 将时间设置为 0 点
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        calendar.set(Calendar.MILLISECOND, 0);
+        // 加上 30 天
+        calendar.add(Calendar.DAY_OF_MONTH, 30);
+
+        // 距离选择(一千米)
+        int distance = 5000;
+
+        List<StoreInfoVo> storeInfoVoList = storeInfoMapper.getMoreRecommendedStores(queryWrapper);
+        if (!storeInfoVoList.isEmpty()) {
+            // 提前查询所有需要的字典数据
+            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<Object, List<Map<String, Object>>> avgScoreMap = new HashMap<>();
+            Map<Integer, List<StoreComment>> commentMap = new HashMap<>();
+
+            // 如果获取美食列表进行以下前置操作
+            List<Integer> storeIds = storeInfoVoList.stream().map(StoreInfoVo::getId).collect(Collectors.toList());
+            LambdaUpdateWrapper<LifeCoupon> quanWrapper = new LambdaUpdateWrapper<>();
+            quanWrapper.in(LifeCoupon::getStoreId, storeIds).eq(LifeCoupon::getStatus, 1).orderByDesc(LifeCoupon::getCreatedTime);
+
+            avgScoreMap = storeEvaluationMapper.allStoreAvgScore().stream().collect(Collectors.groupingBy(o -> o.get("store_id")));
+            commentMap = storeCommentMapper.selectList(new QueryWrapper<StoreComment>().eq("business_type", "5").eq("delete_flag", 0)).stream().collect(Collectors.groupingBy(StoreComment::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));
+                }
+                //写经纬度
+                String[] split = record.getStorePosition().split(",");
+                record.setStorePositionLongitude(split[0]);
+                record.setStorePositionLatitude(split[1]);
+                //处理一下到期状态
+                Date expirationTime = record.getExpirationTime();
+                if (expirationTime != null) {
+                    // 获取当前时间
+                    Calendar now = Calendar.getInstance();
+                    Date nowCurrentDate = now.getTime();
+                    // 计算 30 天后的时间
+                    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();
+                    // 将 expirationTime 转换为 LocalDate
+                    LocalDate expDate = expirationTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+                    // 计算距离到期的天数
+                    long daysToExpire = ChronoUnit.DAYS.between(nowLocal, expDate);
+                    record.setDaysToExpire(daysToExpire);
+                }
+
+                // 设置店铺得分,设置店铺人均消费,设置总评论数
+                if (avgScoreMap.containsKey(String.valueOf(record.getId()))) {
+                    record.setAvgScore(String.valueOf(avgScoreMap.get(String.valueOf(record.getId())).get(0).get("avg_score")));
+                }
+                // 设置店铺得分,设置店铺人均消费,设置总评论数
+                if (commentMap.containsKey(record.getId())) {
+                    record.setTotalNum(String.valueOf(commentMap.get(record.getId()).size()));
+                }
+
+            }
+        }
+        List<StoreInfoVo> filteredList = new ArrayList<>();
+        // 根据距离筛选店铺列表
+        if (lon != null && lat != null) {
+            filteredList = storeInfoVoList.stream()
+                    .filter(store -> {
+                        // 检查店铺坐标是否存在
+                        if (StringUtils.isEmpty(store.getStorePosition())) {
+                            return false;
+                        }
+                        
+                        try {
+                            // 解析店铺坐标(格式:经度,纬度)
+                            String[] positionArray = store.getStorePosition().split(",");
+                            if (positionArray.length != 2) {
+                                return false;
+                            }
+                            
+                            double storeLon = Double.parseDouble(positionArray[0].trim());
+                            double storeLat = Double.parseDouble(positionArray[1].trim());
+                            
+                            // 计算距离(单位:千米)
+                            double calculatedDistance = DistanceUtil.haversineCalculateDistance(lon, lat, storeLon, storeLat);
+                            
+                            // 将距离转换为米进行比较(distance 单位是米)
+                            double distanceInMeters = calculatedDistance * 1000;
+                            
+                            // 筛选距离范围内的店铺
+                            return distanceInMeters <= distance;
+                        } catch (Exception e) {
+                            // 计算距离失败时,记录日志并过滤掉该店铺
+                            return false;
+                        }
+                    })
+                    .collect(Collectors.toList());
+            
+            // 记录距离筛选结果
+            if (log.isInfoEnabled()) {
+                log.info("距离筛选完成,原始店铺数量:" + storeInfoVoList.size() + ",筛选后店铺数量:" + filteredList.size() + ",筛选距离:" + distance + "米");
+            }
+        }
+        return filteredList;
+    }
 }