From b9903ead016b8b1aa68eb04b48fca3b53fdab0d3 Mon Sep 17 00:00:00 2001
From: cloudroam <cloudroam>
Date: 星期一, 30 十二月 2024 10:42:43 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master-v4' into master-v4
---
src/main/java/com/mzl/flower/mapper/district/DistrictMapperCustom.java | 18
src/main/java/com/mzl/flower/dto/response/system/AreaDTO.java | 13
src/main/java/com/mzl/flower/dto/response/district/DistrictVO.java | 48 +
src/main/java/com/mzl/flower/mapper/district/DistrictTengxunMapper.java | 17
src/main/java/com/mzl/flower/mapper/district/DistrictMapper.java | 16
src/main/resources/mapper/district/DistrictMapperCustom.xml | 10
src/main/java/com/mzl/flower/service/impl/map/MapTengxunServiceImpl.java | 152 ++++
src/main/java/com/mzl/flower/service/impl/district/DistrictServiceImpl.java | 303 ++++++++
src/main/java/com/mzl/flower/dto/map/gaode/CityCodeTypeAdapter.java | 43 +
src/main/java/com/mzl/flower/service/map/MapTengxunService.java | 11
src/main/resources/mapper/district/DistrictMapper.xml | 22
src/main/java/com/mzl/flower/dto/map/gaode/GaodeDistrict.java | 99 ++
src/main/java/com/mzl/flower/config/TengxunMapProperties.java | 17
src/main/java/com/mzl/flower/config/GaodeMapProperties.java | 17
src/main/java/com/mzl/flower/service/impl/district/DistrictTengxunServiceImpl.java | 367 ++++++++++
src/main/java/com/mzl/flower/entity/district/DistrictTengxunDO.java | 46 +
src/main/resources/mapper/district/DistrictTengxunMapperCustom.xml | 10
src/main/java/com/mzl/flower/web/v2/district/DistrictTengxunController.java | 76 ++
src/main/java/com/mzl/flower/dto/map/tengxun/TengxunLocation.java | 25
src/main/java/com/mzl/flower/dto/request/district/QueryDistrictTengxunDTO.java | 8
src/main/java/com/mzl/flower/dto/request/district/CreateDistrictGaodeDTO.java | 59 +
src/main/resources/mapper/district/DistrictTengxunMapper.xml | 20
src/main/java/com/mzl/flower/schedule/MapScheduleService.java | 44 +
src/main/java/com/mzl/flower/service/district/DistrictTengxunService.java | 71 +
src/main/java/com/mzl/flower/service/impl/map/MapGaodeServiceImpl.java | 107 ++
src/main/java/com/mzl/flower/dto/request/district/CreateDistrictTengxunDTO.java | 50 +
src/main/java/com/mzl/flower/dto/response/district/DistrictTengxunVO.java | 13
src/main/java/com/mzl/flower/dto/map/gaode/GaodeMapResponse.java | 33
src/main/java/com/mzl/flower/service/map/MapGaodeService.java | 11
src/main/java/com/mzl/flower/web/system/ProvinceController.java | 25
src/main/java/com/mzl/flower/web/v2/district/DistrictGaodeController.java | 80 ++
src/main/java/com/mzl/flower/mapper/district/DistrictTengxunMapperCustom.java | 19
src/main/java/com/mzl/flower/dto/map/tengxun/TencentMapResponse.java | 40 +
src/main/java/com/mzl/flower/service/district/DistrictService.java | 80 ++
src/main/java/com/mzl/flower/entity/district/DistrictDO.java | 58 +
src/main/resources/application.yml | 13
src/main/java/com/mzl/flower/dto/map/tengxun/TengxunDistrict.java | 77 ++
37 files changed, 2,114 insertions(+), 4 deletions(-)
diff --git a/src/main/java/com/mzl/flower/config/GaodeMapProperties.java b/src/main/java/com/mzl/flower/config/GaodeMapProperties.java
new file mode 100644
index 0000000..1120473
--- /dev/null
+++ b/src/main/java/com/mzl/flower/config/GaodeMapProperties.java
@@ -0,0 +1,17 @@
+package com.mzl.flower.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Data
+@Component
+@ConfigurationProperties(prefix = "map.gaode")
+public class GaodeMapProperties {
+
+ /**
+ * 高德地图地址行政区划查询接口
+ */
+ private String administrativeDivisionsUrl;
+
+}
diff --git a/src/main/java/com/mzl/flower/config/TengxunMapProperties.java b/src/main/java/com/mzl/flower/config/TengxunMapProperties.java
new file mode 100644
index 0000000..9800a52
--- /dev/null
+++ b/src/main/java/com/mzl/flower/config/TengxunMapProperties.java
@@ -0,0 +1,17 @@
+package com.mzl.flower.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Data
+@Component
+@ConfigurationProperties(prefix = "map.tengxun")
+public class TengxunMapProperties {
+
+ /**
+ * 腾讯地图地址行政区划查询接口
+ */
+ private String administrativeDivisionsUrl;
+
+}
diff --git a/src/main/java/com/mzl/flower/dto/map/gaode/CityCodeTypeAdapter.java b/src/main/java/com/mzl/flower/dto/map/gaode/CityCodeTypeAdapter.java
new file mode 100644
index 0000000..3bc877a
--- /dev/null
+++ b/src/main/java/com/mzl/flower/dto/map/gaode/CityCodeTypeAdapter.java
@@ -0,0 +1,43 @@
+package com.mzl.flower.dto.map.gaode;
+import com.google.gson.TypeAdapter;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonToken;
+import com.google.gson.stream.JsonWriter;
+
+import java.io.IOException;
+
+public class CityCodeTypeAdapter extends TypeAdapter<String> {
+ @Override
+ public void write(JsonWriter out, String value) throws IOException {
+ if (value == null) {
+ out.nullValue();
+ } else {
+ out.value(value);
+ }
+ }
+
+ @Override
+ public String read(JsonReader in) throws IOException {
+ if (in.peek() == JsonToken.BEGIN_ARRAY) {
+ // 处理数组类型
+ StringBuilder result = new StringBuilder();
+ in.beginArray();
+ while (in.hasNext()) {
+ if (result.length() > 0) {
+ result.append(",");
+ }
+ result.append(in.nextString());
+ }
+ in.endArray();
+ return result.toString();
+ } else if (in.peek() == JsonToken.STRING) {
+ // 处理字符串类型
+ return in.nextString();
+ } else if (in.peek() == JsonToken.NULL) {
+ in.nextNull();
+ return "";
+ } else {
+ throw new IllegalStateException("Unexpected JSON type: " + in.peek());
+ }
+ }
+}
diff --git a/src/main/java/com/mzl/flower/dto/map/gaode/GaodeDistrict.java b/src/main/java/com/mzl/flower/dto/map/gaode/GaodeDistrict.java
new file mode 100644
index 0000000..4e7759a
--- /dev/null
+++ b/src/main/java/com/mzl/flower/dto/map/gaode/GaodeDistrict.java
@@ -0,0 +1,99 @@
+package com.mzl.flower.dto.map.gaode;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.google.gson.annotations.JsonAdapter;
+import com.mzl.flower.dto.map.tengxun.TengxunLocation;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+// 行政区划对象
+
+/**
+ * 代码共6位,前两位代表省(一级)、中间两位为市/地区(二级),最后两位为区县(三级)
+ * 1)省级:前两位有值,后4位置0,如,河北省:130000
+ * 2)市/地区:前4四位有值,包含省代码与市代码,最后两位置0,如河北省保定市:130600
+ * 3)区县:6位全有值,包含前4位省市代码及区县代码,河北省保定市涿州市:130681
+ * 4)直辖市、香港、澳门:
+ * 同省级,在行政区划接口(ws/district/v1/list)中,其下直接为区级(没有二级结构填充)
+ * 例:北京,东城区 (而非:“北京,北京,东城区”)
+ * 5)直辖县:第3、4位为90的,为省直辖县
+ * 6)中国范围内,省市区行政区划以外的区域值为999999(如中国东海)
+ * 7)东莞市、中山市、儋州市、嘉峪关市 因其下无区县级,因此增加了末位为99代码的同名子级,用于补齐到三级区划的结构
+ *
+ * 如何获取城市编码(city_code):
+ * 1)编码前4位不为0,第5、6位为0的,为常规城市,可直接取用
+ * 2)北京、上海、重庆、天津、香港、澳门,编码和省一致,需要单独提出
+ * 3)第3、4位为90的为省直辖县,一般当做城市来应用,也需要单独提出
+ */
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class GaodeDistrict {
+
+ private String id;
+ /**
+ * 城市编码
+ */
+ @JsonAdapter(CityCodeTypeAdapter.class)
+ private String citycode;
+ /**
+ * 区域编码
+ * 街道没有独有的 adcode,均继承父类(区县)的 adcode
+ */
+ private String adcode;
+ /**
+ * 行政区名称
+ */
+ private String name;
+
+ /**
+ * 行政区边界坐标点
+ * 当一个行政区范围,由完全分隔两块或者多块的地块组
+ *
+ * 成,每块地的 polyline 坐标串以 | 分隔 。
+ *
+ * 如北京 的 朝阳区
+ *
+ */
+ private String polyline;
+
+
+ /**
+ *
+ * 区域中心点
+ * 乡镇级别返回的center是边界线上的形点,其他行政级别返回的center不一定是中心点,若政府机构位于面内,则返回政府坐标,政府不在面内,则返回繁华点坐标
+ */
+ private String center;
+
+ /**
+ * 行政区划级别
+ *
+ * country:国家
+ *
+ * province:省份(直辖市会在province显示)
+ *
+ * city:市(直辖市会在province显示)
+ *
+ * district:区县
+ *
+ * street:街道
+ *
+ */
+ private String level;
+
+ /**
+ * 下级行政区列表,包含 district 元素
+ */
+ private List<GaodeDistrict> districts;
+
+ /**
+ * 行政区划父级别唯一标识(adcode)
+ */
+ private String parentId;
+}
\ No newline at end of file
diff --git a/src/main/java/com/mzl/flower/dto/map/gaode/GaodeMapResponse.java b/src/main/java/com/mzl/flower/dto/map/gaode/GaodeMapResponse.java
new file mode 100644
index 0000000..8ced6d9
--- /dev/null
+++ b/src/main/java/com/mzl/flower/dto/map/gaode/GaodeMapResponse.java
@@ -0,0 +1,33 @@
+package com.mzl.flower.dto.map.gaode;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+
+import java.util.List;
+
+// 顶层对象
+@JsonIgnoreProperties(ignoreUnknown = true)
+@Data
+public class GaodeMapResponse {
+ /**
+ * 返回结果状态值
+ * 值为0或1,0表示失败;1表示成功
+ */
+ private String status;
+ /**
+ * 返回状态说明
+ */
+ private String info;
+ /**
+ * 状态码
+ * 返回状态说明,10000代表正确,详情参阅 info 状态表
+ */
+ private String infocode;
+ private int count;
+ /**
+ * 行政区列表
+ */
+ private List<GaodeDistrict> districts;
+}
+
+
diff --git a/src/main/java/com/mzl/flower/dto/map/tengxun/TencentMapResponse.java b/src/main/java/com/mzl/flower/dto/map/tengxun/TencentMapResponse.java
new file mode 100644
index 0000000..d8c0cbe
--- /dev/null
+++ b/src/main/java/com/mzl/flower/dto/map/tengxun/TencentMapResponse.java
@@ -0,0 +1,40 @@
+package com.mzl.flower.dto.map.tengxun;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+import java.util.List;
+
+// 顶层对象
+@JsonIgnoreProperties(ignoreUnknown = true)
+@Data
+public class TencentMapResponse {
+ private int status;
+ private String message;
+ private String requestId;
+ private int dataVersion;
+ private List<TengxunDistrict> result;
+
+ @SerializedName("request_id")
+ public String getRequestId() {
+ return requestId;
+ }
+
+ @SerializedName("request_id")
+ public void setRequestId(String requestId) {
+ this.requestId = requestId;
+ }
+
+ @SerializedName("data_version")
+ public int getDataVersion() {
+ return dataVersion;
+ }
+
+ @SerializedName("data_version")
+ public void setDataVersion(int dataVersion) {
+ this.dataVersion = dataVersion;
+ }
+}
+
+
diff --git a/src/main/java/com/mzl/flower/dto/map/tengxun/TengxunDistrict.java b/src/main/java/com/mzl/flower/dto/map/tengxun/TengxunDistrict.java
new file mode 100644
index 0000000..f4c54a6
--- /dev/null
+++ b/src/main/java/com/mzl/flower/dto/map/tengxun/TengxunDistrict.java
@@ -0,0 +1,77 @@
+package com.mzl.flower.dto.map.tengxun;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import java.util.List;
+
+// 行政区划对象
+
+/**
+ * 代码共6位,前两位代表省(一级)、中间两位为市/地区(二级),最后两位为区县(三级)
+ * 1)省级:前两位有值,后4位置0,如,河北省:130000
+ * 2)市/地区:前4四位有值,包含省代码与市代码,最后两位置0,如河北省保定市:130600
+ * 3)区县:6位全有值,包含前4位省市代码及区县代码,河北省保定市涿州市:130681
+ * 4)直辖市、香港、澳门:
+ * 同省级,在行政区划接口(ws/district/v1/list)中,其下直接为区级(没有二级结构填充)
+ * 例:北京,东城区 (而非:“北京,北京,东城区”)
+ * 5)直辖县:第3、4位为90的,为省直辖县
+ * 6)中国范围内,省市区行政区划以外的区域值为999999(如中国东海)
+ * 7)东莞市、中山市、儋州市、嘉峪关市 因其下无区县级,因此增加了末位为99代码的同名子级,用于补齐到三级区划的结构
+ *
+ * 如何获取城市编码(city_code):
+ * 1)编码前4位不为0,第5、6位为0的,为常规城市,可直接取用
+ * 2)北京、上海、重庆、天津、香港、澳门,编码和省一致,需要单独提出
+ * 3)第3、4位为90的为省直辖县,一般当做城市来应用,也需要单独提出
+ */
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class TengxunDistrict {
+
+ /**
+ * 行政区划唯一标识(adcode)
+ */
+ private String id;
+ /**
+ * 行政区划唯一标识(adcode)
+ */
+ private String code;
+ /**
+ * 简称,如“内蒙古”
+ */
+ private String name;
+ /**
+ * 全称,如“内蒙古自治区”
+ */
+ private String fullname;
+
+ /**
+ * 行政区划级别
+ */
+ private Integer level;
+
+ /**
+ * 行政区划拼音,每一下标为一个字的全拼,如:
+ * [“nei”,“meng”,“gu”]
+ */
+ private List<String> pinyin;
+ /**
+ * 经纬度
+ */
+ private TengxunLocation tengxunLocation;
+ /**
+ * 当前区划的下级区划信息,结构与当前区划一致,如果没有下级区划则不返回此字段
+ * 行政区划代码(adcode)规则说明
+ */
+ private List<TengxunDistrict> districts;
+
+
+ /**
+ * 行政区划父级别唯一标识(adcode)
+ */
+ private String parentId;
+}
\ No newline at end of file
diff --git a/src/main/java/com/mzl/flower/dto/map/tengxun/TengxunLocation.java b/src/main/java/com/mzl/flower/dto/map/tengxun/TengxunLocation.java
new file mode 100644
index 0000000..f9d48aa
--- /dev/null
+++ b/src/main/java/com/mzl/flower/dto/map/tengxun/TengxunLocation.java
@@ -0,0 +1,25 @@
+package com.mzl.flower.dto.map.tengxun;
+
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+// 经纬度对象
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class TengxunLocation {
+
+ /**
+ * 纬度
+ */
+ private double lat;
+ /**
+ * 经度
+ */
+ private double lng;
+
+}
diff --git a/src/main/java/com/mzl/flower/dto/request/district/CreateDistrictGaodeDTO.java b/src/main/java/com/mzl/flower/dto/request/district/CreateDistrictGaodeDTO.java
new file mode 100644
index 0000000..154a75f
--- /dev/null
+++ b/src/main/java/com/mzl/flower/dto/request/district/CreateDistrictGaodeDTO.java
@@ -0,0 +1,59 @@
+package com.mzl.flower.dto.request.district;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+
+@Data
+@ApiModel("高德地图的行政区划 ")
+public class CreateDistrictGaodeDTO {
+
+ private String id;
+
+ /**
+ * 名称
+ */
+ @ApiModelProperty(value = "name")
+ @NotEmpty(message = "名称不能为空")
+ private String name;
+
+ /**
+ * 区域编码
+ */
+ @ApiModelProperty(value = "citycode")
+ private String citycode;
+
+ /**
+ * 区域编码
+ */
+ @NotEmpty(message = "区域编码不能为空")
+ @ApiModelProperty(value = "adcode")
+ private String adcode;
+
+
+ /**
+ * 行政区域边界坐标点
+ */
+ @ApiModelProperty(value = "adcode")
+ private String polyline;
+
+ /**
+ * 区域中心点
+ */
+ @ApiModelProperty(value = "adcode")
+ private String center;
+
+
+ @ApiModelProperty(value = "等级")
+ private String level;
+
+ /**
+ * 父id
+ */
+ @ApiModelProperty(value = "父id")
+ private String parentId;
+
+
+}
diff --git a/src/main/java/com/mzl/flower/dto/request/district/CreateDistrictTengxunDTO.java b/src/main/java/com/mzl/flower/dto/request/district/CreateDistrictTengxunDTO.java
new file mode 100644
index 0000000..f0f918e
--- /dev/null
+++ b/src/main/java/com/mzl/flower/dto/request/district/CreateDistrictTengxunDTO.java
@@ -0,0 +1,50 @@
+package com.mzl.flower.dto.request.district;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiOperation;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+
+@Data
+@ApiModel("腾讯地图的行政区划 ")
+public class CreateDistrictTengxunDTO {
+
+ private String id;
+
+ /**
+ * 名称
+ */
+ @ApiModelProperty(value = "name")
+ @NotEmpty(message = "名称不能为空")
+ private String name;
+
+ /**
+ * 全称
+ */
+ @ApiModelProperty(value = "fullname")
+ @NotEmpty(message = "全称不能为空")
+ private String fullname;
+
+ /**
+ * 区域编码
+ */
+ @ApiModelProperty(value = "code")
+ @NotEmpty(message = "编码不能为空")
+ private String code;
+
+
+ @ApiModelProperty(value = "等级")
+ private Integer level;
+
+ /**
+ * 父id
+ */
+ @ApiModelProperty(value = "父id")
+ private String parentId;
+
+
+
+}
diff --git a/src/main/java/com/mzl/flower/dto/request/district/QueryDistrictTengxunDTO.java b/src/main/java/com/mzl/flower/dto/request/district/QueryDistrictTengxunDTO.java
new file mode 100644
index 0000000..c5333cc
--- /dev/null
+++ b/src/main/java/com/mzl/flower/dto/request/district/QueryDistrictTengxunDTO.java
@@ -0,0 +1,8 @@
+package com.mzl.flower.dto.request.district;
+
+import lombok.Data;
+
+@Data
+public class QueryDistrictTengxunDTO {
+
+}
diff --git a/src/main/java/com/mzl/flower/dto/response/district/DistrictTengxunVO.java b/src/main/java/com/mzl/flower/dto/response/district/DistrictTengxunVO.java
new file mode 100644
index 0000000..969dadd
--- /dev/null
+++ b/src/main/java/com/mzl/flower/dto/response/district/DistrictTengxunVO.java
@@ -0,0 +1,13 @@
+package com.mzl.flower.dto.response.district;
+
+import com.mzl.flower.entity.district.DistrictTengxunDO;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class DistrictTengxunVO extends DistrictTengxunDO {
+
+ List<DistrictTengxunVO> children;
+
+}
diff --git a/src/main/java/com/mzl/flower/dto/response/district/DistrictVO.java b/src/main/java/com/mzl/flower/dto/response/district/DistrictVO.java
new file mode 100644
index 0000000..8e94a7c
--- /dev/null
+++ b/src/main/java/com/mzl/flower/dto/response/district/DistrictVO.java
@@ -0,0 +1,48 @@
+package com.mzl.flower.dto.response.district;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class DistrictVO {
+
+ private String id;
+
+ /**
+ * 名称
+ */
+ private String name;
+
+ /**
+ * 城市编码
+ */
+ private String citycode;
+
+ /**
+ * 区域编码
+ */
+ private String adcode;
+
+ /**
+ * 行政区域边界坐标点
+ */
+ private String polyline;
+
+ /**
+ * 区域中心点
+ */
+ private String center;
+
+ /**
+ * 行政区划级别(country国家 province 省份 city市 district 区县 street街道)
+ */
+ private String level;
+ /**
+ * 父id
+ */
+ private String parentId;
+
+
+ List<DistrictVO> children;
+}
diff --git a/src/main/java/com/mzl/flower/dto/response/system/AreaDTO.java b/src/main/java/com/mzl/flower/dto/response/system/AreaDTO.java
index fd56223..8c45a82 100644
--- a/src/main/java/com/mzl/flower/dto/response/system/AreaDTO.java
+++ b/src/main/java/com/mzl/flower/dto/response/system/AreaDTO.java
@@ -1,12 +1,23 @@
package com.mzl.flower.dto.response.system;
+import lombok.AllArgsConstructor;
import lombok.Data;
+import lombok.NoArgsConstructor;
+import java.util.ArrayList;
import java.util.List;
@Data
+@NoArgsConstructor
+@AllArgsConstructor
public class AreaDTO {
private String code;
private String name;
- private List<AreaDTO> children;
+ private List<AreaDTO> children=new ArrayList<>();
+
+ public AreaDTO(String code, String name) {
+ this.code = code;
+ this.name = name;
+ }
+
}
diff --git a/src/main/java/com/mzl/flower/entity/district/DistrictDO.java b/src/main/java/com/mzl/flower/entity/district/DistrictDO.java
new file mode 100644
index 0000000..3e6b79e
--- /dev/null
+++ b/src/main/java/com/mzl/flower/entity/district/DistrictDO.java
@@ -0,0 +1,58 @@
+package com.mzl.flower.entity.district;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.mzl.flower.base.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * 对接高德地图行政区划
+ *
+ * @author @TaoJie
+ * @since 2024-12-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@Accessors(chain = true)
+@TableName("t_district")
+public class DistrictDO extends BaseEntity {
+
+
+ /**
+ * 名称
+ */
+ private String name;
+
+ /**
+ * 城市编码
+ */
+ private String citycode;
+
+ /**
+ * 区域编码
+ */
+ private String adcode;
+
+ /**
+ * 行政区域边界坐标点
+ */
+ private String polyline;
+
+ /**
+ * 区域中心点
+ */
+ private String center;
+
+ /**
+ * 行政区划级别(country国家 province 省份 city市 district 区县 street街道)
+ */
+ private String level;
+
+ /**
+ * 父id
+ */
+ private String parentId;
+
+
+}
diff --git a/src/main/java/com/mzl/flower/entity/district/DistrictTengxunDO.java b/src/main/java/com/mzl/flower/entity/district/DistrictTengxunDO.java
new file mode 100644
index 0000000..3bc8f84
--- /dev/null
+++ b/src/main/java/com/mzl/flower/entity/district/DistrictTengxunDO.java
@@ -0,0 +1,46 @@
+package com.mzl.flower.entity.district;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.mzl.flower.base.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * 对接高德地图行政区划
+ *
+ * @author @TaoJie
+ * @since 2024-12-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@Accessors(chain = true)
+@TableName("t_district_tengxun")
+public class DistrictTengxunDO extends BaseEntity {
+
+
+ /**
+ * 名称
+ */
+ private String name;
+
+ /**
+ * 城市编码
+ */
+ private String fullname;
+
+ /**
+ * 区域编码
+ */
+ private String code;
+
+
+ private Integer level;
+
+ /**
+ * 父id
+ */
+ private String parentId;
+
+
+}
diff --git a/src/main/java/com/mzl/flower/mapper/district/DistrictMapper.java b/src/main/java/com/mzl/flower/mapper/district/DistrictMapper.java
new file mode 100644
index 0000000..546b0a0
--- /dev/null
+++ b/src/main/java/com/mzl/flower/mapper/district/DistrictMapper.java
@@ -0,0 +1,16 @@
+package com.mzl.flower.mapper.district;
+
+import com.mzl.flower.entity.district.DistrictDO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 对接高德地图行政区划 Mapper 接口
+ * </p>
+ *
+ * @author @TaoJie
+ * @since 2024-12-19
+ */
+public interface DistrictMapper extends BaseMapper<DistrictDO> {
+
+}
diff --git a/src/main/java/com/mzl/flower/mapper/district/DistrictMapperCustom.java b/src/main/java/com/mzl/flower/mapper/district/DistrictMapperCustom.java
new file mode 100644
index 0000000..a4c598f
--- /dev/null
+++ b/src/main/java/com/mzl/flower/mapper/district/DistrictMapperCustom.java
@@ -0,0 +1,18 @@
+package com.mzl.flower.mapper.district;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.mzl.flower.entity.district.DistrictDO;
+
+/**
+ * <p>
+ * 对接高德地图行政区划 Mapper 接口
+ * </p>
+ *
+ * @author @TaoJie
+ * @since 2024-12-19
+ */
+public interface DistrictMapperCustom extends BaseMapper<DistrictDO> {
+
+ void removeAllDistricts();
+
+}
diff --git a/src/main/java/com/mzl/flower/mapper/district/DistrictTengxunMapper.java b/src/main/java/com/mzl/flower/mapper/district/DistrictTengxunMapper.java
new file mode 100644
index 0000000..1a9d587
--- /dev/null
+++ b/src/main/java/com/mzl/flower/mapper/district/DistrictTengxunMapper.java
@@ -0,0 +1,17 @@
+package com.mzl.flower.mapper.district;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.mzl.flower.entity.district.DistrictDO;
+import com.mzl.flower.entity.district.DistrictTengxunDO;
+
+/**
+ * <p>
+ * 对接高德地图行政区划 Mapper 接口
+ * </p>
+ *
+ * @author @TaoJie
+ * @since 2024-12-19
+ */
+public interface DistrictTengxunMapper extends BaseMapper<DistrictTengxunDO> {
+
+}
diff --git a/src/main/java/com/mzl/flower/mapper/district/DistrictTengxunMapperCustom.java b/src/main/java/com/mzl/flower/mapper/district/DistrictTengxunMapperCustom.java
new file mode 100644
index 0000000..42215a2
--- /dev/null
+++ b/src/main/java/com/mzl/flower/mapper/district/DistrictTengxunMapperCustom.java
@@ -0,0 +1,19 @@
+package com.mzl.flower.mapper.district;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.mzl.flower.entity.district.DistrictDO;
+import com.mzl.flower.entity.district.DistrictTengxunDO;
+
+/**
+ * <p>
+ * 对接高德地图行政区划 Mapper 接口
+ * </p>
+ *
+ * @author @TaoJie
+ * @since 2024-12-19
+ */
+public interface DistrictTengxunMapperCustom extends BaseMapper<DistrictTengxunDO> {
+
+ void removeAllDistricts();
+
+}
diff --git a/src/main/java/com/mzl/flower/schedule/MapScheduleService.java b/src/main/java/com/mzl/flower/schedule/MapScheduleService.java
new file mode 100644
index 0000000..1369c3d
--- /dev/null
+++ b/src/main/java/com/mzl/flower/schedule/MapScheduleService.java
@@ -0,0 +1,44 @@
+package com.mzl.flower.schedule;
+
+import com.mzl.flower.service.district.DistrictTengxunService;
+import com.mzl.flower.service.map.MapGaodeService;
+import com.mzl.flower.service.map.MapTengxunService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+@Component
+@Slf4j
+public class MapScheduleService {
+
+ @Autowired
+ private MapTengxunService mapTengxunService;
+
+ @Autowired
+ private MapGaodeService mapGaodeService;
+
+ @Autowired
+ private DistrictTengxunService districtTengxunService;
+
+
+
+
+ /**
+ * 每个月第一天凌晨5点执行一次
+ */
+// @Scheduled(cron = "5 * * * * ?")
+ @Scheduled(cron = "0 5 0 1 * ?")
+ public void expiredPointGoodsRecord() {
+
+ // 高德地图解析-行政区划
+// mapGaodeService.getAdministrativeDivision();
+ // 腾讯地图解析-行政区划
+ mapTengxunService.getAdministrativeDivision();
+
+// districtTengxunService.refreshDistrict();
+
+ }
+
+
+}
diff --git a/src/main/java/com/mzl/flower/service/district/DistrictService.java b/src/main/java/com/mzl/flower/service/district/DistrictService.java
new file mode 100644
index 0000000..91769e2
--- /dev/null
+++ b/src/main/java/com/mzl/flower/service/district/DistrictService.java
@@ -0,0 +1,80 @@
+package com.mzl.flower.service.district;
+
+import com.mzl.flower.dto.request.district.CreateDistrictGaodeDTO;
+import com.mzl.flower.dto.response.district.DistrictVO;
+import com.mzl.flower.dto.response.system.AreaDTO;
+import com.mzl.flower.entity.district.DistrictDO;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 对接高德地图行政区划 服务类
+ * </p>
+ *
+ * @author @TaoJie
+ * @since 2024-12-19
+ */
+public interface DistrictService extends IService<DistrictDO> {
+
+ void removeAllDistricts();
+
+ void refreshDistrict();
+
+ /**
+ * 获取所有的行政区划列表
+ * @return
+ */
+ List<DistrictDO> getAllDistrict();
+
+ /**
+ * 从数据库里面获取
+ * @return
+ */
+ List<AreaDTO> getAreaDTOListByDB();
+
+ /**
+ * 从JSON文件里面获取
+ * @return
+ */
+ List<AreaDTO> getAreaDTOListByJsonFile();
+
+
+ /**
+ * 保存高德数据库入数据库
+ * @param districtDOList
+ */
+ void saveRemoteDistricts(List<DistrictDO> districtDOList);
+
+ List<DistrictVO> getDistrictTreeList();
+
+ /**
+ * 创建行政区划
+ * @param dto
+ * @return
+ */
+ boolean createDistrict(CreateDistrictGaodeDTO dto);
+
+ /**
+ * 更新行政区划
+ * @param dto
+ * @return
+ */
+ boolean updateDistrict(CreateDistrictGaodeDTO dto);
+
+ /**
+ * 删除行政区划
+ * @param id
+ * @return
+ */
+ boolean deleteDistrict(String id);
+
+ /**
+ * 获取行政区划
+ * @return
+ */
+ String getChineseArea();
+
+ void clearChineseDataCache();
+}
diff --git a/src/main/java/com/mzl/flower/service/district/DistrictTengxunService.java b/src/main/java/com/mzl/flower/service/district/DistrictTengxunService.java
new file mode 100644
index 0000000..5b7f829
--- /dev/null
+++ b/src/main/java/com/mzl/flower/service/district/DistrictTengxunService.java
@@ -0,0 +1,71 @@
+package com.mzl.flower.service.district;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.mzl.flower.dto.request.district.CreateDistrictTengxunDTO;
+import com.mzl.flower.dto.response.district.DistrictTengxunVO;
+import com.mzl.flower.dto.response.system.AreaDTO;
+import com.mzl.flower.entity.district.DistrictTengxunDO;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 对接高德地图行政区划 服务类
+ * </p>
+ *
+ * @author @TaoJie
+ * @since 2024-12-19
+ */
+public interface DistrictTengxunService extends IService<DistrictTengxunDO> {
+
+ void removeAllDistricts();
+
+ void refreshDistrict();
+
+ /**
+ * 获取所有的行政区划列表
+ * @return
+ */
+ List<DistrictTengxunDO> getAllDistrict();
+
+ /**
+ * 从数据库里面获取
+ * @return
+ */
+ List<AreaDTO> getAreaDTOListByDB();
+
+ /**
+ * 从JSON文件里面获取
+ * @return
+ */
+ List<AreaDTO> getAreaDTOListByJsonFile();
+
+
+ /**
+ * 将远程的数据保存入库
+ * @param districtTengxunDOList
+ */
+ void saveRemoteDistricts(List<DistrictTengxunDO> districtTengxunDOList);
+
+ List<DistrictTengxunVO> getDistrictTreeList();
+
+ /**
+ * 创建行政区
+ * @param dto
+ * @return
+ */
+ boolean createDistrict(CreateDistrictTengxunDTO dto);
+
+ /**
+ * 删除行政区划及所有下级
+ * @param id
+ * @return
+ */
+ boolean deleteDistrict(String id);
+
+ boolean updateDistrict(CreateDistrictTengxunDTO dto);
+
+ String getChineseArea();
+
+ void clearChineseDataCache();
+}
diff --git a/src/main/java/com/mzl/flower/service/impl/district/DistrictServiceImpl.java b/src/main/java/com/mzl/flower/service/impl/district/DistrictServiceImpl.java
new file mode 100644
index 0000000..9eebb91
--- /dev/null
+++ b/src/main/java/com/mzl/flower/service/impl/district/DistrictServiceImpl.java
@@ -0,0 +1,303 @@
+package com.mzl.flower.service.impl.district;
+
+import cn.hutool.core.util.IdUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.google.gson.Gson;
+import com.mzl.flower.base.cache.StringCacheClient;
+import com.mzl.flower.config.exception.ValidationException;
+import com.mzl.flower.config.security.SecurityUtils;
+import com.mzl.flower.dto.request.district.CreateDistrictGaodeDTO;
+import com.mzl.flower.dto.response.district.DistrictVO;
+import com.mzl.flower.dto.response.system.AreaDTO;
+import com.mzl.flower.entity.district.DistrictDO;
+import com.mzl.flower.entity.district.DistrictTengxunDO;
+import com.mzl.flower.mapper.district.DistrictMapper;
+import com.mzl.flower.mapper.district.DistrictMapperCustom;
+import com.mzl.flower.service.district.DistrictService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.mzl.flower.utils.ConverterUtil;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+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.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ * 对接高德地图行政区划 服务实现类
+ * </p>
+ *
+ * @author @TaoJie
+ * @since 2024-12-19
+ */
+@Service
+public class DistrictServiceImpl extends ServiceImpl<DistrictMapper, DistrictDO> implements DistrictService {
+
+ @Autowired
+ private DistrictMapperCustom districtMapperCustom;
+
+ @Autowired
+ private StringCacheClient stringCacheClient;
+ @Override
+ public void removeAllDistricts() {
+ districtMapperCustom.removeAllDistricts();
+ }
+
+ @Override
+ public void refreshDistrict() {
+ // 获取所有的数据,并组织成树形结构
+ List<DistrictDO> districtDOList = getAllDistrict();
+ List<DistrictVO> districtVOList= ConverterUtil.transList(districtDOList, DistrictVO.class);
+ if(CollectionUtils.isNotEmpty(districtDOList)){
+ // 找出parent_id 是null的为根节点
+ Optional<DistrictVO> root = districtVOList.stream().filter(districtVO -> districtVO.getParentId() == null).findFirst();
+ // 遍历districtDOList,形成树形结构
+ if(null!=root && root.isPresent()){
+ DistrictVO rootNode = root.get();
+ // 构建树形结构
+ buildTree(rootNode, districtVOList);
+ // 查看这里的树形状结构,将这里的树型转换成之前前端使用的结构
+ AreaDTO areaDTO = transform(rootNode);
+ Gson gson=new Gson();
+ System.out.println("整个中国地图的json");
+ System.out.println(gson.toJson(areaDTO));
+ System.out.println("整个中国地图下城市的json");
+ System.out.println(gson.toJson(areaDTO.getChildren()));
+
+ }
+
+ }
+ // 根据id和partent_id 构造出行政区划字典
+// AreaDTO areaDTO = AreaDTO.build(districtDOList);
+
+ }
+
+
+ // 递归构建树形结构
+ private static void buildTree(DistrictVO parent, List<DistrictVO> allNodes) {
+ List<DistrictVO> children = allNodes.stream()
+ .filter(node -> parent.getId().equals(node.getParentId()))
+ .collect(Collectors.toList());
+
+ parent.setChildren(children);
+
+ for (DistrictVO child : children) {
+ buildTree(child, allNodes);
+ }
+ }
+
+ // 转换方法
+ public static AreaDTO transform(DistrictVO sourceNode) {
+ if (sourceNode == null) {
+ return null;
+ }
+
+ // 映射当前节点
+ AreaDTO targetNode = new AreaDTO(sourceNode.getName(), sourceNode.getName());
+
+ // 递归映射子节点
+ if (sourceNode.getChildren() != null) {
+ for (DistrictVO child : sourceNode.getChildren()) {
+ targetNode.getChildren().add(transform(child));
+ }
+ }
+
+ return targetNode;
+ }
+
+
+ @Override
+ public List<DistrictDO> getAllDistrict() {
+ return baseMapper.selectList(new LambdaQueryWrapper<DistrictDO>().eq(DistrictDO::getDeleted, false).orderByAsc(DistrictDO::getAdcode));
+ }
+
+ @Override
+ public List<AreaDTO> getAreaDTOListByDB() {
+ return null;
+ }
+
+ @Override
+ public List<AreaDTO> getAreaDTOListByJsonFile() {
+ return null;
+ }
+
+ @Override
+ public void saveRemoteDistricts(List<DistrictDO> districtDOList) {
+ // 先把所有数据放入缓存
+ removeAllDistricts();
+
+ districtDOList.stream().forEach(districtDO -> {
+ districtDO.create();
+ districtDO.setCreateBy("system");
+ districtDO.setUpdateBy("system");
+ });
+ // 保存数据入库
+ saveBatch(districtDOList);
+
+// saveOrUpdateBatch(districtDOList)
+ }
+
+ @Override
+ public List<DistrictVO> getDistrictTreeList() {
+ // 获取所有的数据,并组织成树形结构
+ List<DistrictDO> districtDOList = getAllDistrict();
+ List<DistrictVO> districtVOList= ConverterUtil.transList(districtDOList, DistrictVO.class);
+ if(CollectionUtils.isNotEmpty(districtDOList)){
+ // 找出parent_id 是null的为根节点
+ Optional<DistrictVO> root = districtVOList.stream().filter(districtVO -> districtVO.getParentId() == null).findFirst();
+ // 遍历districtDOList,形成树形结构
+ if(null!=root && root.isPresent()){
+ DistrictVO rootNode = root.get();
+ // 构建树形结构
+ buildTree(rootNode, districtVOList);
+ return rootNode.getChildren();
+
+ }
+
+ }
+ return null;
+ }
+
+ @Transactional
+ @Override
+ public boolean createDistrict(CreateDistrictGaodeDTO dto) {
+
+ // 查看相同节点下的名称是否存在,这里的partentId可能是null的情况
+
+ if(StringUtils.isBlank(dto.getParentId())){
+ // 获取根节点 adcode=100000
+ LambdaQueryWrapper<DistrictDO> queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(DistrictDO::getDeleted, false).eq(DistrictDO::getAdcode,"100000");
+ List<DistrictDO> list = list(queryWrapper);
+ if(CollectionUtils.isNotEmpty(list)){
+ DistrictDO districtDO = list.get(0);
+ dto.setParentId(districtDO.getId());
+ }
+
+ }
+
+ if(StringUtils.isNotBlank(dto.getName())){
+ LambdaQueryWrapper<DistrictDO> queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(DistrictDO::getDeleted, false).eq(DistrictDO::getName, dto.getName());
+ if (dto.getParentId() == null) {
+ queryWrapper.isNull(DistrictDO::getParentId);
+ } else {
+ queryWrapper.eq(DistrictDO::getParentId, dto.getParentId());
+ }
+ if (count(queryWrapper)>0) {
+ throw new ValidationException("当前名称已经存在");
+ }
+ }
+
+
+ DistrictDO districtDO =new DistrictDO();
+ BeanUtils.copyProperties(dto,districtDO);
+
+ districtDO.setId(IdUtil.simpleUUID());
+ districtDO.create(SecurityUtils.getUserId());
+
+
+ boolean result= save(districtDO);
+ // 清空缓存
+ clearChineseDataCache();
+ return result;
+ }
+
+ @Transactional
+ @Override
+ public boolean updateDistrict(CreateDistrictGaodeDTO dto) {
+ DistrictDO existsDistrict = getById(dto.getId());
+ if(Objects.isNull(existsDistrict)){
+ throw new ValidationException("当前id不存在");
+ }
+
+ if(StringUtils.isNotBlank(dto.getName())){
+ LambdaQueryWrapper<DistrictDO> queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(DistrictDO::getDeleted, false)
+ .eq(DistrictDO::getName, dto.getName())
+ .ne(DistrictDO::getId,dto.getId());
+ if (dto.getParentId() == null) {
+ queryWrapper.isNull(DistrictDO::getParentId);
+ } else {
+ queryWrapper.eq(DistrictDO::getParentId, dto.getParentId());
+ }
+ if (count(queryWrapper)>0) {
+ throw new ValidationException("当前名称已经存在");
+ }
+ }
+
+
+ BeanUtils.copyProperties(dto, existsDistrict);
+ existsDistrict.update(SecurityUtils.getUserId());
+
+ boolean result= updateById(existsDistrict);
+ // 清空缓存
+ clearChineseDataCache();
+
+ return result;
+
+ }
+
+ @Transactional
+ @Override
+ public boolean deleteDistrict(String id) {
+ DistrictDO existsDistrict = getById(id);
+ existsDistrict.update(SecurityUtils.getUserId());
+ existsDistrict.setDeleted(true);
+ updateById(existsDistrict);
+
+ List<DistrictDO> childrenList = list(new LambdaQueryWrapper<DistrictDO>().eq(DistrictDO::getParentId, id));
+ if(CollectionUtils.isNotEmpty(childrenList)){
+ childrenList.stream().forEach(districtTengxunDO -> {
+ deleteDistrict(districtTengxunDO.getId());
+ });
+ }
+ // 清空缓存
+ clearChineseDataCache();
+ return true;
+ }
+
+ @Override
+ public String getChineseArea() {
+ String result = stringCacheClient.get("CHINA_AREA_DATA");
+ if (StringUtils.isNotBlank(result)) {
+ return result;
+ } else { List<DistrictDO> districtDOList = getAllDistrict();
+ List<DistrictVO> districtVOList= ConverterUtil.transList(districtDOList, DistrictVO.class);
+ if(CollectionUtils.isNotEmpty(districtDOList)){
+ // 找出parent_id 是null的为根节点
+ Optional<DistrictVO> root = districtVOList.stream().filter(districtVO -> districtVO.getParentId() == null).findFirst();
+ // 遍历districtDOList,形成树形结构
+ if(null!=root && root.isPresent()){
+ DistrictVO rootNode = root.get();
+ // 构建树形结构
+ buildTree(rootNode, districtVOList);
+ // 查看这里的树形状结构,将这里的树型转换成之前前端使用的结构
+ AreaDTO areaDTO = transform(rootNode);
+ Gson gson=new Gson();
+ result=gson.toJson(areaDTO.getChildren());
+// System.out.println(result);
+ if(StringUtils.isNotBlank(result)){
+ stringCacheClient.set("CHINA_AREA_DATA", result);
+ }
+ return result;
+ }
+
+ }
+ return null;
+ }
+ }
+
+ @Override
+ public void clearChineseDataCache() {
+ stringCacheClient.delete("CHINA_AREA_DATA");
+ }
+
+}
diff --git a/src/main/java/com/mzl/flower/service/impl/district/DistrictTengxunServiceImpl.java b/src/main/java/com/mzl/flower/service/impl/district/DistrictTengxunServiceImpl.java
new file mode 100644
index 0000000..b2ec3f5
--- /dev/null
+++ b/src/main/java/com/mzl/flower/service/impl/district/DistrictTengxunServiceImpl.java
@@ -0,0 +1,367 @@
+package com.mzl.flower.service.impl.district;
+
+import cn.hutool.core.util.IdUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.gson.Gson;
+import com.mzl.flower.base.cache.StringCacheClient;
+import com.mzl.flower.config.exception.ValidationException;
+import com.mzl.flower.config.security.SecurityUtils;
+import com.mzl.flower.dto.request.district.CreateDistrictTengxunDTO;
+import com.mzl.flower.dto.response.district.DistrictTengxunVO;
+import com.mzl.flower.dto.response.system.AreaDTO;
+import com.mzl.flower.entity.district.DistrictTengxunDO;
+import com.mzl.flower.entity.district.DistrictTengxunDO;
+import com.mzl.flower.mapper.district.DistrictTengxunMapper;
+import com.mzl.flower.mapper.district.DistrictTengxunMapperCustom;
+import com.mzl.flower.service.district.DistrictTengxunService;
+import com.mzl.flower.utils.ConverterUtil;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ * 对接高德地图行政区划 服务实现类
+ * </p>
+ *
+ * @author @TaoJie
+ * @since 2024-12-19
+ */
+@Service
+public class DistrictTengxunServiceImpl extends ServiceImpl<DistrictTengxunMapper, DistrictTengxunDO> implements DistrictTengxunService {
+
+ @Autowired
+ private DistrictTengxunMapperCustom districtTengxunMapperCustom;
+ @Override
+ public void removeAllDistricts() {
+ districtTengxunMapperCustom.removeAllDistricts();
+ }
+
+ @Autowired
+ private StringCacheClient stringCacheClient;
+ @Override
+ public void refreshDistrict() {
+ List<DistrictTengxunDO> districtTengxunDOList = getAllDistrict();
+ List<DistrictTengxunVO> districtTengxunVOList = ConverterUtil.transList(districtTengxunDOList, DistrictTengxunVO.class);
+
+ if (CollectionUtils.isNotEmpty(districtTengxunDOList)) {
+ // 找出所有 parent_id 为 null 的节点作为根节点集合
+ List<DistrictTengxunVO> roots = districtTengxunVOList.stream()
+ .filter(districtTengxunVO -> districtTengxunVO.getParentId() == null)
+ .collect(Collectors.toList());
+
+ // 遍历根节点,构建每棵树形结构
+ List<AreaDTO> areaDTOList = new ArrayList<>();
+ for (DistrictTengxunVO rootNode : roots) {
+ // 构建树形结构
+ buildTree(rootNode, districtTengxunVOList);
+
+ // 将树形转换成前端需要的结构
+ AreaDTO areaDTO = transform(rootNode);
+ areaDTOList.add(areaDTO);
+
+ // 打印每个根节点对应的树形 JSON
+ Gson gson = new Gson();
+ System.out.println("根节点:" + rootNode.getName());
+ System.out.println("树形结构 JSON:" + gson.toJson(areaDTO));
+ }
+
+ // 如果需要整个树形结构的 JSON
+ Gson gson = new Gson();
+ System.out.println("整个中国地图的 JSON:" + gson.toJson(areaDTOList));
+ }
+
+ }
+
+
+ // 递归构建树形结构
+ private static void buildTree(DistrictTengxunVO parent, List<DistrictTengxunVO> allNodes) {
+ List<DistrictTengxunVO> children = allNodes.stream()
+ .filter(node -> parent.getId().equals(node.getParentId()))
+ .collect(Collectors.toList());
+
+ parent.setChildren(children);
+
+ for (DistrictTengxunVO child : children) {
+ buildTree(child, allNodes);
+ }
+ }
+
+ // 转换方法
+ public static AreaDTO transform(DistrictTengxunVO sourceNode) {
+ if (sourceNode == null) {
+ return null;
+ }
+
+ // 映射当前节点
+ AreaDTO targetNode = new AreaDTO(sourceNode.getName(), sourceNode.getName());
+
+ // 递归映射子节点
+ if (sourceNode.getChildren() != null) {
+ for (DistrictTengxunVO child : sourceNode.getChildren()) {
+ targetNode.getChildren().add(transform(child));
+ }
+ }
+
+ return targetNode;
+ }
+
+
+ @Override
+ public List<DistrictTengxunDO> getAllDistrict() {
+ return baseMapper.selectList(new LambdaQueryWrapper<DistrictTengxunDO>().eq(DistrictTengxunDO::getDeleted, false).orderByAsc(DistrictTengxunDO::getCode));
+ }
+
+ @Override
+ public List<AreaDTO> getAreaDTOListByDB() {
+
+ return null;
+ }
+
+ @Override
+ public List<AreaDTO> getAreaDTOListByJsonFile() {
+ return null;
+ }
+
+ @Override
+ public void saveRemoteDistricts(List<DistrictTengxunDO> districtTengxunDOList) {
+
+ districtTengxunDOList.stream().forEach(districtTengxunDO -> {
+ // 保存数据库中必要的信息
+ districtTengxunDO.create();
+ districtTengxunDO.setCreateBy("system");
+ districtTengxunDO.setUpdateBy("system");
+ });
+
+ saveOrUpdateBatch(districtTengxunDOList);
+ /*
+ List<DistrictTengxunDO> existList=new ArrayList<>();
+ List<DistrictTengxunDO> noneExistList=new ArrayList<>();
+
+ // 查看是否已经存在code,如果存在则更新,不存在则插入
+ districtTengxunDOList.stream().forEach(districtTengxunDO -> {
+ List<DistrictTengxunDO> list = list(new LambdaQueryWrapper<DistrictTengxunDO>().eq(DistrictTengxunDO::getDeleted, false).eq(DistrictTengxunDO::getCode,districtTengxunDO.getCode() ));
+ if (CollectionUtils.isNotEmpty(list)) {
+ existList.add(districtTengxunDO);
+ } else {
+ // 插入
+ noneExistList.add(districtTengxunDO);
+ }
+ });
+
+
+
+ removeAllDistricts();
+ System.out.println("删除成功");
+ // 保存数据入库
+ saveBatch(districtTengxunDOList);*/
+ System.out.println("保存成功");
+ }
+
+ @Override
+ public List<DistrictTengxunVO> getDistrictTreeList() {
+ List<DistrictTengxunDO> districtTengxunDOList = getAllDistrict();
+ List<DistrictTengxunVO> districtTengxunVOList = ConverterUtil.transList(districtTengxunDOList, DistrictTengxunVO.class);
+
+ if (CollectionUtils.isNotEmpty(districtTengxunDOList)) {
+ // 找出所有 parent_id 为 null 的节点作为根节点集合
+ List<DistrictTengxunVO> roots = districtTengxunVOList.stream()
+ .filter(districtTengxunVO -> districtTengxunVO.getParentId() == null)
+ .collect(Collectors.toList());
+
+
+ for (DistrictTengxunVO rootNode : roots) {
+ // 构建树形结构
+ buildTree(rootNode, districtTengxunVOList);
+
+ }
+ return roots;
+ }
+ return null;
+ }
+
+ @Transactional
+ @Override
+ public boolean createDistrict(CreateDistrictTengxunDTO dto) {
+
+ // 查看编码是否存在
+ if (count(new LambdaQueryWrapper<DistrictTengxunDO>()
+ .eq(DistrictTengxunDO::getDeleted, false)
+ .eq(DistrictTengxunDO::getCode, dto.getCode()))>0) {
+ throw new ValidationException("当前编码已经存在,code全局唯一");
+ }
+ // 查看相同节点下的名称是否存在,这里的partentId可能是null的情况
+
+ if(StringUtils.isNotBlank(dto.getName())){
+ LambdaQueryWrapper<DistrictTengxunDO> queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(DistrictTengxunDO::getDeleted, false)
+ .eq(DistrictTengxunDO::getName, dto.getName());
+ if (dto.getParentId() == null) {
+ queryWrapper.isNull(DistrictTengxunDO::getParentId);
+ } else {
+ queryWrapper.eq(DistrictTengxunDO::getParentId, dto.getParentId());
+ }
+ if (count(queryWrapper)>0) {
+ throw new ValidationException("当前名称已经存在");
+ }
+ }
+
+ if(StringUtils.isNotBlank(dto.getFullname())){
+ LambdaQueryWrapper<DistrictTengxunDO> queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(DistrictTengxunDO::getDeleted, false)
+ .eq(DistrictTengxunDO::getFullname, dto.getFullname());
+ if (dto.getParentId() == null) {
+ queryWrapper.isNull(DistrictTengxunDO::getParentId);
+ } else {
+ queryWrapper.eq(DistrictTengxunDO::getParentId, dto.getParentId());
+ }
+ if (count(queryWrapper)>0) {
+ throw new ValidationException("当前全称已经存在");
+ }
+ }
+
+ DistrictTengxunDO districtTengxunDO =new DistrictTengxunDO();
+ BeanUtils.copyProperties(dto,districtTengxunDO);
+
+ districtTengxunDO.setId(IdUtil.simpleUUID());
+ districtTengxunDO.create(SecurityUtils.getUserId());
+
+ // 保存
+ boolean result=save(districtTengxunDO);
+ // 清空缓存
+ clearChineseDataCache();
+ return result;
+ }
+
+ @Transactional
+ @Override
+ public boolean deleteDistrict(String id) {
+ DistrictTengxunDO existsDistrict = getById(id);
+ existsDistrict.update(SecurityUtils.getUserId());
+ existsDistrict.setDeleted(true);
+ updateById(existsDistrict);
+
+ List<DistrictTengxunDO> childrenList = list(new LambdaQueryWrapper<DistrictTengxunDO>().eq(DistrictTengxunDO::getParentId, id));
+ if(CollectionUtils.isNotEmpty(childrenList)){
+ childrenList.stream().forEach(districtTengxunDO -> {
+ deleteDistrict(districtTengxunDO.getId());
+ });
+ }
+ // 清空缓存
+ clearChineseDataCache();
+ return true;
+ }
+
+ @Transactional
+ @Override
+ public boolean updateDistrict(CreateDistrictTengxunDTO dto) {
+ DistrictTengxunDO existsDistrict = getById(dto.getId());
+ if(Objects.isNull(existsDistrict)){
+ throw new ValidationException("当前id不存在");
+ }
+
+ // 查看编码是否存在
+ if (count(new LambdaQueryWrapper<DistrictTengxunDO>()
+ .eq(DistrictTengxunDO::getDeleted, false)
+ .eq(DistrictTengxunDO::getCode, dto.getCode()).ne(DistrictTengxunDO::getId,dto.getId()))>0) {
+ throw new ValidationException("当前编码已经存在,code全局唯一");
+ }
+ // 查看相同节点下的名称是否存在,这里的partentId可能是null的情况
+
+ if(StringUtils.isNotBlank(dto.getName())){
+ LambdaQueryWrapper<DistrictTengxunDO> queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(DistrictTengxunDO::getDeleted, false)
+ .eq(DistrictTengxunDO::getName, dto.getName())
+ .ne(DistrictTengxunDO::getId,dto.getId());
+ if (dto.getParentId() == null) {
+ queryWrapper.isNull(DistrictTengxunDO::getParentId);
+ } else {
+ queryWrapper.eq(DistrictTengxunDO::getParentId, dto.getParentId());
+ }
+ if (count(queryWrapper)>0) {
+ throw new ValidationException("当前名称已经存在");
+ }
+ }
+
+ if(StringUtils.isNotBlank(dto.getFullname())){
+ LambdaQueryWrapper<DistrictTengxunDO> queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(DistrictTengxunDO::getDeleted, false)
+ .eq(DistrictTengxunDO::getFullname, dto.getFullname())
+ .ne(DistrictTengxunDO::getId,dto.getId());
+ if (dto.getParentId() == null) {
+ queryWrapper.isNull(DistrictTengxunDO::getParentId);
+ } else {
+ queryWrapper.eq(DistrictTengxunDO::getParentId, dto.getParentId());
+ }
+ if (count(queryWrapper)>0) {
+ throw new ValidationException("当前全称已经存在");
+ }
+ }
+
+ BeanUtils.copyProperties(dto, existsDistrict);
+ existsDistrict.update(SecurityUtils.getUserId());
+
+ boolean result= updateById(existsDistrict);
+ // 清空缓存
+ clearChineseDataCache();
+ return result;
+ }
+
+ @Override
+ public String getChineseArea() {
+
+ String result = stringCacheClient.get("CHINA_AREA_DATA");
+ if (StringUtils.isNotBlank(result)) {
+ return result;
+ } else {
+ // 打印每个根节点对应的树形 JSON
+ Gson gson = new Gson();
+
+ List<DistrictTengxunDO> districtTengxunDOList = getAllDistrict();
+ List<DistrictTengxunVO> districtTengxunVOList = ConverterUtil.transList(districtTengxunDOList, DistrictTengxunVO.class);
+
+ if (CollectionUtils.isNotEmpty(districtTengxunDOList)) {
+ // 找出所有 parent_id 为 null 的节点作为根节点集合
+ List<DistrictTengxunVO> roots = districtTengxunVOList.stream()
+ .filter(districtTengxunVO -> districtTengxunVO.getParentId() == null)
+ .collect(Collectors.toList());
+
+ // 遍历根节点,构建每棵树形结构
+ List<AreaDTO> areaDTOList = new ArrayList<>();
+ for (DistrictTengxunVO rootNode : roots) {
+ // 构建树形结构
+ buildTree(rootNode, districtTengxunVOList);
+
+ // 将树形转换成前端需要的结构
+ AreaDTO areaDTO = transform(rootNode);
+ areaDTOList.add(areaDTO);
+ }
+ result=gson.toJson(areaDTOList);
+ if(StringUtils.isNotBlank(result)){
+ stringCacheClient.set("CHINA_AREA_DATA", result);
+ }
+
+ return result;
+ }
+ return "";
+ }
+
+
+ }
+
+ @Override
+ public void clearChineseDataCache() {
+ stringCacheClient.delete("CHINA_AREA_DATA");
+ }
+
+}
diff --git a/src/main/java/com/mzl/flower/service/impl/map/MapGaodeServiceImpl.java b/src/main/java/com/mzl/flower/service/impl/map/MapGaodeServiceImpl.java
new file mode 100644
index 0000000..24935d5
--- /dev/null
+++ b/src/main/java/com/mzl/flower/service/impl/map/MapGaodeServiceImpl.java
@@ -0,0 +1,107 @@
+package com.mzl.flower.service.impl.map;
+
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.http.HttpUtil;
+import com.google.gson.Gson;
+import com.mzl.flower.config.GaodeMapProperties;
+import com.mzl.flower.dto.map.gaode.GaodeDistrict;
+import com.mzl.flower.dto.map.gaode.GaodeMapResponse;
+import com.mzl.flower.dto.response.coupon.CouponTemplateActivyVO;
+import com.mzl.flower.entity.district.DistrictDO;
+import com.mzl.flower.service.district.DistrictService;
+import com.mzl.flower.service.map.MapGaodeService;
+import com.mzl.flower.utils.ConverterUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.codec.digest.Md5Crypt;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+@Service
+@Slf4j
+public class MapGaodeServiceImpl implements MapGaodeService {
+
+ @Autowired
+ private GaodeMapProperties gaodeMapProperties;
+
+ @Autowired
+ private DistrictService districtService;
+
+ @Override
+ public void getAdministrativeDivision() {
+
+ String administrativeDivisionsUrl = gaodeMapProperties.getAdministrativeDivisionsUrl();
+ System.out.println(administrativeDivisionsUrl);
+ //可以单独传入http参数,这样参数会自动做URL编码,拼接在URL中
+ HashMap<String, Object> paramMap = new HashMap<>();
+
+ String result= HttpUtil.get(administrativeDivisionsUrl, paramMap);
+ System.out.println(result);
+ // 使用 Gson 解析 JSON 字符串
+ Gson gson = new Gson();
+ GaodeMapResponse response = gson.fromJson(result, GaodeMapResponse.class);
+ if(response.getStatus().equals("1")&&response.getInfocode().equals("10000")){
+ log.info("高德地图获取行政区划成功");
+ log.info(response.getDistricts().toString());
+ List<GaodeDistrict> allTengxunDistricts = new ArrayList<>();
+ for (GaodeDistrict gaodeDistrict : response.getDistricts()){
+ addDistrictToList(gaodeDistrict, null, allTengxunDistricts); // 从根节点开始,父节点 ID 为 null
+ }
+ // 打印所有区划信息
+ for (GaodeDistrict gaodeDistrict :allTengxunDistricts){
+ printDistrictInfo(gaodeDistrict);
+ }
+ // 保存所有的行政区划数据到数据库中
+ // 将allTengxunDistricts转换成List<DsitrictVO>
+ List<DistrictDO> districtDOList= ConverterUtil.transList(allTengxunDistricts, DistrictDO.class);
+
+ /**
+ * 保存数据到数据库中
+ */
+ districtService.saveRemoteDistricts(districtDOList);
+
+
+ System.out.println("保存成功");
+ }else{
+ log.error("高德地图获取行政区划失败");
+ }
+
+
+
+ }
+
+ public static void addDistrictToList(GaodeDistrict gaodeDistrict, String parentId, List<GaodeDistrict> allTengxunDistricts) {
+ // 设置id
+ gaodeDistrict.setId(IdUtil.simpleUUID());
+// String idStr=gaodeDistrict.getAdcode()+gaodeDistrict.getLevel();
+// gaodeDistrict.setId(idStr);
+ // 设置父节点 ID
+ gaodeDistrict.setParentId(parentId);
+ // 将当前区划添加到结果列表
+ allTengxunDistricts.add(gaodeDistrict);
+
+ // 递归遍历子区划
+ if (gaodeDistrict.getDistricts() != null) {
+ for (GaodeDistrict child : gaodeDistrict.getDistricts()) {
+ addDistrictToList(child, gaodeDistrict.getId(), allTengxunDistricts); // 将当前节点的 ID 作为子节点的父节点 ID
+ }
+ }
+ }
+
+ public static void printDistrictInfo(GaodeDistrict gaodeDistrict) {
+ // 打印相关信息
+ System.out.println("ID: " + gaodeDistrict.getId() + ", 父节点ID: " + gaodeDistrict.getParentId());
+ System.out.println("名称: " + gaodeDistrict.getName());
+ System.out.println("编码: " + gaodeDistrict.getAdcode());
+ System.out.println("级别: " + gaodeDistrict.getLevel());
+ System.out.println("边界线: " + gaodeDistrict.getPolyline());
+ System.out.println("中心点: " + gaodeDistrict.getCenter());
+ System.out.println("子节点数量: " + gaodeDistrict.getDistricts().size());
+
+ System.out.println("--------------------------");
+ }
+
+}
diff --git a/src/main/java/com/mzl/flower/service/impl/map/MapTengxunServiceImpl.java b/src/main/java/com/mzl/flower/service/impl/map/MapTengxunServiceImpl.java
new file mode 100644
index 0000000..fc0b4f5
--- /dev/null
+++ b/src/main/java/com/mzl/flower/service/impl/map/MapTengxunServiceImpl.java
@@ -0,0 +1,152 @@
+package com.mzl.flower.service.impl.map;
+
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.http.HttpUtil;
+import com.google.gson.Gson;
+import com.mzl.flower.config.TengxunMapProperties;
+import com.mzl.flower.dto.map.gaode.GaodeDistrict;
+import com.mzl.flower.dto.map.tengxun.TengxunDistrict;
+import com.mzl.flower.dto.map.tengxun.TencentMapResponse;
+import com.mzl.flower.entity.district.DistrictDO;
+import com.mzl.flower.entity.district.DistrictTengxunDO;
+import com.mzl.flower.service.BaseService;
+import com.mzl.flower.service.district.DistrictTengxunService;
+import com.mzl.flower.service.map.MapTengxunService;
+import com.mzl.flower.utils.ConverterUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+@Slf4j
+@Service
+public class MapTengxunServiceImpl extends BaseService implements MapTengxunService {
+
+ @Autowired
+ private TengxunMapProperties tengxunMapProperties;
+
+ @Autowired
+ private DistrictTengxunService districtTengxunService;
+
+ @Override
+ public void getAdministrativeDivision() {
+ String administrativeDivisionsUrl = tengxunMapProperties.getAdministrativeDivisionsUrl();
+ //可以单独传入http参数,这样参数会自动做URL编码,拼接在URL中
+ HashMap<String, Object> paramMap = new HashMap<>();
+
+ String result= HttpUtil.get(administrativeDivisionsUrl, paramMap);
+ System.out.println(result);
+ // 使用 Gson 解析 JSON 字符串
+ Gson gson = new Gson();
+ TencentMapResponse response = gson.fromJson(result, TencentMapResponse.class);
+
+ if(response.getStatus()==0){
+
+
+ List<TengxunDistrict> allDistricts = response.getResult();
+ // 将腾讯地图返回的数据格式转换成标准的三层结构
+ List<TengxunDistrict> formatterDistrict =normalizeTreeToThreeLevels(allDistricts);
+
+ List<TengxunDistrict> allTengxunDistricts = new ArrayList<>();
+ // 递归遍历所有的节点,然后把所有节点加入到 allDistricts 列表中
+ for (TengxunDistrict tengxunDistrict : formatterDistrict){
+ addDistrictToList(tengxunDistrict, null, allTengxunDistricts); // 从根节点开始,父节点 ID 为 null
+ }
+ List<DistrictTengxunDO> districtTengxunDOList= ConverterUtil.transList(allTengxunDistricts, DistrictTengxunDO.class);
+
+ districtTengxunService.saveRemoteDistricts(districtTengxunDOList);
+
+
+// for (TengxunDistrict tengxunDistrict : allTengxunDistricts) {
+// printDistrictInfo(tengxunDistrict);
+// }
+
+ }
+
+ }
+
+ public static List<TengxunDistrict> normalizeTreeToThreeLevels(List<TengxunDistrict> tree) {
+ List<TengxunDistrict> result = new ArrayList<>();
+ for (TengxunDistrict node : tree) {
+ int depth = getTreeDepth(node);
+ if(depth<3){
+ List<TengxunDistrict> childrenList=new ArrayList<>();
+ childrenList.add(node);
+
+ TengxunDistrict tengxunDistrict= new TengxunDistrict();
+ BeanUtils.copyProperties(node, tengxunDistrict);
+ tengxunDistrict.setDistricts(childrenList);
+ // 虚拟的id、code
+ tengxunDistrict.setId(tengxunDistrict.getId()+"virtual");
+ // 虚拟的层级
+ tengxunDistrict.setLevel(-1);
+ result.add(tengxunDistrict);
+ continue;
+ }else{
+ result.add(node);
+ }
+
+ }
+ return result;
+ }
+
+ /**
+ * 遍历树的深度
+ * @param node
+ * @return
+ */
+ private static int getTreeDepth(TengxunDistrict node) {
+ if (node == null || node.getDistricts() == null || node.getDistricts().isEmpty()) {
+ return 1;
+ }
+ int maxDepth = 0;
+ for (TengxunDistrict child : node.getDistricts()) {
+ maxDepth = Math.max(maxDepth, getTreeDepth(child));
+ }
+ return maxDepth + 1;
+ }
+
+ // 打印区划信息的辅助方法
+ public static void printDistrictInfo(TengxunDistrict tengxunDistrict) {
+ System.out.println("ID: " + tengxunDistrict.getId() + ", 父节点ID: " + tengxunDistrict.getParentId());
+ System.out.println("名称: " + tengxunDistrict.getName());
+ System.out.println("全称: " + tengxunDistrict.getFullname());
+ System.out.println("级别: " + tengxunDistrict.getLevel());
+ System.out.println("拼音: " + tengxunDistrict.getPinyin());
+ System.out.println("经纬度: " + tengxunDistrict.getTengxunLocation());
+ System.out.println("--------------------------");
+ }
+
+
+ // 递归遍历区划节点,并将它们添加到 allDistricts 列表
+ public static void addDistrictToList(TengxunDistrict tengxunDistrict, String parentId, List<TengxunDistrict> allTengxunDistricts) {
+ // 将腾讯地图返回的id作为code存放到code中
+ tengxunDistrict.setCode(tengxunDistrict.getId());
+ // 如果name 是空的话,则将fullname赋值给name
+ if(StringUtils.isBlank(tengxunDistrict.getName())){
+ tengxunDistrict.setName(tengxunDistrict.getFullname());
+ }
+
+// tengxunDistrict.setId(IdUtil.simpleUUID());
+ // 设置父节点 ID
+ tengxunDistrict.setParentId(parentId);
+
+ // 将当前区划添加到结果列表
+ allTengxunDistricts.add(tengxunDistrict);
+
+ // 递归遍历子区划
+ if (tengxunDistrict.getDistricts()!= null) {
+ for (TengxunDistrict child : tengxunDistrict.getDistricts()) {
+ addDistrictToList(child, tengxunDistrict.getId(), allTengxunDistricts); // 将当前节点的 ID 作为子节点的父节点 ID
+ }
+ }
+ }
+
+
+}
diff --git a/src/main/java/com/mzl/flower/service/map/MapGaodeService.java b/src/main/java/com/mzl/flower/service/map/MapGaodeService.java
new file mode 100644
index 0000000..054451e
--- /dev/null
+++ b/src/main/java/com/mzl/flower/service/map/MapGaodeService.java
@@ -0,0 +1,11 @@
+package com.mzl.flower.service.map;
+
+public interface MapGaodeService {
+
+ /**
+ * 获取腾讯的行政区划
+ */
+ void getAdministrativeDivision();
+
+
+}
diff --git a/src/main/java/com/mzl/flower/service/map/MapTengxunService.java b/src/main/java/com/mzl/flower/service/map/MapTengxunService.java
new file mode 100644
index 0000000..d64246c
--- /dev/null
+++ b/src/main/java/com/mzl/flower/service/map/MapTengxunService.java
@@ -0,0 +1,11 @@
+package com.mzl.flower.service.map;
+
+public interface MapTengxunService {
+
+ /**
+ * 获取腾讯的行政区划
+ */
+ void getAdministrativeDivision();
+
+
+}
diff --git a/src/main/java/com/mzl/flower/web/system/ProvinceController.java b/src/main/java/com/mzl/flower/web/system/ProvinceController.java
index 1d9c307..ec2fa4e 100644
--- a/src/main/java/com/mzl/flower/web/system/ProvinceController.java
+++ b/src/main/java/com/mzl/flower/web/system/ProvinceController.java
@@ -2,6 +2,8 @@
import com.mzl.flower.base.BaseController;
import com.mzl.flower.base.R;
+import com.mzl.flower.service.district.DistrictService;
+import com.mzl.flower.service.district.DistrictTengxunService;
import com.mzl.flower.service.system.ProvinceService;
import com.mzl.flower.utils.LocalUtil;
import io.swagger.annotations.Api;
@@ -23,6 +25,18 @@
@Autowired
private ProvinceService provinceService;
+
+ /**
+ * 腾讯地图获取中国省市区数据
+ */
+ @Autowired
+ private DistrictTengxunService districtTengxunService;
+
+ /**
+ * 高德地图获取中国省市区数据
+ */
+ @Autowired
+ private DistrictService districtService;
@ApiOperation(value = "获取省份")
@GetMapping("/provinces")
@@ -58,13 +72,20 @@
@ApiOperation(value = "获取中国省市区数据")
@GetMapping("/area/json")
public ResponseEntity<String> getChineseArea() {
- return returnData(R.SUCCESS.getCode(), provinceService.getChineseArea());
+
+ // 高德地图
+// return returnData(R.SUCCESS.getCode(), districtService.getChineseArea());
+ // 腾讯地图
+ return returnData(R.SUCCESS.getCode(), districtTengxunService.getChineseArea());
+// return returnData(R.SUCCESS.getCode(), provinceService.getChineseArea());
}
@ApiOperation(value = "刷新中国省市区数据缓存")
@GetMapping("/area/json/refresh")
public ResponseEntity<String> refresh() {
- provinceService.refreshChineseData();
+// provinceService.refreshChineseData();
+// districtService.clearChineseDataCache();
+ districtTengxunService.clearChineseDataCache();
return returnData(R.SUCCESS.getCode(), null);
}
}
diff --git a/src/main/java/com/mzl/flower/web/v2/district/DistrictGaodeController.java b/src/main/java/com/mzl/flower/web/v2/district/DistrictGaodeController.java
new file mode 100644
index 0000000..b3bc67a
--- /dev/null
+++ b/src/main/java/com/mzl/flower/web/v2/district/DistrictGaodeController.java
@@ -0,0 +1,80 @@
+package com.mzl.flower.web.v2.district;
+
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.mzl.flower.base.BaseController;
+import com.mzl.flower.base.R;
+import com.mzl.flower.base.ReturnDataDTO;
+
+
+import com.mzl.flower.dto.request.district.CreateDistrictGaodeDTO;
+import com.mzl.flower.dto.request.district.CreateDistrictTengxunDTO;
+import com.mzl.flower.dto.request.district.QueryDistrictTengxunDTO;
+import com.mzl.flower.dto.response.district.DistrictVO;
+import com.mzl.flower.service.district.DistrictService;
+
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import com.mzl.flower.entity.district.DistrictDO;
+
+/**
+ * 对接高德地图行政区划前端控制器
+ *
+* @author @TaoJie
+* @since 2024-12-19
+*/
+@RestController
+@RequestMapping("/v2/district-gaode")
+public class DistrictGaodeController extends BaseController {
+
+ @Autowired
+ private DistrictService districtService;
+
+ @PostMapping("")
+ @ApiOperation(value = "新增", notes = "新增")
+ public ResponseEntity<ReturnDataDTO> create(@Validated @RequestBody CreateDistrictGaodeDTO dto) {
+ return returnData(R.SUCCESS.getCode(), districtService.createDistrict(dto));
+ }
+
+ @PutMapping("/{id}")
+ @ApiOperation(value = "修改", notes = "修改")
+ public ResponseEntity<ReturnDataDTO> update(@PathVariable String id,@Validated @RequestBody CreateDistrictGaodeDTO dto) {
+ dto.setId(id);
+ return returnData(R.SUCCESS.getCode(), districtService.updateDistrict(dto));
+ }
+
+ @DeleteMapping("/{id}")
+ @ApiOperation(value = "删除", notes = "删除")
+ public ResponseEntity<ReturnDataDTO> delete(@PathVariable String id) {
+ return returnData(R.SUCCESS.getCode(), districtService.deleteDistrict(id));
+ }
+
+ @GetMapping("/{id}")
+ @ApiOperation(value = "详情", notes = "详情")
+ public ResponseEntity<DistrictDO> get(@PathVariable String id) {
+
+ return returnData(R.SUCCESS.getCode(),districtService.getById(id));
+ }
+
+ @GetMapping("/page")
+ @ApiOperation(value = "查询-分页", notes = "查询-分页")
+ public ResponseEntity<ReturnDataDTO<Page<DistrictDO>>> page(Page page, QueryDistrictTengxunDTO dto
+ ) {
+// return returnData(R.SUCCESS.getCode(), ConverterUtil.transPage(resultPage, CouponTemplateActivyVO.class));
+ return null;
+ }
+
+ @GetMapping("/list")
+ @ApiOperation(value = "查询-全部", notes = "查询-全部")
+ public ResponseEntity<ReturnDataDTO<Page<DistrictVO>>> list(QueryDistrictTengxunDTO dto) {
+
+ return returnData(R.SUCCESS.getCode(), districtService.getDistrictTreeList());
+
+ }
+
+
+
+}
diff --git a/src/main/java/com/mzl/flower/web/v2/district/DistrictTengxunController.java b/src/main/java/com/mzl/flower/web/v2/district/DistrictTengxunController.java
new file mode 100644
index 0000000..0bcd675
--- /dev/null
+++ b/src/main/java/com/mzl/flower/web/v2/district/DistrictTengxunController.java
@@ -0,0 +1,76 @@
+package com.mzl.flower.web.v2.district;
+
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.mzl.flower.base.BaseController;
+import com.mzl.flower.base.R;
+import com.mzl.flower.base.ReturnDataDTO;
+import com.mzl.flower.dto.request.district.CreateDistrictTengxunDTO;
+import com.mzl.flower.dto.request.district.QueryDistrictTengxunDTO;
+import com.mzl.flower.dto.response.district.DistrictTengxunVO;
+import com.mzl.flower.entity.district.DistrictDO;
+import com.mzl.flower.entity.district.DistrictTengxunDO;
+import com.mzl.flower.service.district.DistrictTengxunService;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * 对接腾讯地图行政区划前端控制器
+ *
+* @author @TaoJie
+* @since 2024-12-19
+*/
+@RestController
+@RequestMapping("/v2/district-tengxun")
+public class DistrictTengxunController extends BaseController {
+
+ @Autowired
+ private DistrictTengxunService districtTengxunService;
+
+ @PostMapping("")
+ @ApiOperation(value = "新增", notes = "新增")
+ public ResponseEntity<ReturnDataDTO> create(@Validated @RequestBody CreateDistrictTengxunDTO dto) {
+ return returnData(R.SUCCESS.getCode(), districtTengxunService.createDistrict(dto));
+ }
+
+ @PutMapping("/{id}")
+ @ApiOperation(value = "修改", notes = "修改")
+ public ResponseEntity<ReturnDataDTO> update(@PathVariable String id,@Validated @RequestBody CreateDistrictTengxunDTO dto) {
+ dto.setId(id);
+ return returnData(R.SUCCESS.getCode(), districtTengxunService.updateDistrict(dto));
+ }
+
+ @DeleteMapping("/{id}")
+ @ApiOperation(value = "删除", notes = "删除")
+ public ResponseEntity<ReturnDataDTO> delete(@PathVariable String id) {
+ return returnData(R.SUCCESS.getCode(), districtTengxunService.deleteDistrict(id));
+ }
+
+ @GetMapping("/{id}")
+ @ApiOperation(value = "详情", notes = "详情")
+ public ResponseEntity<DistrictTengxunDO> get(@PathVariable String id) {
+ return returnData(R.SUCCESS.getCode(), districtTengxunService.getById(id));
+ }
+
+ @GetMapping("/page")
+ @ApiOperation(value = "查询-分页", notes = "查询-分页")
+ public ResponseEntity<ReturnDataDTO<Page<DistrictDO>>> page(Page page, QueryDistrictTengxunDTO dto
+ ) {
+// return returnData(R.SUCCESS.getCode(), ConverterUtil.transPage(resultPage, CouponTemplateActivyVO.class));
+ return null;
+ }
+
+ @GetMapping("/list")
+ @ApiOperation(value = "查询-全部", notes = "查询-全部")
+ public ResponseEntity<ReturnDataDTO<Page<DistrictTengxunVO>>> list(QueryDistrictTengxunDTO dto) {
+
+ return returnData(R.SUCCESS.getCode(), districtTengxunService.getDistrictTreeList());
+
+ }
+
+
+
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 6ad42f0..3094aba 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -87,4 +87,15 @@
secret: 9121c703fb0c416b21a8c289dd73ae9b #secret
sms:
- verificationCode: SMS_301300012 #验证码通用模版
\ No newline at end of file
+ verificationCode: SMS_301300012 #验证码通用模版
+
+map:
+ tengxun:
+# apiKey: GSBBZ-CJA3U-NNDVH-GE65N-6FIF6-ZGBCU
+ apiKey: PRFBZ-INBLB-PYEU6-JCKUM-AYD7V-V7BIF
+ # 新政区划接口url
+ administrative_divisions_url : https://apis.map.qq.com/ws/district/v1/list?key=${map.tengxun.apiKey}&&struct_type=1
+ gaode:
+ apiKey: 19b8a6e7325089d484fcee00076746fa
+ # 新政区划接口url
+ administrative_divisions_url: https://restapi.amap.com/v3/config/district?key=${map.gaode.apiKey}&subdistrict=3&subdistrict=3&extensions=base
\ No newline at end of file
diff --git a/src/main/resources/mapper/district/DistrictMapper.xml b/src/main/resources/mapper/district/DistrictMapper.xml
new file mode 100644
index 0000000..dc74ec4
--- /dev/null
+++ b/src/main/resources/mapper/district/DistrictMapper.xml
@@ -0,0 +1,22 @@
+<?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.mzl.flower.mapper.district.DistrictMapper">
+
+ <!-- 通用查询映射结果 -->
+ <resultMap id="BaseResultMap" type="com.mzl.flower.entity.district.DistrictDO">
+ <id column="id" property="id" />
+ <result column="deleted" property="deleted" />
+ <result column="create_by" property="createBy" />
+ <result column="create_time" property="createTime" />
+ <result column="update_by" property="updateBy" />
+ <result column="update_time" property="updateTime" />
+ <result column="name" property="name" />
+ <result column="citycode" property="citycode" />
+ <result column="adcode" property="adcode" />
+ <result column="polyline" property="polyline" />
+ <result column="center" property="center" />
+ <result column="level" property="level" />
+ <result column="parent_id" property="parentId" />
+ </resultMap>
+
+</mapper>
diff --git a/src/main/resources/mapper/district/DistrictMapperCustom.xml b/src/main/resources/mapper/district/DistrictMapperCustom.xml
new file mode 100644
index 0000000..93a7269
--- /dev/null
+++ b/src/main/resources/mapper/district/DistrictMapperCustom.xml
@@ -0,0 +1,10 @@
+<?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.mzl.flower.mapper.district.DistrictMapperCustom">
+
+ <delete id="removeAllDistricts">
+ delete from t_district
+ </delete>
+
+
+</mapper>
diff --git a/src/main/resources/mapper/district/DistrictTengxunMapper.xml b/src/main/resources/mapper/district/DistrictTengxunMapper.xml
new file mode 100644
index 0000000..61467b0
--- /dev/null
+++ b/src/main/resources/mapper/district/DistrictTengxunMapper.xml
@@ -0,0 +1,20 @@
+<?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.mzl.flower.mapper.district.DistrictTengxunMapper">
+
+ <!-- 通用查询映射结果 -->
+ <resultMap id="BaseResultMap" type="com.mzl.flower.entity.district.DistrictTengxunDO">
+ <id column="id" property="id" />
+ <result column="deleted" property="deleted" />
+ <result column="create_by" property="createBy" />
+ <result column="create_time" property="createTime" />
+ <result column="update_by" property="updateBy" />
+ <result column="update_time" property="updateTime" />
+ <result column="name" property="name" />
+ <result column="fullname" property="fullname" />
+ <result column="code" property="code" />
+ <result column="level" property="level" />
+ <result column="parent_id" property="parentId" />
+ </resultMap>
+
+</mapper>
diff --git a/src/main/resources/mapper/district/DistrictTengxunMapperCustom.xml b/src/main/resources/mapper/district/DistrictTengxunMapperCustom.xml
new file mode 100644
index 0000000..a52e60d
--- /dev/null
+++ b/src/main/resources/mapper/district/DistrictTengxunMapperCustom.xml
@@ -0,0 +1,10 @@
+<?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.mzl.flower.mapper.district.DistrictTengxunMapperCustom">
+
+ <delete id="removeAllDistricts">
+ delete from t_district_tengxun
+ </delete>
+
+
+</mapper>
--
Gitblit v1.9.3