门店管理

master
wjt 1 year ago
parent 09c67e8dfa
commit 865090d0a1

@ -0,0 +1,69 @@
package com.baiye.util;
import lombok.RequiredArgsConstructor;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResult;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.stereotype.Component;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author jt
*/
@Component
@RequiredArgsConstructor
public class GeoUtil {
private final RedisUtils redisUtils;
/**
* redis
*
* @param key
* @param longitude
* @param latitude
*/
public void geoAdd(String key, double longitude, double latitude, String geoKey) {
Point point = new Point(longitude, latitude);
RedisGeoCommands.GeoLocation geoLocation = new RedisGeoCommands.GeoLocation(key, point);
redisUtils.set(geoKey, geoLocation);
}
/**
*
*
* @param key1
* @param key2
* @return
*/
public double distanceBetween(String geoKey, String key1, String key2) {
return redisUtils.distance(geoKey, key1, key2);
}
/**
*
*
* @param key
* @param distance
* @return
*/
public Map<String, Double> distanceInclude(String geoKey, String key, double distance) {
Map<String, Double> map = new LinkedHashMap<>();
GeoResults<RedisGeoCommands.GeoLocation<Object>> geoResults = redisUtils.radius(geoKey, key, new Distance(distance));
if (geoResults != null) {
for (GeoResult<RedisGeoCommands.GeoLocation<Object>> geoResult : geoResults) {
// 与目标点相距的距离信息
Distance geoResultDistance = geoResult.getDistance();
// 该点的信息
RedisGeoCommands.GeoLocation<Object> geoResultContent = geoResult.getContent();
map.put(geoResultContent.getName().toString(), geoResultDistance.getValue());
}
}
return map;
}
}

@ -9,11 +9,11 @@ import com.baiye.enums.MailRequestEnum;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.GeoResults;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisConnectionUtils;
import org.springframework.data.redis.core.RedisTemplate;
@ -22,6 +22,7 @@ import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Component
@ -715,4 +716,42 @@ public class RedisUtils {
concat(format).concat(StrPool.DASHED).concat(String.valueOf(batch));
}
/**
*
*
* @param key id
* @param point
* @param name
*/
public void set(String key, RedisGeoCommands.GeoLocation geoLocation) {
redisTemplate.opsForGeo().add(key, geoLocation);
}
/**
*
*
* @param geoKey
* @param key1
* @param key2
* @return
*/
public Double distance(String geoKey, String key1, String key2) {
Distance distance = redisTemplate.opsForGeo().distance(geoKey, key1, key2);
return distance.getValue();
}
/**
*
*
* @param geoKey
* @param key
* @param distance
* @return
*/
public GeoResults<RedisGeoCommands.GeoLocation<Object>> radius(String geoKey, String key, Distance distance) {
RedisGeoCommands.GeoRadiusCommandArgs geoRadiusCommandArgs = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
GeoResults<RedisGeoCommands.GeoLocation<Object>> radius = redisTemplate.opsForGeo().radius(geoKey, key, distance, geoRadiusCommandArgs.includeDistance());
return radius;
}
}

@ -2,11 +2,13 @@ package com.baiye.modules.distribute.controller;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.modules.distribute.dto.StoreDTO;
import com.baiye.modules.distribute.entity.StoreEntity;
import com.baiye.modules.distribute.qo.StoreQo;
import com.baiye.modules.distribute.service.StoreService;
import com.baiye.modules.distribute.vo.StoreVO;
import com.baiye.result.R;
import com.baiye.util.GeoUtil;
import com.baiye.validation.group.CreateGroup;
import com.baiye.validation.group.UpdateGroup;
import io.swagger.v3.oas.annotations.Operation;
@ -15,6 +17,8 @@ import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author wjt
* @date 2023/9/5
@ -26,11 +30,26 @@ import org.springframework.web.bind.annotation.*;
public class StoreController {
private final StoreService storeService;
private final GeoUtil geoUtil;
@GetMapping("/queryAll")
@GetMapping("/queryPage")
@Operation(summary = "分页查询门店")
public R<PageResult<StoreVO>> queryStore(@Validated PageParam pageParam, StoreQo storeQo) {
return R.ok(storeService.queryStore(pageParam, storeQo));
public R<PageResult<StoreVO>> queryStorePage(@Validated PageParam pageParam, StoreQo storeQo) {
return R.ok(storeService.queryStorePage(pageParam, storeQo));
}
@GetMapping("/queryAll")
@Operation(summary = "不分页查询门店")
public R<List<StoreVO>> queryStore(StoreQo storeQo) {
return R.ok(storeService.queryStore(storeQo));
}
@GetMapping("/queryRange")
@Operation(summary = "查询范围内所有的门店")
public R<List<StoreDTO>> queryRangeStore(@RequestParam("longitude") Double longitude,
@RequestParam("latitude") Double latitude,
@RequestParam("distance") Double distance) {
return R.ok(storeService.queryRangeStore(longitude, latitude, distance));
}
@PostMapping("/add")

@ -0,0 +1,34 @@
package com.baiye.modules.distribute.dto;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springdoc.api.annotations.ParameterObject;
import java.math.BigDecimal;
/**
* @author wjt
* @date 2023/9/13
*/
@Data
@Schema(title = "门店管理dto")
@ParameterObject
public class StoreDTO {
@Parameter(description = "门店名称")
private String storeName;
@Parameter(description = "门店id")
private String id;
@Parameter(description = "纬度")
private BigDecimal latitude;
@Parameter(description = "经度")
private BigDecimal longitude;
@Parameter(description = "联系方式")
private String nid;
@Parameter(description = "门店地址")
private String address;
@Parameter(description = "距离/米")
private Double distance;
@Parameter(description = "序号")
private Integer index;
}

@ -12,6 +12,7 @@ import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
/**
* @author wjt
@ -40,7 +41,8 @@ public class StoreEntity extends LogicDeletedBaseEntity {
@Schema(title = "门店状态 0-正常 1-未营业")
@NotNull(message = "门店状态不能为空", groups = {CreateGroup.class})
private Integer storeStatus;
@Schema(title = "nid")
private String nid;
@Schema(title = "省份")
private String province;
@ -50,6 +52,9 @@ public class StoreEntity extends LogicDeletedBaseEntity {
@Schema(title = "区县")
private String county;
@Schema(title = "详细地址")
private String detail;
@Schema(title = "营业开始时间")
@NotNull(message = "营业时间不能为空", groups = {CreateGroup.class})
private String tradeStartTime;
@ -61,4 +66,12 @@ public class StoreEntity extends LogicDeletedBaseEntity {
@TableField(exist = false)
@NotNull(message = "地址不能为空", groups = {CreateGroup.class})
private String address;
@Schema(title = "经度")
@NotNull(message = "经度不能为空", groups = {CreateGroup.class})
private BigDecimal longitude;
@Schema(title = "玮度")
@NotNull(message = "玮度不能为空", groups = {CreateGroup.class})
private BigDecimal latitude;
}

@ -30,8 +30,7 @@ public interface StoreMapper extends ExtendMapper<StoreEntity> {
.eqIfPresent(StoreEntity::getProvince, qo.getProvince())
.eqIfPresent(StoreEntity::getCity, qo.getCity())
.eqIfPresent(StoreEntity::getCounty, qo.getCounty())
.eq(StoreEntity::getDeleted, 0)
.eq(StoreEntity::getCreateBy, qo.getCreateBy())
// .geIfPresent(StoreEntity::getTradeStartTime, qo.getTradeEndTime())
// .leIfPresent(StoreEntity::getTradeEndTime, qo.getTradeStartTime())

@ -37,9 +37,11 @@ public class StoreQo {
@Parameter(description = "添加的结束时间")
private Date createEndTime;
// @Parameter(description = "营业开始时间")
// @Parameter(description = "营业开始时间")
// private String tradeStartTime;
//
// @Parameter(description = "营业结束时间")
// private String tradeEndTime;
@Parameter(description = "创建人")
private Long createBy;
}

@ -3,10 +3,13 @@ package com.baiye.modules.distribute.service;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.extend.mybatis.plus.service.ExtendService;
import com.baiye.modules.distribute.dto.StoreDTO;
import com.baiye.modules.distribute.entity.StoreEntity;
import com.baiye.modules.distribute.qo.StoreQo;
import com.baiye.modules.distribute.vo.StoreVO;
import java.util.List;
/**
* @author wjt
* @date 2023/9/5
@ -20,7 +23,15 @@ public interface StoreService extends ExtendService<StoreEntity> {
* @param storeQo
* @return
*/
PageResult<StoreVO> queryStore(PageParam pageParam, StoreQo storeQo);
PageResult<StoreVO> queryStorePage(PageParam pageParam, StoreQo storeQo);
/**
*
*
* @param storeQo
* @return
*/
List<StoreVO> queryStore(StoreQo storeQo);
/**
*
@ -42,4 +53,15 @@ public interface StoreService extends ExtendService<StoreEntity> {
* @param storeId id
*/
void deleteStore(Long storeId);
/**
*
*
* @param longitude
* @param latitude
* @param distance
* @return
*/
List<StoreDTO> queryRangeStore(Double longitude, Double latitude, Double distance);
}

@ -1,20 +1,31 @@
package com.baiye.modules.distribute.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import com.baiye.domain.PageParam;
import com.baiye.domain.PageResult;
import com.baiye.exception.BadRequestException;
import com.baiye.extend.mybatis.plus.service.impl.ExtendServiceImpl;
import com.baiye.modules.distribute.dto.StoreDTO;
import com.baiye.modules.distribute.entity.StoreEntity;
import com.baiye.modules.distribute.mapper.StoreMapper;
import com.baiye.modules.distribute.qo.StoreQo;
import com.baiye.modules.distribute.service.CustomStoreService;
import com.baiye.modules.distribute.service.StoreService;
import com.baiye.modules.distribute.vo.StoreVO;
import com.baiye.security.util.SecurityUtils;
import com.baiye.util.GeoUtil;
import com.baiye.util.RedisUtils;
import com.baiye.utils.AddressSplitterUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@ -29,11 +40,13 @@ import java.util.stream.Collectors;
public class StoreServiceImpl extends ExtendServiceImpl<StoreMapper, StoreEntity> implements StoreService {
private final CustomStoreService customStoreService;
private final RedisUtils redisUtils;
private final GeoUtil geoUtil;
private final String storeRedisKey = "store::";
@Override
public PageResult<StoreVO> queryStore(PageParam pageParam, StoreQo storeQo) {
public PageResult<StoreVO> queryStorePage(PageParam pageParam, StoreQo storeQo) {
storeQo.setCreateBy(SecurityUtils.getCurrentUserId());
PageResult<StoreVO> storeEntityPageResult = baseMapper.queryPage(pageParam, storeQo);
List<StoreVO> records = storeEntityPageResult.getRecords();
if (CollUtil.isNotEmpty(records)) {
@ -48,14 +61,34 @@ public class StoreServiceImpl extends ExtendServiceImpl<StoreMapper, StoreEntity
return storeEntityPageResult;
}
@Override
public List<StoreVO> queryStore(StoreQo qo) {
LambdaQueryWrapper<StoreEntity> wrapper = new LambdaQueryWrapper<>();
if (qo.getStoreName() != null) {
wrapper.like(StoreEntity::getStoreName, qo.getStoreName());
}
wrapper.eq(StoreEntity::getCreateBy, SecurityUtils.getCurrentUserId());
wrapper.orderByDesc(StoreEntity::getCreateTime);
List<StoreEntity> storeEntities = baseMapper.selectList(wrapper);
return Convert.toList(StoreVO.class, storeEntities);
}
@Override
public void addStore(StoreEntity storeEntity) {
//同一个公司门店名不能重复
Long currentUserId = SecurityUtils.getCurrentUserId();
StoreEntity storeEntity1 = baseMapper.selectOne(new LambdaQueryWrapper<StoreEntity>().eq(StoreEntity::getCreateBy, currentUserId).eq(StoreEntity::getStoreName, storeEntity.getStoreName()));
if (storeEntity1 != null) {
throw new BadRequestException("门店名称重复");
}
String address = storeEntity.getAddress();
Map<String, String> map = AddressSplitterUtil.getAddress(address);
storeEntity.setProvince(map.get("province"));
storeEntity.setCity(map.get("city"));
storeEntity.setCounty(map.get("county"));
storeEntity.setDetail(map.get("detail"));
baseMapper.insert(storeEntity);
addStoreRedis(storeEntity);
}
@Override
@ -86,4 +119,63 @@ public class StoreServiceImpl extends ExtendServiceImpl<StoreMapper, StoreEntity
public void deleteStore(Long storeId) {
baseMapper.deleteById(storeId);
}
@Override
public List<StoreDTO> queryRangeStore(Double longitude, Double latitude, Double distance) {
List<StoreDTO> list = new ArrayList<>();
// Long whichUserId = SecurityUtils.getWhichUserId();
// log.info("父id{}",whichUserId);
Long userId = 1L;
List<StoreEntity> storeEntities = baseMapper.selectList(new LambdaQueryWrapper<StoreEntity>().eq(StoreEntity::getCreateBy, userId));
Map<String, Double> map = new HashMap<>();
if (CollUtil.isNotEmpty(storeEntities)) {
redisUtils.del(userId.toString());
for (StoreEntity storeEntity : storeEntities) {
geoUtil.geoAdd(storeEntity.getId().toString(), storeEntity.getLongitude().doubleValue(), storeEntity.getLatitude().doubleValue(), userId.toString());
}
String key = RandomUtil.randomString(4);
geoUtil.geoAdd(key, longitude, latitude, userId.toString());
map = geoUtil.distanceInclude(userId.toString(), key, distance);
}
if (map != null) {
int index = 0;
for (Map.Entry<String, Double> range : map.entrySet()) {
String key = range.getKey();
StoreDTO storeRedis = getStoreRedis(key);
if (storeRedis != null && storeRedis.getId() != null) {
storeRedis.setDistance(range.getValue());
storeRedis.setIndex(index);
list.add(storeRedis);
index++;
}
}
}
return list;
}
public StoreDTO getStoreRedis(String id) {
Object o = redisUtils.get(storeRedisKey + id);
if (o != null) {
return BeanUtil.toBean(o, StoreDTO.class);
} else {
StoreEntity storeEntity = baseMapper.selectById(id);
StoreDTO storeDTO = new StoreDTO();
if (storeEntity != null && storeEntity.getId() != null) {
BeanUtil.copyProperties(storeEntity, storeDTO);
storeDTO.setAddress(storeEntity.getCounty() + storeEntity.getDetail());
redisUtils.set(storeRedisKey + storeEntity.getId(), storeDTO);
}
return storeDTO;
}
}
public void addStoreRedis(StoreEntity storeEntity) {
StoreDTO storeDTO = new StoreDTO();
BeanUtil.copyProperties(storeEntity, storeDTO);
storeDTO.setAddress(storeEntity.getCounty() + storeEntity.getDetail());
redisUtils.set(storeRedisKey + storeEntity.getId(), storeDTO);
}
}

@ -1,8 +1,12 @@
package com.baiye.modules.distribute.vo;
import com.baiye.validation.group.CreateGroup;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
/**
* @author wjt
@ -46,4 +50,9 @@ public class StoreVO {
@Schema(title = "营业时间")
private String tradeTime;
@Schema(title = "经度")
private BigDecimal latitude;
@Schema(title = "玮度")
private BigDecimal longitude;
}

Loading…
Cancel
Save