商品搜索距离计算

This commit is contained in:
liyj 2026-01-12 15:27:43 +08:00
parent c22df25f16
commit 25f1ade10d
2 changed files with 136 additions and 8 deletions

View File

@ -0,0 +1,98 @@
package com.suisung.mall.common.utils;
import cn.hutool.core.convert.Convert;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class DistanceCalculatorUtils {
// 地球半径千米
private static final double EARTH_RADIUS = 6371.0;
/**
* 计算两个经纬度坐标之间的距离Haversine公式
* @param lat1 第一个点的纬度
* @param lon1 第一个点的经度
* @param lat2 第二个点的纬度
* @param lon2 第二个点的经度
* @return 距离千米
*/
public static double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
// 将角度转换为弧度
double lat1Rad = Math.toRadians(lat1);
double lon1Rad = Math.toRadians(lon1);
double lat2Rad = Math.toRadians(lat2);
double lon2Rad = Math.toRadians(lon2);
// 计算差值
double deltaLat = lat2Rad - lat1Rad;
double deltaLon = lon2Rad - lon1Rad;
// Haversine公式
double a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) +
Math.cos(lat1Rad) * Math.cos(lat2Rad) *
Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return EARTH_RADIUS * c;
}
/**
* 重载方法返回不同单位的距离
* @param unit 单位"km"=千米, "m"=, "mile"=英里
*/
public static double calculateDistance(double lat1, double lon1, double lat2, double lon2, String unit) {
double distanceKm = calculateDistance(lat1, lon1, lat2, lon2);
switch (unit.toLowerCase()) {
case "km":
return distanceKm;
case "m":
return distanceKm * 1000;
case "mile":
return distanceKm * 0.621371;
case "nautical": // 海里
return distanceKm * 0.539957;
default:
return distanceKm;
}
}
// 使用示例
public static void main(String[] args) {
// 示例北京(39.9042, 116.4074)到上海(31.2304, 121.4737)
double lat1 = 23.212212;
double lon1 = 110.23232332;
double lat2 = 23.332099038755167;
double lon2 = 110.08853179682197;
double distanceKm = calculateDistance(lat1, lon1, lat2, lon2);
double distanceM = calculateDistance(lat1, lon1, lat2, lon2, "m");
double distanceMile = calculateDistance(lat1, lon1, lat2, lon2, "mile");
System.out.println("北京到上海的距离:");
System.out.printf("千米: %.2f km\n", distanceKm);
System.out.printf("米: %.2f m\n", distanceM);
System.out.printf("英里: %.2f miles\n", distanceMile);
List<Map> product_base_rows=new ArrayList<>();
Map base=new HashMap<>();
base.put("store_id",111);
product_base_rows.add(base);
base.put("store_id",22);
product_base_rows.add(base);
base.put("store_id",33);
product_base_rows.add(base);
base.put("store_id",44);
product_base_rows.add(base);
base.put("store_id",44);
product_base_rows.add(base);
System.out.println(product_base_rows);
List<Integer> storeIds= product_base_rows.stream().map(map -> Convert.toInt(map.get("store_id"))).distinct().collect(Collectors.toList());
System.out.println(storeIds);
}
}

View File

@ -62,6 +62,7 @@ import com.suisung.mall.shop.product.service.*;
import com.suisung.mall.shop.sixun.service.SxSyncGoodsService; import com.suisung.mall.shop.sixun.service.SxSyncGoodsService;
import com.suisung.mall.shop.store.service.*; import com.suisung.mall.shop.store.service.*;
import com.suisung.mall.shop.user.service.*; import com.suisung.mall.shop.user.service.*;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -408,7 +409,7 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
productInfo.setProduct_buy_limit(product_buy_limit); productInfo.setProduct_buy_limit(product_buy_limit);
//用来判断是否使用 //用来判断是否使用
cn.hutool.json.JSONArray spec_array = cn.hutool.json.JSONUtil.parseArray(productObjMap.get("productSpec")); cn.hutool.json.JSONArray spec_array = JSONUtil.parseArray(productObjMap.get("productSpec"));
List<Integer> spec_id_row = new ArrayList<>(); List<Integer> spec_id_row = new ArrayList<>();
for (Object spec_jo : spec_array) { for (Object spec_jo : spec_array) {
cn.hutool.json.JSONObject item = (cn.hutool.json.JSONObject) spec_jo; cn.hutool.json.JSONObject item = (cn.hutool.json.JSONObject) spec_jo;
@ -988,7 +989,7 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
// ITEM_ID/SKU唯一编号表 // ITEM_ID/SKU唯一编号表
// product_id + sort(spec_item_id) = 构造唯一ITEM ID // product_id + sort(spec_item_id) = 构造唯一ITEM ID
String item_spec = item_row.getItem_spec(); String item_spec = item_row.getItem_spec();
cn.hutool.json.JSONArray array_item_spec = cn.hutool.json.JSONUtil.parseArray(item_spec); cn.hutool.json.JSONArray array_item_spec = JSONUtil.parseArray(item_spec);
List<Integer> spec_item_ids = new ArrayList<>(); List<Integer> spec_item_ids = new ArrayList<>();
List<String> item_names = new ArrayList<>(); List<String> item_names = new ArrayList<>();
Long item_id; Long item_id;
@ -1361,7 +1362,7 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
// ITEM_ID/SKU唯一编号表 // ITEM_ID/SKU唯一编号表
// product_id + sort(spec_item_id) = 构造唯一ITEM ID // product_id + sort(spec_item_id) = 构造唯一ITEM ID
String item_spec = $product_item_row.getItem_spec(); String item_spec = $product_item_row.getItem_spec();
cn.hutool.json.JSONArray array_item_spec = cn.hutool.json.JSONUtil.parseArray(item_spec); cn.hutool.json.JSONArray array_item_spec = JSONUtil.parseArray(item_spec);
List<Integer> spec_item_ids = new ArrayList<>(); List<Integer> spec_item_ids = new ArrayList<>();
List<String> item_names = new ArrayList<>(); List<String> item_names = new ArrayList<>();
@ -2063,6 +2064,30 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
} }
} }
//start 计算店铺距离
Map<Integer,Double> distanceMap=new HashedMap();
String lat1 = getParameter("userLat");//维度
String lon1=getParameter("userLng");//经度
boolean isCaculateDistance=false;//是否要计算距离
if(StringUtils.isNotEmpty(lat1)&&StringUtils.isNotEmpty(lon1)){
List<Integer> storeIds= product_base_rows.stream().map(map ->Convert.toInt(map.get("store_id"))).distinct().collect(Collectors.toList());
if(!storeIds.isEmpty()){
isCaculateDistance=true;
QueryWrapper<ShopStoreBase> queryWrapper = new QueryWrapper<>();
queryWrapper.in("store_id",storeIds);
List<ShopStoreBase> shopStoreBases= shopStoreBaseService.list(queryWrapper);
for (ShopStoreBase shopStoreBase : shopStoreBases) {
String store_latitude=shopStoreBase.getStore_latitude();
String store_longitude=shopStoreBase.getStore_longitude();
if(StringUtils.isNotEmpty(store_latitude)&&StringUtils.isNotEmpty(store_longitude)){
double distance=DistanceCalculatorUtils.calculateDistance(Convert.toDouble(lat1),Convert.toDouble(lon1),Convert.toDouble(store_latitude),Convert.toDouble(store_longitude));
distanceMap.put(shopStoreBase.getStore_id(),NumberUtil.round(distance,2).doubleValue());
}
}
}
}
//end 计算店铺距离
//List<ShopProductIndex> productIndexList = shopProductIndexService.gets(product_id_row); //List<ShopProductIndex> productIndexList = shopProductIndexService.gets(product_id_row);
//过滤过期的活动商品 start //过滤过期的活动商品 start
List<ShopProductIndex> productIndexList = filterEndActivity(product_id_row); List<ShopProductIndex> productIndexList = filterEndActivity(product_id_row);
@ -2078,6 +2103,11 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
product_base_row.put("is_virtual", Convert.toInt(shopProductBaseService.isVirtual(Convert.toInt(product_index_row.get("kind_id"))))); product_base_row.put("is_virtual", Convert.toInt(shopProductBaseService.isVirtual(Convert.toInt(product_index_row.get("kind_id")))));
product_base_row.put("product_uniqid", product_info_row.get("product_uniqid")); product_base_row.put("product_uniqid", product_info_row.get("product_uniqid"));
product_base_row.put("product_spec", product_info_row.get("product_spec")); product_base_row.put("product_spec", product_info_row.get("product_spec"));
if(isCaculateDistance){//计算店铺距离
Integer storeId=Convert.toInt(product_base_row.get("store_id"));
double distance= distanceMap.get(storeId);
product_base_row.put("distance",distance);
}
if(null!= product_info_row.get("product_spec")){ if(null!= product_info_row.get("product_spec")){
JSONArray jsonArray_spec = JSONObject.parseArray((String) product_info_row.get("product_spec")); JSONArray jsonArray_spec = JSONObject.parseArray((String) product_info_row.get("product_spec"));
@ -4212,8 +4242,8 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
// 满减 // 满减
if (ObjectUtil.equal(StateCode.ACTIVITY_TYPE_REDUCTION, activity_type_id) && CheckUtil.isNotEmpty(activity_id)) { if (ObjectUtil.equal(StateCode.ACTIVITY_TYPE_REDUCTION, activity_type_id) && CheckUtil.isNotEmpty(activity_id)) {
com.alibaba.fastjson.JSONObject requirement = (com.alibaba.fastjson.JSONObject) activity_rule.get("requirement"); JSONObject requirement = (JSONObject) activity_rule.get("requirement");
com.alibaba.fastjson.JSONObject buy = (com.alibaba.fastjson.JSONObject) requirement.get("buy"); JSONObject buy = (JSONObject) requirement.get("buy");
JSONArray item = (JSONArray) buy.get("item"); JSONArray item = (JSONArray) buy.get("item");
List<Long> reduction_item_ids = Convert.toList(Long.class, item); List<Long> reduction_item_ids = Convert.toList(Long.class, item);
if (CollUtil.isNotEmpty(reduction_item_ids)) { if (CollUtil.isNotEmpty(reduction_item_ids)) {
@ -4985,7 +5015,7 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
newProductItem.setItem_unit_price(newProductItem.getItem_advice_price()); newProductItem.setItem_unit_price(newProductItem.getItem_advice_price());
String item_spec = newProductItem.getItem_spec(); String item_spec = newProductItem.getItem_spec();
cn.hutool.json.JSONArray array_item_spec = cn.hutool.json.JSONUtil.parseArray(item_spec); cn.hutool.json.JSONArray array_item_spec = JSONUtil.parseArray(item_spec);
List<Integer> spec_item_ids = new ArrayList<>(); List<Integer> spec_item_ids = new ArrayList<>();
List<String> item_names = new ArrayList<>(); List<String> item_names = new ArrayList<>();
@ -6027,7 +6057,7 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
// item.setItem_quantity(null); // item.setItem_quantity(null);
// ITEM_ID/SKU唯一编号表 // ITEM_ID/SKU唯一编号表
// product_id + sort(spec_item_id) = 构造唯一ITEM ID // product_id + sort(spec_item_id) = 构造唯一ITEM ID
cn.hutool.json.JSONArray array_item_spec = cn.hutool.json.JSONUtil.parseArray(item_spec); cn.hutool.json.JSONArray array_item_spec = JSONUtil.parseArray(item_spec);
List<Integer> spec_item_ids = new ArrayList<>(); List<Integer> spec_item_ids = new ArrayList<>();
List<String> item_names = new ArrayList<>(); List<String> item_names = new ArrayList<>();
for (Object josn_item_spec : array_item_spec) { for (Object josn_item_spec : array_item_spec) {
@ -6508,7 +6538,7 @@ public class ShopProductBaseServiceImpl extends BaseServiceImpl<ShopProductBaseM
@Override @Override
public Map getProductByProductNumber(String productNumber) { public Map getProductByProductNumber(String productNumber) {
UserDto userDto = ContextUtil.getCurrentUser(); UserDto userDto = getCurrentUser();
String store_id = userDto.getStore_id(); String store_id = userDto.getStore_id();
Map data = new HashMap(); Map data = new HashMap();