|
|
@@ -47,6 +47,7 @@ import shop.alien.store.util.GroupConstant;
|
|
|
import shop.alien.store.util.ai.AiAuthTokenUtil;
|
|
|
import shop.alien.util.ali.AliOSSUtil;
|
|
|
import shop.alien.util.common.DistanceUtil;
|
|
|
+import shop.alien.util.common.JwtUtil;
|
|
|
import shop.alien.util.common.constant.CouponStatusEnum;
|
|
|
import shop.alien.util.common.constant.CouponTypeEnum;
|
|
|
import shop.alien.util.common.constant.OcrTypeEnum;
|
|
|
@@ -2031,9 +2032,10 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
|
|
|
List<StoreStaffConfig> storeStaffConfigs = storeStaffConfigMapper.selectList(lambdaQueryWrapper);
|
|
|
result.setEmployeeList(storeStaffConfigs);
|
|
|
|
|
|
- // 该用户的打卡记录
|
|
|
+ // 该用户的打卡记录(仅审核通过 check_flag=2,未审核/审核中/拒绝均不计入)
|
|
|
LambdaQueryWrapper<StoreClockIn> clockInWrapper = new LambdaQueryWrapper<>();
|
|
|
clockInWrapper.eq(StoreClockIn::getUserId, userId);
|
|
|
+ clockInWrapper.eq(StoreClockIn::getCheckFlag, 2);
|
|
|
List<StoreClockIn> clockInList = storeClockInMapper.selectList(clockInWrapper);
|
|
|
|
|
|
List<StoreClockIn> clockStoreList = clockInList.stream().filter(item -> item.getStoreId() == Integer.parseInt(storeId)).collect(Collectors.toList());
|
|
|
@@ -5071,9 +5073,6 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
|
|
|
return Collections.emptyList();
|
|
|
}
|
|
|
|
|
|
- QueryWrapper<StoreInfoVo> queryWrapper = new QueryWrapper<>();
|
|
|
- queryWrapper.eq("a.delete_flag", 0).eq("b.delete_flag", 0);
|
|
|
- //如果查询未过期
|
|
|
// 获取当前时刻
|
|
|
Date currentDate = new Date();
|
|
|
// 获取当前日期和时间
|
|
|
@@ -5085,49 +5084,134 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
|
|
|
calendar.set(Calendar.MILLISECOND, 0);
|
|
|
// 加上 30 天
|
|
|
calendar.add(Calendar.DAY_OF_MONTH, 30);
|
|
|
- // 如果 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));
|
|
|
+ // 构建position参数(格式:经度,纬度)
|
|
|
+ String position = lon + "," + lat;
|
|
|
|
|
|
- // 构建一级分类
|
|
|
- if (StringUtils.isNotEmpty(businessSection)) {
|
|
|
- queryWrapper.eq("a.business_section", businessSection);
|
|
|
- // 构建二级分类
|
|
|
- if (StringUtils.isNotEmpty(businessTypes)) {
|
|
|
- queryWrapper.eq("a.business_types", businessTypes);
|
|
|
- // 构建三级分类
|
|
|
- if (StringUtils.isNotEmpty(businessClassify)) {
|
|
|
- // 解析businessClassify参数(格式:1,2,3)
|
|
|
- String[] classifyArray = businessClassify.split(",");
|
|
|
- // 使用FIND_IN_SET函数检查数据库字段是否包含参数中的任何一个值
|
|
|
- queryWrapper.and(wrapper -> {
|
|
|
- for (int i = 0; i < classifyArray.length; i++) {
|
|
|
- String classify = classifyArray[i].trim();
|
|
|
- if (StringUtils.isNotEmpty(classify)) {
|
|
|
- if (i == 0) {
|
|
|
- wrapper.apply("FIND_IN_SET({0}, a.business_classify) > 0", classify);
|
|
|
- } else {
|
|
|
- wrapper.or().apply("FIND_IN_SET({0}, a.business_classify) > 0", classify);
|
|
|
+ // 先查询当前用户好友店铺ID(互相关注的商户)
|
|
|
+ Set<Integer> friendStoreIds = new HashSet<>();
|
|
|
+ try {
|
|
|
+ // 从上下文获取当前登录用户ID -> 查询手机号 -> 组装粉丝ID
|
|
|
+ JSONObject currentUserInfo = JwtUtil.getCurrentUserInfo();
|
|
|
+ if (currentUserInfo != null) {
|
|
|
+ Integer currentUserId = currentUserInfo.getInteger("userId");
|
|
|
+ if (currentUserId != null) {
|
|
|
+ LifeUser currentUser = lifeUserMapper.selectById(currentUserId);
|
|
|
+ if (currentUser != null && StringUtils.isNotEmpty(currentUser.getUserPhone())) {
|
|
|
+ String myFansId = "user_" + currentUser.getUserPhone();
|
|
|
+
|
|
|
+ // 我关注的店铺
|
|
|
+ LambdaQueryWrapper<LifeFans> myFollowWrapper = new LambdaQueryWrapper<>();
|
|
|
+ myFollowWrapper.eq(LifeFans::getFansId, myFansId)
|
|
|
+ .likeRight(LifeFans::getFollowedId, "store_")
|
|
|
+ .eq(LifeFans::getDeleteFlag, 0);
|
|
|
+ List<LifeFans> myFollows = lifeFansMapper.selectList(myFollowWrapper);
|
|
|
+
|
|
|
+ // 过滤出互相关注(店铺也关注我)的店铺phoneId:store_xxx
|
|
|
+ Set<String> mutualStorePhones = new HashSet<>();
|
|
|
+ if (!CollectionUtils.isEmpty(myFollows)) {
|
|
|
+ List<String> followedStoreIds = myFollows.stream()
|
|
|
+ .map(LifeFans::getFollowedId)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (!followedStoreIds.isEmpty()) {
|
|
|
+ // 查询这些店铺是否关注我
|
|
|
+ LambdaQueryWrapper<LifeFans> reciprocalWrapper = new LambdaQueryWrapper<>();
|
|
|
+ reciprocalWrapper.in(LifeFans::getFansId, followedStoreIds)
|
|
|
+ .eq(LifeFans::getFollowedId, myFansId)
|
|
|
+ .eq(LifeFans::getDeleteFlag, 0);
|
|
|
+ List<LifeFans> reciprocals = lifeFansMapper.selectList(reciprocalWrapper);
|
|
|
+ Set<String> reciprocalFansIds = reciprocals.stream()
|
|
|
+ .map(LifeFans::getFansId)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+
|
|
|
+ // 互相关注的店铺 phoneId(store_开头)
|
|
|
+ for (String followedId : followedStoreIds) {
|
|
|
+ if (reciprocalFansIds.contains(followedId)) {
|
|
|
+ mutualStorePhones.add(followedId);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- });
|
|
|
+
|
|
|
+ if (!mutualStorePhones.isEmpty()) {
|
|
|
+ // 提取店铺手机号
|
|
|
+ Set<String> storePhones = mutualStorePhones.stream()
|
|
|
+ .map(pid -> {
|
|
|
+ int idx = pid.indexOf('_');
|
|
|
+ return idx != -1 ? pid.substring(idx + 1) : pid;
|
|
|
+ })
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+
|
|
|
+ // 根据店铺手机号查询 store_user,提取 store_id
|
|
|
+ LambdaQueryWrapper<StoreUser> storeUserWrapper = new LambdaQueryWrapper<>();
|
|
|
+ storeUserWrapper.in(StoreUser::getPhone, storePhones)
|
|
|
+ .eq(StoreUser::getDeleteFlag, 0);
|
|
|
+ List<StoreUser> storeUsers = storeUserMapper.selectList(storeUserWrapper);
|
|
|
+ friendStoreIds = storeUsers.stream()
|
|
|
+ .map(StoreUser::getStoreId)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 好友优先不影响主流程
|
|
|
+ log.warn("更多推荐-好友店铺优先排序失败,忽略该步骤。error={}", e.getMessage());
|
|
|
}
|
|
|
|
|
|
- // 构建position参数(格式:经度,纬度)
|
|
|
- String position = lon + "," + lat;
|
|
|
- List<StoreInfoVo> storeInfoVoList = storeInfoMapper.getMoreRecommendedStores(queryWrapper, position);
|
|
|
+ // 查询好友店铺(不限制 business_section)
|
|
|
+ List<StoreInfoVo> friendStoreList = Collections.emptyList();
|
|
|
+ if (!friendStoreIds.isEmpty()) {
|
|
|
+ QueryWrapper<StoreInfoVo> friendQueryWrapper = new QueryWrapper<>();
|
|
|
+ friendQueryWrapper.eq("a.delete_flag", 0).eq("b.delete_flag", 0);
|
|
|
+ friendQueryWrapper.and(w -> w.isNull("a.expiration_time")
|
|
|
+ .or()
|
|
|
+ .gt("a.expiration_time", currentDate));
|
|
|
+ friendQueryWrapper.and(w -> w.isNull("a.food_licence_expiration_time")
|
|
|
+ .or()
|
|
|
+ .gt("a.food_licence_expiration_time", currentDate));
|
|
|
+ friendQueryWrapper.in("a.id", friendStoreIds);
|
|
|
+ friendStoreList = storeInfoMapper.getMoreRecommendedStores(friendQueryWrapper, position);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询当前类型店铺(仅按 business_section)
|
|
|
+ QueryWrapper<StoreInfoVo> currentTypeQueryWrapper = new QueryWrapper<>();
|
|
|
+ currentTypeQueryWrapper.eq("a.delete_flag", 0).eq("b.delete_flag", 0);
|
|
|
+ currentTypeQueryWrapper.and(w -> w.isNull("a.expiration_time")
|
|
|
+ .or()
|
|
|
+ .gt("a.expiration_time", currentDate));
|
|
|
+ currentTypeQueryWrapper.and(w -> w.isNull("a.food_licence_expiration_time")
|
|
|
+ .or()
|
|
|
+ .gt("a.food_licence_expiration_time", currentDate));
|
|
|
+ if (StringUtils.isNotEmpty(businessSection)) {
|
|
|
+ currentTypeQueryWrapper.eq("a.business_section", businessSection);
|
|
|
+ }
|
|
|
+ List<StoreInfoVo> currentTypeStoreList = storeInfoMapper.getMoreRecommendedStores(currentTypeQueryWrapper, position);
|
|
|
+
|
|
|
+ // 合并:好友店铺在前,当前类型店铺在后;按店铺ID去重
|
|
|
+ Map<Integer, StoreInfoVo> mergedMap = new LinkedHashMap<>();
|
|
|
+ if (!CollectionUtils.isEmpty(friendStoreList)) {
|
|
|
+ for (StoreInfoVo vo : friendStoreList) {
|
|
|
+ mergedMap.put(vo.getId(), vo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!CollectionUtils.isEmpty(currentTypeStoreList)) {
|
|
|
+ for (StoreInfoVo vo : currentTypeStoreList) {
|
|
|
+ mergedMap.putIfAbsent(vo.getId(), vo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ List<StoreInfoVo> storeInfoVoList = new ArrayList<>(mergedMap.values());
|
|
|
if (CollectionUtils.isEmpty(storeInfoVoList)) {
|
|
|
return Collections.emptyList();
|
|
|
}
|
|
|
+
|
|
|
+ // 好友店铺 + 当前类型店铺,最多回显30个
|
|
|
+ if (storeInfoVoList.size() > 30) {
|
|
|
+ storeInfoVoList = new ArrayList<>(storeInfoVoList.subList(0, 30));
|
|
|
+ }
|
|
|
// 提前查询所有需要的字典数据
|
|
|
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());
|
|
|
@@ -5992,9 +6076,10 @@ public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo
|
|
|
result.setIsFollowed(0); // 用户ID或店铺信息为空,默认未关注
|
|
|
}
|
|
|
|
|
|
- // 该用户的打卡记录
|
|
|
+ // 该用户的打卡记录(仅审核通过 check_flag=2)
|
|
|
LambdaQueryWrapper<StoreClockIn> clockInWrapper = new LambdaQueryWrapper<>();
|
|
|
clockInWrapper.eq(StoreClockIn::getUserId, userId);
|
|
|
+ clockInWrapper.eq(StoreClockIn::getCheckFlag, 2);
|
|
|
List<StoreClockIn> clockInList = storeClockInMapper.selectList(clockInWrapper);
|
|
|
|
|
|
List<StoreClockIn> clockStoreList = clockInList.stream().filter(item -> item.getStoreId() == Integer.parseInt(storeId)).collect(Collectors.toList());
|