You've already forked FrameTour-BE
refactor(scenic): 重构景区相关接口和缓存机制
- 移除 ScenicMapper 接口,将相关方法移至 ScenicRepository - 修改景区列表查询逻辑,使用 ScenicRepository 的 list 方法 - 优化景区详情获取方式,使用 ScenicRepository 的 getScenicBasic 方法 - 重构缓存机制,增加对景区基本信息的缓存 - 优化 AppScenicService 和 ScenicService接口,使用 ScenicV2DTO 替代 ScenicRespV
This commit is contained in:
@@ -13,7 +13,6 @@ import com.ycwl.basic.facebody.entity.AddFaceResp;
|
||||
import com.ycwl.basic.mapper.DeviceMapper;
|
||||
import com.ycwl.basic.mapper.CustomUploadTaskMapper;
|
||||
import com.ycwl.basic.mapper.FaceSampleMapper;
|
||||
import com.ycwl.basic.mapper.ScenicMapper;
|
||||
import com.ycwl.basic.mapper.SourceMapper;
|
||||
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
|
||||
import com.ycwl.basic.model.custom.entity.CustomUploadTaskEntity;
|
||||
|
@@ -7,6 +7,7 @@ import com.ycwl.basic.model.mobile.scenic.ScenicIndexVO;
|
||||
import com.ycwl.basic.model.mobile.scenic.account.ScenicLoginReq;
|
||||
import com.ycwl.basic.model.mobile.scenic.account.ScenicLoginRespVO;
|
||||
import com.ycwl.basic.model.pc.device.resp.DeviceRespVO;
|
||||
import com.ycwl.basic.model.pc.scenic.entity.ScenicEntity;
|
||||
import com.ycwl.basic.model.pc.scenic.req.ScenicReqQuery;
|
||||
import com.ycwl.basic.model.pc.scenic.resp.ScenicRespVO;
|
||||
import com.ycwl.basic.utils.ApiResponse;
|
||||
@@ -18,7 +19,7 @@ import java.util.List;
|
||||
* @Date:2024/12/6 10:23
|
||||
*/
|
||||
public interface AppScenicService {
|
||||
ApiResponse<PageInfo<ScenicAppVO>> pageQuery(ScenicReqQuery scenicReqQuery);
|
||||
ApiResponse<PageInfo<ScenicEntity>> pageQuery(ScenicReqQuery scenicReqQuery);
|
||||
|
||||
ApiResponse<ScenicDeviceCountVO> deviceCountByScenicId(Long scenicId);
|
||||
|
||||
|
@@ -1,10 +1,11 @@
|
||||
package com.ycwl.basic.service.mobile.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.ycwl.basic.constant.BaseContextHandler;
|
||||
import com.ycwl.basic.mapper.*;
|
||||
import com.ycwl.basic.integration.scenic.dto.scenic.ScenicV2DTO;
|
||||
import com.ycwl.basic.mapper.DeviceMapper;
|
||||
import com.ycwl.basic.mapper.ExtraDeviceMapper;
|
||||
import com.ycwl.basic.mapper.ScenicAccountMapper;
|
||||
import com.ycwl.basic.model.jwt.JwtInfo;
|
||||
import com.ycwl.basic.model.mobile.scenic.ScenicAppVO;
|
||||
import com.ycwl.basic.model.mobile.scenic.ScenicDeviceCountVO;
|
||||
@@ -14,7 +15,6 @@ import com.ycwl.basic.model.mobile.scenic.account.ScenicLoginRespVO;
|
||||
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
|
||||
import com.ycwl.basic.model.pc.device.resp.DeviceRespVO;
|
||||
import com.ycwl.basic.model.pc.scenic.entity.ScenicAccountEntity;
|
||||
import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity;
|
||||
import com.ycwl.basic.model.pc.scenic.entity.ScenicEntity;
|
||||
import com.ycwl.basic.model.pc.scenic.req.ScenicReqQuery;
|
||||
import com.ycwl.basic.model.pc.scenic.resp.ScenicRespVO;
|
||||
@@ -31,6 +31,7 @@ import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@@ -44,8 +45,6 @@ import static com.ycwl.basic.constant.JwtRoleConstant.MERCHANT;
|
||||
@Service
|
||||
public class AppScenicServiceImpl implements AppScenicService {
|
||||
|
||||
@Autowired
|
||||
private ScenicMapper scenicMapper;
|
||||
@Autowired
|
||||
private DeviceMapper deviceMapper;
|
||||
@Autowired
|
||||
@@ -64,10 +63,15 @@ public class AppScenicServiceImpl implements AppScenicService {
|
||||
private ScenicRepository scenicRepository;
|
||||
|
||||
@Override
|
||||
public ApiResponse<PageInfo<ScenicAppVO>> pageQuery(ScenicReqQuery scenicReqQuery) {
|
||||
PageHelper.startPage(scenicReqQuery.getPageNum(), scenicReqQuery.getPageSize());
|
||||
List<ScenicAppVO> list = scenicMapper.appList(scenicReqQuery);
|
||||
PageInfo<ScenicAppVO> pageInfo = new PageInfo<>(list);
|
||||
public ApiResponse<PageInfo<ScenicEntity>> pageQuery(ScenicReqQuery scenicReqQuery) {
|
||||
|
||||
ScenicReqQuery query = new ScenicReqQuery();
|
||||
query.setPageSize(1000);
|
||||
List<ScenicV2DTO> scenicList = scenicRepository.list(query);
|
||||
List<ScenicEntity> list = scenicList.stream().map(scenic -> {
|
||||
return scenicRepository.getScenic(Long.valueOf(scenic.getId()));
|
||||
}).toList();
|
||||
PageInfo<ScenicEntity> pageInfo = new PageInfo<>(list);
|
||||
return ApiResponse.success(pageInfo);
|
||||
}
|
||||
|
||||
@@ -140,8 +144,58 @@ public class AppScenicServiceImpl implements AppScenicService {
|
||||
|
||||
@Override
|
||||
public List<ScenicAppVO> scenicListByLnLa(ScenicIndexVO scenicIndexVO) {
|
||||
List<ScenicAppVO> scenicAppVOS = scenicMapper.scenicListByLnLa(scenicIndexVO);
|
||||
return scenicAppVOS.stream().filter(scenic -> scenic.getDistance().compareTo(scenic.getRadius().multiply(BigDecimal.valueOf(1_000L))) < 0).toList();
|
||||
// 从 scenicRepository 获取所有景区(1000个)
|
||||
ScenicReqQuery query = new ScenicReqQuery();
|
||||
query.setPageNum(1);
|
||||
query.setPageSize(1000);
|
||||
List<ScenicV2DTO> scenicList = scenicRepository.list(query);
|
||||
|
||||
List<ScenicAppVO> list = new ArrayList<>();
|
||||
|
||||
// 为每个景区获取详细信息(包含经纬度)
|
||||
for (ScenicV2DTO scenicDTO : scenicList) {
|
||||
try {
|
||||
// 获取景区详细信息(包含经纬度)
|
||||
ScenicEntity scenicEntity = scenicRepository.getScenic(Long.parseLong(scenicDTO.getId()));
|
||||
if (scenicEntity != null && scenicEntity.getLatitude() != null && scenicEntity.getLongitude() != null) {
|
||||
// 计算距离
|
||||
BigDecimal distance = calculateDistance(
|
||||
scenicIndexVO.getLatitude(),
|
||||
scenicIndexVO.getLongitude(),
|
||||
scenicEntity.getLatitude(),
|
||||
scenicEntity.getLongitude()
|
||||
);
|
||||
|
||||
// 根据距离和范围筛选景区
|
||||
if (scenicEntity.getRadius() != null &&
|
||||
distance.compareTo(scenicEntity.getRadius().multiply(BigDecimal.valueOf(1_000L))) < 0) {
|
||||
|
||||
// 转换为 ScenicAppVO
|
||||
ScenicAppVO scenicAppVO = new ScenicAppVO();
|
||||
scenicAppVO.setId(scenicEntity.getId());
|
||||
scenicAppVO.setName(scenicEntity.getName());
|
||||
scenicAppVO.setPhone(scenicEntity.getPhone());
|
||||
scenicAppVO.setIntroduction(scenicEntity.getIntroduction());
|
||||
scenicAppVO.setCoverUrl(scenicEntity.getCoverUrl());
|
||||
scenicAppVO.setLongitude(scenicEntity.getLongitude());
|
||||
scenicAppVO.setLatitude(scenicEntity.getLatitude());
|
||||
scenicAppVO.setRadius(scenicEntity.getRadius());
|
||||
scenicAppVO.setProvince(scenicEntity.getProvince());
|
||||
scenicAppVO.setCity(scenicEntity.getCity());
|
||||
scenicAppVO.setArea(scenicEntity.getArea());
|
||||
scenicAppVO.setAddress(scenicEntity.getAddress());
|
||||
scenicAppVO.setDistance(distance);
|
||||
|
||||
list.add(scenicAppVO);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 单个景区获取失败,继续处理下一个
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -183,4 +237,29 @@ public class AppScenicServiceImpl implements AppScenicService {
|
||||
deviceRespVOList.addAll(0, extraDeviceList);
|
||||
return ApiResponse.success(deviceRespVOList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算两点之间的距离(米)
|
||||
* 使用 Haversine 公式
|
||||
*/
|
||||
private BigDecimal calculateDistance(BigDecimal lat1, BigDecimal lon1, BigDecimal lat2, BigDecimal lon2) {
|
||||
if (lat1 == null || lon1 == null || lat2 == null || lon2 == null) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
final double R = 6371000; // 地球半径(米)
|
||||
|
||||
double lat1Rad = Math.toRadians(lat1.doubleValue());
|
||||
double lat2Rad = Math.toRadians(lat2.doubleValue());
|
||||
double deltaLat = Math.toRadians(lat2.subtract(lat1).doubleValue());
|
||||
double deltaLon = Math.toRadians(lon2.subtract(lon1).doubleValue());
|
||||
|
||||
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));
|
||||
|
||||
double distance = R * c;
|
||||
return BigDecimal.valueOf(distance);
|
||||
}
|
||||
}
|
||||
|
@@ -1,11 +1,8 @@
|
||||
package com.ycwl.basic.service.pc;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter;
|
||||
import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity;
|
||||
import com.ycwl.basic.model.pc.scenic.req.ScenicAddOrUpdateReq;
|
||||
import com.ycwl.basic.integration.scenic.dto.scenic.ScenicV2DTO;
|
||||
import com.ycwl.basic.model.pc.scenic.req.ScenicReqQuery;
|
||||
import com.ycwl.basic.model.pc.scenic.resp.ScenicRespVO;
|
||||
import com.ycwl.basic.pay.adapter.IPayAdapter;
|
||||
import com.ycwl.basic.storage.adapters.IStorageAdapter;
|
||||
import com.ycwl.basic.utils.ApiResponse;
|
||||
@@ -17,7 +14,7 @@ import java.util.List;
|
||||
* @Date:2024/12/3 15:22
|
||||
*/
|
||||
public interface ScenicService {
|
||||
ApiResponse<List<ScenicRespVO>> list(ScenicReqQuery scenicReqQuery);
|
||||
ApiResponse<List<ScenicV2DTO>> list(ScenicReqQuery scenicReqQuery);
|
||||
|
||||
IStorageAdapter getScenicStorageAdapter(Long scenicId);
|
||||
|
||||
|
@@ -1,39 +1,27 @@
|
||||
package com.ycwl.basic.service.pc.impl;
|
||||
|
||||
import com.ycwl.basic.utils.JacksonUtil;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.ycwl.basic.facebody.FaceBodyFactory;
|
||||
import com.ycwl.basic.facebody.adapter.IFaceBodyAdapter;
|
||||
import com.ycwl.basic.mapper.ScenicAccountMapper;
|
||||
import com.ycwl.basic.mapper.ScenicMapper;
|
||||
import com.ycwl.basic.model.pc.scenic.entity.ScenicAccountEntity;
|
||||
import com.ycwl.basic.integration.scenic.dto.scenic.ScenicV2DTO;
|
||||
import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity;
|
||||
import com.ycwl.basic.model.pc.scenic.req.ScenicAddOrUpdateReq;
|
||||
import com.ycwl.basic.model.pc.scenic.req.ScenicReqQuery;
|
||||
import com.ycwl.basic.model.pc.scenic.resp.ScenicRespVO;
|
||||
import com.ycwl.basic.pay.PayFactory;
|
||||
import com.ycwl.basic.pay.adapter.IPayAdapter;
|
||||
import com.ycwl.basic.repository.ScenicRepository;
|
||||
import com.ycwl.basic.service.pc.ScenicService;
|
||||
import com.ycwl.basic.service.task.TaskFaceService;
|
||||
import com.ycwl.basic.storage.StorageFactory;
|
||||
import com.ycwl.basic.storage.adapters.IStorageAdapter;
|
||||
import com.ycwl.basic.storage.exceptions.StorageUnsupportedException;
|
||||
import com.ycwl.basic.utils.ApiResponse;
|
||||
import com.ycwl.basic.utils.SnowFlakeUtil;
|
||||
import com.ycwl.basic.utils.JacksonUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static com.ycwl.basic.constant.FaceConstant.USER_FACE_DB_NAME;
|
||||
|
||||
/**
|
||||
* @Author:longbinbin
|
||||
* @Date:2024/12/3 15:25
|
||||
@@ -41,15 +29,13 @@ import static com.ycwl.basic.constant.FaceConstant.USER_FACE_DB_NAME;
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ScenicServiceImpl implements ScenicService {
|
||||
@Autowired
|
||||
private ScenicMapper scenicMapper;
|
||||
@Autowired
|
||||
private ScenicRepository scenicRepository;
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public ApiResponse<List<ScenicRespVO>> list(ScenicReqQuery scenicReqQuery) {
|
||||
return ApiResponse.success(scenicMapper.list(scenicReqQuery));
|
||||
public ApiResponse<List<ScenicV2DTO>> list(ScenicReqQuery scenicReqQuery) {
|
||||
return ApiResponse.success(scenicRepository.list(scenicReqQuery));
|
||||
}
|
||||
|
||||
private static final Map<Long, IStorageAdapter> scenicStorageAdapterMap = new ConcurrentHashMap<>();
|
||||
|
Reference in New Issue
Block a user