|
|
package com.yohoufo.product.service.impl;
|
|
|
|
|
|
import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
|
|
|
import com.yohobuy.ufo.model.response.store.StoreInfoBo;
|
|
|
import com.yohoufo.common.cache.CacheClient;
|
|
|
import com.yohoufo.common.exception.UfoServiceException;
|
|
|
import com.yohoufo.dal.product.IStoreInfoDAO;
|
|
|
import com.yohoufo.dal.product.IStoreInfoExtendDAO;
|
|
|
import com.yohoufo.dal.product.model.StoreInfo;
|
|
|
import com.yohoufo.dal.product.model.StoreInfoExtend;
|
|
|
import com.yohoufo.product.service.StoreService;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
@Service
|
|
|
public class StoreServiceImpl implements StoreService {
|
|
|
|
|
|
@Autowired
|
|
|
private CacheClient cacheClient;
|
|
|
|
|
|
@Autowired
|
|
|
private IStoreInfoDAO storeInfoDao;
|
|
|
|
|
|
@Autowired
|
|
|
private IStoreInfoExtendDAO storeInfoExtendDao;
|
|
|
|
|
|
private static final String STORE_CACHE_KEY_PREFIX = "ufo:offline:store:";
|
|
|
|
|
|
private static final int STORE_CACHE_TIME_MINUTES = 10;
|
|
|
|
|
|
private static final int SIGN_RANGE_DEFAULT = 800;
|
|
|
|
|
|
private final Logger LOG = LoggerFactory.getLogger(this.getClass());
|
|
|
|
|
|
@Override
|
|
|
public StoreInfoBo queryStoreInfoById(int storeId) {
|
|
|
String key = RedisKeyBuilder.newInstance().appendFixed(STORE_CACHE_KEY_PREFIX).appendVar(storeId).getKey();
|
|
|
StoreInfoBo storeInfoCache = cacheClient.get(key, StoreInfoBo.class);
|
|
|
if(storeInfoCache != null)
|
|
|
return storeInfoCache;
|
|
|
|
|
|
StoreInfoBo storeInfoBo = getStoreInfoFromDb(storeId);
|
|
|
if(storeInfoBo != null)
|
|
|
cacheClient.set(key, STORE_CACHE_TIME_MINUTES * 60, storeInfoBo);
|
|
|
|
|
|
return storeInfoBo;
|
|
|
}
|
|
|
|
|
|
private StoreInfoBo getStoreInfoFromDb(int storeId) {
|
|
|
if(storeId < 1) {
|
|
|
LOG.warn("getStoreInfoFromDb invalid storeId: {}", storeId);
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
StoreInfo storeInfo = storeInfoDao.selectByPrimaryKey(storeId);
|
|
|
StoreInfoExtend storeInfoExtend = storeInfoExtendDao.selectByStoreId(storeId);
|
|
|
if(storeInfo == null || storeInfoExtend == null) {
|
|
|
LOG.warn("getStoreInfoFromDb null for storeId: {}", storeId);
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
StoreInfoBo storeInfoBo = StoreInfoBo.builder()
|
|
|
.storeId(storeInfo.getId())
|
|
|
.storeName(storeInfo.getStoreName())
|
|
|
.storeAddress(storeInfoExtend.getAddress())
|
|
|
.latitude(storeInfoExtend.getLatitude())
|
|
|
.longitude(storeInfoExtend.getLongitude())
|
|
|
.locationRadius(storeInfoExtend.getSignRange())
|
|
|
.build();
|
|
|
|
|
|
LOG.info("get storeInfo from db: {}", storeInfoBo);
|
|
|
return storeInfoBo;
|
|
|
}
|
|
|
|
|
|
|
|
|
@Override
|
|
|
public boolean isLocationInStore(int storeId, double userLongitude, double userLatitude) {
|
|
|
StoreInfoBo storeInfoBo = queryStoreInfoById(storeId);
|
|
|
if(storeInfoBo == null) {
|
|
|
LOG.warn("none storeInfo by storeId: {}", storeId);
|
|
|
throw new UfoServiceException(500, "门店信息不存在");
|
|
|
}
|
|
|
return isInRange(userLongitude, userLatitude, storeInfoBo);
|
|
|
}
|
|
|
|
|
|
private boolean isInRange(Double userLongitude, Double userLatitude, StoreInfoBo storeInfoBo) {
|
|
|
if (storeInfoBo == null) {
|
|
|
return false;
|
|
|
}
|
|
|
Double latitude = new Double(storeInfoBo.getLatitude());
|
|
|
Double longitude = new Double(storeInfoBo.getLongitude());
|
|
|
|
|
|
Double degree = (24901 * 1609) / 360.0;
|
|
|
double raidusMile = (storeInfoBo.getLocationRadius() == null) ? SIGN_RANGE_DEFAULT : storeInfoBo.getLocationRadius();
|
|
|
|
|
|
Double dpmLat = 1 / degree;
|
|
|
Double radiusLat = dpmLat * raidusMile;
|
|
|
Double minLat = latitude - radiusLat;
|
|
|
Double maxLat = latitude + radiusLat;
|
|
|
|
|
|
Double mpdLng = degree * Math.cos(latitude * (Math.PI / 180));
|
|
|
Double dpmLng = 1 / mpdLng;
|
|
|
Double radiusLng = dpmLng * raidusMile;
|
|
|
Double minLng = longitude - radiusLng;
|
|
|
Double maxLng = longitude + radiusLng;
|
|
|
|
|
|
if (userLongitude >= minLng && userLongitude <= maxLng && userLatitude >= minLat && userLatitude <= maxLat) {
|
|
|
return true;
|
|
|
} else {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
} |
...
|
...
|
|