小程序实现定位城市切换且城市根据首字母A-Z排序后端数据实现逻辑

news/2024/7/20 0:55:42 标签: 小程序, java, 城市定位, 省市区sql文件

场景:

话不多说后端提供数据实现步骤:

1.controller层

java">@Api(tags = {"[地区]-城市相关接口"})
@RestController
@RequestMapping("region")
@Slf4j
public class RegionController extends BaseController {

    @Resource
    private 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));
    }

    @Resource
    private 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层

java">@Service
@Slf4j
@Primary
public class RegionServiceImpl extends BaseApplicationService implements RegionService {

    @Resource
    private RegionMapper regionMapper;


    private static final char[] alphabet = new char[26];

    static {
        // 使用循环填充数组元素
        for (int i = 0; i < alphabet.length; i++) {
            alphabet[i] = (char) ('A' + i);
        }
    }

    @Override
    public 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;
    }

    @Override
    public 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;

    @Data
    public 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层

java">public interface RegionMapper extends CrudMapper<Region, Long> {


}


4.实体类

java">@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.腾讯地图处理工具类

java">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;// 腾讯地图ak
                String 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,操作更方便哦

 


http://www.niftyadmin.cn/n/5401033.html

相关文章

Android Shadow插件化框架分析与集成(一)

一、shadow源码导入及分析 1、下载项目源码 2、导入到Android studio 3、设置jdk及sdk版本 包/应用描述类型sample-constant公共字符串常量libsample-host宿主应用applicationsample-host-lib宿主应用依赖包libsample-manager是插件管理器的动态实现,主要负责加载插件和安装…

JavaScript引擎的工作原理:代码解析与执行

文章目录 JavaScript引擎的工作原理&#xff1a;代码解析与执行引言一、 JavaScript引擎简介二、JavaScript代码的执行过程1.解析&#xff08;Parsing&#xff09;2.编译&#xff08;Compilation&#xff09;2.编译&#xff08;Compilation&#xff09;3. JavaScript代码的优化…

云计算 2月20号 (认识操作系统)

1、认识操作系统 计算机系统的组成 知识点1&#xff1a;没有软件系统的计算机称之为"裸机" 知识点2&#xff1a;裸机提供基本的可计算性资源 知识点3&#xff1a;操作系统是最靠近硬件的软件层&#xff0c;负责管理和控制计算机硬件。 计算机硬件组成五大部件 运算器…

【刷题】位运算

消失的两个数字 消失的两个数字 “单身狗”进阶版思路 class Solution { public:vector<int> missingTwo(vector<int>& nums) {int ret 0;int n nums.size();for(int i 0; i < n; i){ret ^ (nums[i] ^ i);}ret ^ (n ^ (n 1) ^ (n 2));// 按位异或的…

【Android开发】01-第一个Android APP

一、改MainActivity class MainActivity : AppCompatActivity() {/*因Android的app有生命周期&#xff0c;故入口是OnCreate而不是main函数*/override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main…

VSCode上搭建C/C++开发环境(vscode配置c/c++环境)Windows系统---保姆级教程

引言劝退 VSCode&#xff0c;全称为Visual Studio Code&#xff0c;是由微软开发的一款轻量级&#xff0c;跨平台的代码编辑器。大家能来搜用VSCode配置c/c&#xff0c;想必也知道VSCode的强大&#xff0c;可以手握一个VSCode同时编写如C&#xff0c;C&#xff0c;C#&#xff…

比特币暴涨逼近历史最高点;阿里云全线降价20%丨 RTE 开发者日报 Vol.155

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

2024 年 20 个最佳移动应用测试工具

技术在不断发展&#xff0c;用户的期望也在不断发展。在这种情况下&#xff0c;组织面临的挑战是提供完美、直观且可靠的体验。这使得移动应用程序测试成为满足这些需求的开发过程的重要组成部分。测试可确保应用程序能够跨多种设备、操作系统和用户场景无缝运行&#xff0c;从…