init
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
package com.newyetai.usercenter.district.constants;
|
||||
|
||||
/**
|
||||
* @author czy
|
||||
* @date 2021-07-08
|
||||
*/
|
||||
public interface DistrictConstants {
|
||||
|
||||
Long DEFAULT_DISTRICT_ID = 0l;
|
||||
|
||||
String CACHE_KEY_DISTRICT_ID = "#districtId";
|
||||
|
||||
interface CacheNames {
|
||||
|
||||
/** 省 **/
|
||||
String DISTRICT_PROVINCE = "district:province";
|
||||
|
||||
/** 市 **/
|
||||
String DISTRICT_CITY = "district:city";
|
||||
|
||||
/** 区 **/
|
||||
String DISTRICT_AREA = "district:area";
|
||||
|
||||
/** 街 **/
|
||||
String DISTRICT_STREET = "district:street";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.newyetai.usercenter.district.controller;
|
||||
|
||||
|
||||
import com.newyetai.common.AlitaResult;
|
||||
import com.newyetai.usercenter.district.constants.DistrictConstants;
|
||||
import com.newyetai.usercenter.district.dto.DistrictDTO;
|
||||
import com.newyetai.usercenter.district.dto.DistrictTreeQueryDTO;
|
||||
import com.newyetai.usercenter.district.entity.District;
|
||||
import com.newyetai.usercenter.district.service.IDistrictService;
|
||||
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 省份城市 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author Carlye
|
||||
* @since 2021-01-25
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/anon/district")
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class DistrictController {
|
||||
|
||||
private final IDistrictService districtService;
|
||||
|
||||
@GetMapping("/tree")
|
||||
@ApiOperation("创建用户附件")
|
||||
public AlitaResult<List<DistrictDTO>> tree(DistrictTreeQueryDTO queryDTO) {
|
||||
return AlitaResult.success(districtService.treeList(queryDTO));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation("获取指定Id下的城市列表(不传就默认查省列表)")
|
||||
public AlitaResult<List<DistrictDTO>> loadDataById(@RequestParam(value = "districtId", required = false) Long districtId) {
|
||||
if (districtId == null) {
|
||||
districtId = DistrictConstants.DEFAULT_DISTRICT_ID;
|
||||
}
|
||||
return AlitaResult.success(districtService.queryListById(districtId));
|
||||
}
|
||||
|
||||
@GetMapping("/all")
|
||||
@ApiOperation("获取全部")
|
||||
public AlitaResult<List<District>> all(@RequestParam(value = "level") Integer level) {
|
||||
return AlitaResult.success(districtService.all(level));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.newyetai.usercenter.district.dao;
|
||||
|
||||
import com.newyetai.usercenter.district.dto.DistrictDTO;
|
||||
import com.newyetai.usercenter.district.entity.District;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 省份城市 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author Carlye
|
||||
* @since 2021-01-25
|
||||
*/
|
||||
public interface DistrictMapper extends BaseMapper<District> {
|
||||
|
||||
List<DistrictDTO> queryById(Long districtId);
|
||||
|
||||
String queryNameByCode(@Param("codes") List<String> codes);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package com.newyetai.usercenter.district.dto;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.newyetai.common.dto.BaseDTO;
|
||||
import com.newyetai.common.util.TreeNode;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.*;
|
||||
import lombok.experimental.Accessors;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 省份城市
|
||||
* </p>
|
||||
*
|
||||
* @author Carlye
|
||||
* @since 2021-01-25
|
||||
*/
|
||||
@ApiModel("省份城市树形DTO")
|
||||
@Data
|
||||
@SuperBuilder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
public class DistrictDTO extends BaseDTO implements TreeNode<Long, DistrictDTO> {
|
||||
|
||||
private static final long serialVersionUID = -3042079366109391854L;
|
||||
|
||||
@ApiModelProperty("城市名称")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("上级城市ID")
|
||||
private Long parentId;
|
||||
|
||||
@ApiModelProperty("首字母")
|
||||
private String initial;
|
||||
|
||||
@ApiModelProperty("简拼")
|
||||
private String initials;
|
||||
|
||||
@ApiModelProperty("全拼")
|
||||
private String pinyin;
|
||||
|
||||
@ApiModelProperty("特别行政区")
|
||||
private String extra;
|
||||
|
||||
@ApiModelProperty("后缀")
|
||||
private String suffix;
|
||||
|
||||
@ApiModelProperty("城市编码")
|
||||
private String code;
|
||||
|
||||
@ApiModelProperty("区域编码")
|
||||
private String areaCode;
|
||||
|
||||
@ApiModelProperty("排序")
|
||||
private Integer districtOrder;
|
||||
|
||||
private Integer level;
|
||||
|
||||
@ApiModelProperty("下级")
|
||||
private List<DistrictDTO> childrenSet;
|
||||
|
||||
public List<DistrictDTO> getChildrenSet() {
|
||||
if (Objects.isNull(this.childrenSet)) {
|
||||
this.childrenSet = Lists.newArrayList();
|
||||
}
|
||||
return this.childrenSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChildren(DistrictDTO node) {
|
||||
getChildrenSet().add(node);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.newyetai.usercenter.district.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 省份城市
|
||||
* </p>
|
||||
*
|
||||
* @author Carlye
|
||||
* @since 2021-01-25
|
||||
*/
|
||||
@ApiModel("省份城市树形查询DTO")
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class DistrictTreeQueryDTO {
|
||||
|
||||
private static final long serialVersionUID = -3042079366109391854L;
|
||||
|
||||
|
||||
@ApiModelProperty("省份编码")
|
||||
private String code;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.newyetai.usercenter.district.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.newyetai.common.entity.BaseEntity;
|
||||
import lombok.*;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 省份城市
|
||||
*
|
||||
* @author Carlye
|
||||
* @since 2021-01-25
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Accessors(chain = true)
|
||||
@TableName("xs_district")
|
||||
public class District extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 城市名称 */
|
||||
private String name;
|
||||
|
||||
/** 上级城市ID */
|
||||
private Long parentId;
|
||||
|
||||
/** 首字母 */
|
||||
private String initial;
|
||||
|
||||
/** 简拼 */
|
||||
private String initials;
|
||||
|
||||
/** 全拼 */
|
||||
private String pinyin;
|
||||
|
||||
/** 特别行政区 */
|
||||
private String extra;
|
||||
|
||||
/** 后缀 */
|
||||
private String suffix;
|
||||
|
||||
/** 城市编码 */
|
||||
private String code;
|
||||
|
||||
/** 区域编码 */
|
||||
private String areaCode;
|
||||
|
||||
/** 排序 */
|
||||
private Integer districtOrder;
|
||||
|
||||
private Integer level;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.newyetai.usercenter.district.dao.DistrictMapper">
|
||||
|
||||
<select id="queryNameByCode" resultType="string">
|
||||
SELECT
|
||||
WM_CONCAT( name ) as addressName
|
||||
FROM
|
||||
xs_district
|
||||
WHERE
|
||||
deleted = 0
|
||||
AND code IN
|
||||
<foreach open="(" separator="," close=")" collection="codes" index="index" item="code" >
|
||||
#{code}
|
||||
</foreach>
|
||||
ORDER BY code ASC
|
||||
</select>
|
||||
|
||||
<select id="queryById" resultType="com.newyetai.usercenter.district.dto.DistrictDTO">
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
xs_district
|
||||
WHERE
|
||||
deleted = 0
|
||||
and parent_id=#{districtId}
|
||||
ORDER BY code ASC
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.newyetai.usercenter.district.mapstruct;
|
||||
|
||||
import com.newyetai.usercenter.district.dto.DistrictDTO;
|
||||
import com.newyetai.usercenter.district.entity.District;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
|
||||
/**
|
||||
* 用户映射器附件地图
|
||||
*
|
||||
* @author Carlye
|
||||
* @date 2021/01/12
|
||||
*/
|
||||
@Mapper
|
||||
public interface DistrictMapMapper {
|
||||
|
||||
DistrictMapMapper INSTANCE = Mappers.getMapper(DistrictMapMapper.class);
|
||||
|
||||
DistrictDTO exchange(District district);
|
||||
|
||||
DistrictDTO exchange(DistrictDTO districtDTO);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.newyetai.usercenter.district.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.newyetai.usercenter.district.dto.DistrictDTO;
|
||||
import com.newyetai.usercenter.district.dto.DistrictTreeQueryDTO;
|
||||
import com.newyetai.usercenter.district.entity.District;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 省份城市 服务类
|
||||
*
|
||||
* @author Carlye
|
||||
* @since 2021-01-25
|
||||
*/
|
||||
public interface IDistrictService extends IService<District> {
|
||||
|
||||
/**
|
||||
* 树列表
|
||||
*
|
||||
* @return {@link List<DistrictDTO>}
|
||||
*/
|
||||
List<DistrictDTO> treeList(DistrictTreeQueryDTO queryDTO);
|
||||
|
||||
List<DistrictDTO> queryListById(Long districtId);
|
||||
|
||||
List<District> all(Integer level);
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
package com.newyetai.usercenter.district.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import com.newyetai.common.exception.util.Assert;
|
||||
import com.newyetai.common.util.TreeHelper;
|
||||
import com.newyetai.frame.redis.aop.annotation.AutoUnLock;
|
||||
import com.newyetai.frame.redis.dto.LockDTO;
|
||||
import com.newyetai.frame.redis.redisson.RedissonUtils;
|
||||
import com.newyetai.usercenter.constants.CacheConstants;
|
||||
import com.newyetai.usercenter.district.constants.DistrictConstants;
|
||||
import com.newyetai.usercenter.district.dao.DistrictMapper;
|
||||
import com.newyetai.usercenter.district.dto.DistrictDTO;
|
||||
import com.newyetai.usercenter.district.dto.DistrictTreeQueryDTO;
|
||||
import com.newyetai.usercenter.district.entity.District;
|
||||
import com.newyetai.usercenter.district.mapstruct.DistrictMapMapper;
|
||||
import com.newyetai.usercenter.district.service.IDistrictService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 省份城市 服务实现类
|
||||
*
|
||||
* @author Carlye
|
||||
* @since 2021-01-25
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class DistrictServiceImpl extends ServiceImpl<DistrictMapper, District>
|
||||
implements IDistrictService {
|
||||
|
||||
private final RedisTemplate redisTemplate;
|
||||
|
||||
private final DistrictMapper districtMapper;
|
||||
|
||||
@Override
|
||||
@AutoUnLock
|
||||
public List<DistrictDTO> treeList(DistrictTreeQueryDTO queryDTO) {
|
||||
List<DistrictDTO> range = redisTemplate.opsForList().range(CacheConstants.DISTRICT_TREE_PROVINCE_KEY, 0, -1);
|
||||
if (CollectionUtils.isEmpty(range)) {
|
||||
Assert.isTrue(RedissonUtils.tryLockAutomatically(LockDTO.builder().methodName("treeList").build()), "正在初始化数据,请稍后再试");
|
||||
List<DistrictDTO> range2 = redisTemplate.opsForList().range(CacheConstants.DISTRICT_TREE_PROVINCE_KEY, 0, -1);
|
||||
if (CollectionUtils.isEmpty(range2)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<District> allDistricts =
|
||||
list(Wrappers.<District>lambdaQuery()
|
||||
.eq(District::getDeleted, false)
|
||||
.orderByAsc(District::getParentId, District::getDistrictOrder,
|
||||
District::getId));
|
||||
if (CollectionUtils.isEmpty(allDistricts)) {
|
||||
List<DistrictDTO> districtDTOS = Lists.newArrayList(new DistrictDTO());
|
||||
redisTemplate.opsForList()
|
||||
.leftPush(CacheConstants.DISTRICT_TREE_PROVINCE_KEY, districtDTOS);
|
||||
redisTemplate.expire(CacheConstants.DISTRICT_TREE_PROVINCE_KEY, 5, TimeUnit.MINUTES);
|
||||
return districtDTOS;
|
||||
}
|
||||
//省市区
|
||||
List<DistrictDTO> allDistrictDTOS = allDistricts.stream()
|
||||
.map(DistrictMapMapper.INSTANCE::exchange).collect(Collectors.toList());
|
||||
|
||||
List<DistrictDTO> districtDTOS = TreeHelper.buildTree(0L, allDistrictDTOS);
|
||||
//区-街道
|
||||
List<DistrictDTO> suffix = Lists.newArrayList();
|
||||
districtDTOS.forEach(districtDTO -> recursiveDistrictDTO(districtDTO, suffix));
|
||||
for (DistrictDTO districtDTO : suffix) {
|
||||
String key = String
|
||||
.join(":", CacheConstants.DISTRICT_TREE_ALL_KEY, districtDTO.getCode());
|
||||
redisTemplate.delete(key);
|
||||
redisTemplate.opsForList().rightPushAll(key, districtDTO.getChildrenSet());
|
||||
redisTemplate.expire(key, 1, TimeUnit.DAYS);
|
||||
}
|
||||
redisTemplate.delete(CacheConstants.DISTRICT_TREE_PROVINCE_KEY);
|
||||
redisTemplate.opsForList()
|
||||
.rightPushAll(CacheConstants.DISTRICT_TREE_PROVINCE_KEY, districtDTOS);
|
||||
redisTemplate.expire(CacheConstants.DISTRICT_TREE_PROVINCE_KEY, 1, TimeUnit.DAYS);
|
||||
range = districtDTOS;
|
||||
}
|
||||
}
|
||||
String code = queryDTO.getCode();
|
||||
if (StringUtils.isNotEmpty(code)) {
|
||||
String key = String.join(":", CacheConstants.DISTRICT_TREE_ALL_KEY, code);
|
||||
return redisTemplate.opsForList().range(key, 0, -1);
|
||||
}
|
||||
return range;
|
||||
}
|
||||
|
||||
|
||||
private static final Integer TAG = 4;
|
||||
|
||||
private void recursiveDistrictDTO(DistrictDTO districtDTO,
|
||||
List<DistrictDTO> suffix) {
|
||||
int length = districtDTO.getCode().length();
|
||||
if (length < TAG) {
|
||||
for (DistrictDTO child : districtDTO.getChildrenSet()) {
|
||||
recursiveDistrictDTO(child, suffix);
|
||||
}
|
||||
}
|
||||
if (length == TAG) {
|
||||
suffix.add(DistrictMapMapper.INSTANCE.exchange(districtDTO));
|
||||
districtDTO.setChildrenSet(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = DistrictConstants.CacheNames.DISTRICT_PROVINCE,
|
||||
key = DistrictConstants.CACHE_KEY_DISTRICT_ID)
|
||||
public List<DistrictDTO> queryListById(Long districtId) {
|
||||
List<DistrictDTO> districtDTOS = districtMapper.queryById(districtId);
|
||||
return districtDTOS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<District> all(Integer level) {
|
||||
List<District> districts = districtMapper.selectList(new LambdaQueryWrapper<District>()
|
||||
.eq(District::getLevel, level)
|
||||
.eq(District::getDeleted, false)
|
||||
.orderByAsc(District::getCode));
|
||||
return districts;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user