场景:
话不多说后端提供数据实现步骤:
1.controller层
@Api(tags = {"[地区]-城市相关接口"})
@RestController
@RequestMapping("region")
@Slf4j
public class RegionController extends BaseController {@Resourceprivate RegionService regionService;@ApiOperation("城市列表[A-Z]")@ApiImplicitParams({@ApiImplicitParam(name = "condition", value = "城市名称", required = false, paramType = "query")})@GetMapping("cityList")public JsonResult<List<AppletCityListVO>> cityList(@RequestParam(value = "condition", required = false) String condition) {return JsonResult.ok(this.regionService.smallProgramCityDisplayList(condition));}@ApiOperation("城市列表")@ApiImplicitParams({@ApiImplicitParam(name = "condition", value = "城市名称", required = false, paramType = "query")})@GetMapping("queryCityList")public JsonResult<List<AppletCityListVO.CityItem>> queryCityList(@RequestParam(value = "condition", required = false) String condition) {return JsonResult.ok(this.regionService.queryCityList(condition));}@Resourceprivate TencentMapUtil tencentMapUtil;@ApiOperation("根据经纬度查询地址")@GetMapping("tencent/map/reGeoCoder")public JsonResult<JSONObject> reGeoCoder(String lat, String lng) {AssertUtil.notBlank(lat, "纬度不能为空");AssertUtil.notBlank(lng, "经度不能为空");JSONObject jsonObject = tencentMapUtil.reGeoCoder(lat, lng);if (EntityConstant.INVALID != jsonObject.getInteger("status")) {log.error("定位授权失败 , errorMsg = {}", jsonObject.getString("message"));throw SimpleException.getInstance("定位授权失败");}JSONObject adInfo = jsonObject.getJSONObject("result").getJSONObject("ad_info");String city_code = adInfo.getString("city_code");String nation_code = adInfo.getString("nation_code");jsonObject.getJSONObject("result").getJSONObject("ad_info").put("cityCode", city_code.replaceAll(nation_code, ""));return JsonResult.ok(jsonObject);}
}
2.service层
@Service
@Slf4j
@Primary
public class RegionServiceImpl extends BaseApplicationService implements RegionService {@Resourceprivate RegionMapper regionMapper;private static final char[] alphabet = new char[26];static {// 使用循环填充数组元素for (int i = 0; i < alphabet.length; i++) {alphabet[i] = (char) ('A' + i);}}@Overridepublic List<AppletCityListVO> smallProgramCityDisplayList(String condition) {List<Region> regionList = this.regionMapper.selectByExample(new ExampleLambda<>(Region.class).andEqualTo(Region::getStatus, EntityConstant.NORMAL).andEqualTo(Region::getLevel, 2).andLike(Objects.nonNull(condition), Region::getName, condition).end());Map<String, List<Region>> cityMap = regionList.stream().collect(Collectors.groupingBy(Region::getInitial));List<AppletCityListVO> cityListVOList = new ArrayList<>(this.alphabet.length);for (char c : this.alphabet) {List<AppletCityListVO.CityItem> tempList = cityMap.containsKey(String.valueOf(c)) ? cityMap.get(String.valueOf(c)).stream().map(item -> {AppletCityListVO.CityItem cityItem = new AppletCityListVO.CityItem();cityItem.setCode(item.getCode());cityItem.setName(item.getName());return cityItem;}).collect(Collectors.toList()) : new ArrayList<>(0);cityListVOList.add(AppletCityListVO.builder().initial(String.valueOf(c)).itemList(tempList).build());}return cityListVOList;}@Overridepublic List<AppletCityListVO.CityItem> queryCityList(String condition) {List<Region> regionList = this.regionMapper.selectByExample(new ExampleLambda<>(Region.class).andEqualTo(Region::getStatus, EntityConstant.NORMAL).andEqualTo(Region::getLevel, 2).andLike(Objects.nonNull(condition), Region::getName, condition).end());return regionList.stream().map(item -> {AppletCityListVO.CityItem cityItem = new AppletCityListVO.CityItem();cityItem.setCode(item.getCode());cityItem.setName(item.getName());return cityItem;}).collect(Collectors.toList());}}@Builder
@Data
public class AppletCityListVO implements Serializable {@ApiModelProperty(value = "首字母")private String initial;@ApiModelProperty(value = "城市列表")private List<CityItem> itemList;@Datapublic static class CityItem {@ApiModelProperty(value = "code")private String code;@ApiModelProperty(value = "名称")private String name;public CityItem(String code, String name) {this.code = code;this.name = name;}public CityItem() {}}}
3.mapper层
public interface RegionMapper extends CrudMapper<Region, Long> {}
4.实体类
@Table(name = "`region`")
@Data
public class Region extends BaseEntity<Long> implements Serializable {private static final long serialVersionUID = 1L;/*** Id*/@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;/*** 1*/@Column(name = "level")private Integer level;/*** code*/@Column(name = "code")private String code;/*** 父级code*/@Column(name = "parent_code")private String parentCode;/*** 名称*/@Column(name = "name")private String name;/*** 名称拼音*/@Column(name = "pinyin")private String pinyin;/*** 首字母*/@Column(name = "initial")private String initial;/*** 状态*/@Column(name = "status")private Integer status;/*** 创建时间*/@Column(name = "gmt_created")@JsonFormat(locale = "zh", pattern = "yyyy-MM-dd HH:mm:ss")private Date gmtCreated;/*** ModifyUser*/@Column(name = "modify_user")private String modifyUser;/*** CreateUser*/@Column(name = "create_user")private String createUser;/*** 更新时间*/@Column(name = "gmt_modified")@JsonFormat(locale = "zh", pattern = "yyyy-MM-dd HH:mm:ss")private Date gmtModified;/*** 是否删除*/@Column(name = "deleted")private Integer deleted;
}
5.腾讯地图处理工具类
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;import java.util.HashMap;
import java.util.Objects;@Slf4j
@Component
public class TencentMapUtil {private String qqAk = "xxxxx-xxxxx-xxxxx-xxxxx-xxxxx-xxxxx";private String geoCoder = "https://apis.map.qq.com/ws/geocoder/v1/";private String distance = "https://apis.map.qq.com/ws/distance/v1/";private String translate = "https://apis.map.qq.com/ws/coord/v1/translate";private String reGeoCoder = "https://apis.map.qq.com/ws/geocoder/v1/?location=";/*** 通过地址查询经纬度** @param addr 地址* @return*/public String geoCoder(String addr) {JSONObject jsonObject = geoCoderRequest(addr);if (null == jsonObject) {return null;}JSONObject location = JSONUtil.parseObj(JSONUtil.toJsonStr(jsonObject.get("location")));if (Objects.nonNull(location) && Objects.nonNull(location.get("lat")) && Objects.nonNull(location.get("lng"))) {return location.get("lat").toString() + "," + location.get("lng").toString();}return null;}public JSONObject geoCoderRequest(String addr) {try {if (StringUtils.isNotEmpty(addr)) {String url = geoCoder +"?address=" + addr +"&key=" + qqAk;// 腾讯地图akString resultStr = HttpUtil.get(url);JSONObject tencentGeo = JSONUtil.parseObj(resultStr);log.info("地址转坐标响应结果:" + JSONUtil.toJsonStr(tencentGeo));if (Objects.nonNull(tencentGeo) && Objects.equals(0, tencentGeo.get("status"))) {return JSONUtil.parseObj(JSONUtil.toJsonStr(tencentGeo.get("result")));}}} catch (Exception e) {log.error("地址转坐标失败,地址:" + addr + ", e: " + e);}return null;}/*** 根据经纬度查询地址** @param lat 纬度* @param lng 经度* @return*/public JSONObject reGeoCoder(String lat, String lng) {StringBuilder url = new StringBuilder(reGeoCoder).append(lat).append(",").append(lng).append("&key=").append(qqAk);String resultStr = HttpUtil.get(url.toString());return JSONUtil.parseObj(resultStr);}/*** 将微信小程序经纬度转换成腾讯地图经纬度** @param lat 纬度* @param lng 经度* @return*/public JSONObject translate(String lat, String lng) {StringBuilder url = new StringBuilder(translate).append("?key=").append(qqAk)// 腾讯地图ak.append("&type=1")// 1.GPS坐标 2.sogou经纬度 3.baidu经纬度 4.mapbar经纬度 5.[默认]腾讯、google、高德坐标 6.sogou墨卡托.append("&&locations=").append(lat).append(",").append(lng);String resultStr = HttpUtil.get(url.toString());return JSONUtil.parseObj(resultStr);}}
6.region.sql文件
链接: https://pan.baidu.com/s/1m1WEgQPGXbUzgZ4qusvegQ 提取码: ztr6 复制这段内容后打开百度网盘手机App,操作更方便哦