Selaa lähdekoodia

行政区选择

drew 5 vuotta sitten
vanhempi
commit
afe8d2015c

+ 30 - 0
src/main/java/com/izouma/awesomeAdmin/domain/District.java

@@ -0,0 +1,30 @@
+package com.izouma.awesomeAdmin.domain;
+
+import io.swagger.annotations.ApiModel;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Data
+@Entity
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+@ApiModel("行政区域")
+public class District extends AuditedEntity {
+    @Id
+    private Long    id;
+    private String  name;
+    private String  fullName;
+    private double  lat;
+    private double  lng;
+    private String  pinyin;
+    private int     level;
+    private Long    parent;
+    private boolean leaf;
+
+}

+ 8 - 0
src/main/java/com/izouma/awesomeAdmin/repo/DistrictRepo.java

@@ -0,0 +1,8 @@
+package com.izouma.awesomeAdmin.repo;
+
+import com.izouma.awesomeAdmin.domain.District;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+
+public interface DistrictRepo extends JpaRepository<District, Long>, JpaSpecificationExecutor<District> {
+}

+ 72 - 0
src/main/java/com/izouma/awesomeAdmin/service/DistrictService.java

@@ -0,0 +1,72 @@
+package com.izouma.awesomeAdmin.service;
+
+import com.izouma.awesomeAdmin.domain.District;
+import com.izouma.awesomeAdmin.repo.DistrictRepo;
+import com.izouma.awesomeAdmin.utils.qqmap.DistrictResponse;
+import com.izouma.awesomeAdmin.utils.qqmap.QQMapUtil;
+import lombok.AllArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@AllArgsConstructor
+public class DistrictService {
+
+    private DistrictRepo districtRepo;
+
+    public void sync() {
+        List<List<DistrictResponse.District>> res = QQMapUtil.queryDistrict().getResult();
+        for (int i = 0; i < 3; i++) {
+            for (DistrictResponse.District district : res.get(i)) {
+                District d = convert(district);
+                d.setLevel(i);
+                if (i > 0) {
+                    int finalI = i;
+                    DistrictResponse.District parent = res.get(i - 1)
+                            .stream()
+                            .filter(ii -> String.valueOf(ii.getId())
+                                    .startsWith(String.valueOf(d.getId()).substring(0, finalI == 1 ? 2 : 4)))
+                            .findFirst()
+                            .orElse(null);
+
+                    if (parent == null) {
+                        parent = res.get(0)
+                                .stream()
+                                .filter(ii -> String.valueOf(ii.getId())
+                                        .startsWith(String.valueOf(d.getId()).substring(0, 2)))
+                                .findFirst()
+                                .orElse(null);
+                        District p = convert(parent);
+                        p.setLevel(1);
+                        p.setParent(Long.parseLong(String.valueOf(parent.getId()).substring(0, 2) + "0100"));
+                        districtRepo.save(p);
+                        d.setParent(p.getId());
+                    } else {
+                        d.setParent((long) parent.getId());
+                    }
+
+                }
+                if (i == 2) {
+                    d.setLeaf(true);
+                }
+                if (i == 1 && !String.valueOf(d.getId()).substring(4).equals("00")) {
+                    d.setLeaf(true);
+                }
+                districtRepo.save(d);
+            }
+        }
+    }
+
+    private District convert(DistrictResponse.District district) {
+        District res = new District();
+        res.setId((long) district.getId());
+        res.setName(district.getName());
+        res.setFullName(district.getFullname());
+        res.setLat(district.getLocation().getLat());
+        res.setLng(district.getLocation().getLng());
+        res.setPinyin(StringUtils.join(district.getPinyin(), " "));
+        return res;
+    }
+}

+ 29 - 0
src/main/java/com/izouma/awesomeAdmin/utils/qqmap/DistrictResponse.java

@@ -0,0 +1,29 @@
+package com.izouma.awesomeAdmin.utils.qqmap;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class DistrictResponse {
+    private int                  status;
+    private String               message;
+    private String               data_version;
+    private List<List<District>> result;
+
+    @Data
+    public static class District {
+        private int           id;
+        private String        name;
+        private String        fullname;
+        private Location      location;
+        private List<String>  pinyin;
+        private List<Integer> cidx;
+    }
+
+    @Data
+    public static class Location {
+        private Double lat;
+        private Double lng;
+    }
+}

+ 11 - 0
src/main/java/com/izouma/awesomeAdmin/utils/qqmap/QQMapUtil.java

@@ -0,0 +1,11 @@
+package com.izouma.awesomeAdmin.utils.qqmap;
+
+import com.alibaba.fastjson.JSON;
+import com.github.kevinsawicki.http.HttpRequest;
+
+public class QQMapUtil {
+    public static DistrictResponse queryDistrict() {
+        return JSON.parseObject(HttpRequest.get("https://apis.map.qq.com/ws/district/v1/list?key=YO4BZ-G75L5-CWJIV-QDPOY-77OIH-LGFMT")
+                .body(), DistrictResponse.class);
+    }
+}

+ 60 - 0
src/main/java/com/izouma/awesomeAdmin/web/DistrictController.java

@@ -0,0 +1,60 @@
+package com.izouma.awesomeAdmin.web;
+
+import com.izouma.awesomeAdmin.domain.District;
+import com.izouma.awesomeAdmin.dto.PageQuery;
+import com.izouma.awesomeAdmin.exception.BusinessException;
+import com.izouma.awesomeAdmin.repo.DistrictRepo;
+import com.izouma.awesomeAdmin.service.DistrictService;
+import com.izouma.awesomeAdmin.utils.ObjUtils;
+import com.izouma.awesomeAdmin.utils.excel.ExcelUtils;
+import lombok.AllArgsConstructor;
+import org.springframework.data.domain.Page;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+
+@RestController
+@RequestMapping("/district")
+@AllArgsConstructor
+public class DistrictController extends BaseController {
+    private DistrictService districtService;
+    private DistrictRepo    districtRepo;
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/save")
+    public District save(@RequestBody District record) {
+        if (record.getId() != null) {
+            District orig = districtRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
+            ObjUtils.merge(orig, record);
+            return districtRepo.save(orig);
+        }
+        return districtRepo.save(record);
+    }
+
+
+    //@PreAuthorize("hasRole('ADMIN')")
+    @GetMapping("/all")
+    public Page<District> all(PageQuery pageQuery) {
+        return districtRepo.findAll(toSpecification(pageQuery,District.class), toPageRequest(pageQuery));
+    }
+
+    @GetMapping("/get/{id}")
+    public District get(@PathVariable Long id) {
+        return districtRepo.findById(id).orElseThrow(new BusinessException("无记录"));
+    }
+
+    @PostMapping("/del/{id}")
+    public void del(@PathVariable Long id) {
+        districtRepo.deleteById(id);
+    }
+
+    @GetMapping("/excel")
+    @ResponseBody
+    public void excel(HttpServletResponse response, PageQuery pageQuery) throws IOException {
+        List<District> data = all(pageQuery).getContent();
+        ExcelUtils.export(response, data);
+    }
+}
+

+ 61 - 0
src/main/vue/src/components/DistrictChoose.vue

@@ -0,0 +1,61 @@
+<template>
+    <div style="display:inline-block">
+        <el-cascader :props="props" filterable v-model="chooseValue" v-if="show" @change="onChange"></el-cascader>
+    </div>
+</template>
+<script>
+    export default {
+        props: {
+            value: {
+                type: Array
+            }
+        },
+        data() {
+            return {
+                show: true,
+                chooseValue: [],
+                props: {
+                    lazy: true,
+                    lazyLoad: (node, resolve) => {
+                        const { level } = node;
+                        let params = { size: 10000, query: { level: level } };
+                        if (level !== 0) {
+                            params.query.parent = node.data.id;
+                        }
+                        this.$http.get('/district/all', params).then(res => {
+                            resolve(res.content);
+                        });
+                    },
+                    value: 'id',
+                    label: 'fullName',
+                    leaf: 'leaf'
+                },
+                emiting: false
+            };
+        },
+        created() {
+            if (this.value) {
+                this.chooseValue = this.value;
+            }
+        },
+        methods: {
+            onChange(e) {
+                this.emiting = true;
+                this.$emit('input', [...e]);
+                this.$nextTick(() => {
+                    this.emiting = false;
+                });
+            }
+        },
+        watch: {
+            value(val) {
+                if (this.emiting) return;
+                this.show = false;
+                this.$nextTick(() => {
+                    this.chooseValue = val;
+                    this.show = true;
+                });
+            }
+        }
+    };
+</script>

+ 2 - 0
src/main/vue/src/main.js

@@ -11,6 +11,7 @@ import SingleUpload from '@/components/SingleUpload';
 import FileUpload from '@/components/FileUpload';
 import RichText from '@/components/RichText';
 import CropUpload from '@/components/CropUpload';
+import DistrictChoose from '@/components/DistrictChoose';
 import Formatters from '@/mixins/formatters';
 import 'normalize.css/normalize.css';
 import 'element-ui/lib/theme-chalk/index.css';
@@ -44,6 +45,7 @@ Vue.component('single-upload', SingleUpload);
 Vue.component('file-upload', FileUpload);
 Vue.component('rich-text', RichText);
 Vue.component('crop-upload', CropUpload);
+Vue.component('district-choose', DistrictChoose);
 Vue.mixin(Formatters);
 
 new Vue({

+ 19 - 13
src/main/vue/src/plugins/http.js

@@ -16,7 +16,7 @@ switch (process.env.NODE_ENV) {
         break;
 }
 const axiosInstance = axios.create({
-    baseURL: baseUrl,
+    baseURL: baseUrl
 });
 
 axiosInstance.interceptors.request.use(
@@ -30,7 +30,7 @@ axiosInstance.interceptors.request.use(
     },
     function(error) {
         return Promise.reject(error);
-    },
+    }
 );
 
 axiosInstance.interceptors.response.use(
@@ -38,20 +38,26 @@ axiosInstance.interceptors.response.use(
         return response;
     },
     function(error) {
-        console.log(error);
-        if (401 === error.response.status) {
+        let errorData = {};
+        if (error instanceof Error) {
+            console.error(error.name + '::' + error.message);
+            errorData = {
+                error: error.message
+            };
+        } else if (401 === error.response.status) {
+            errorData = error.response.data;
             if (router.currentRoute.name !== 'login') {
                 router.replace({
                     name: 'login',
                     params: {
-                        from: router.currentRoute.name,
-                    },
+                        from: router.currentRoute.name
+                    }
                 });
-            }else{
+            } else {
             }
         }
-        return Promise.reject(error.response.data);
-    },
+        return Promise.reject(errorData);
+    }
 );
 export default {
     axios: axiosInstance,
@@ -66,9 +72,9 @@ export default {
                         .get(
                             url,
                             {
-                                params: params,
+                                params: params
                             },
-                            { withCredentials: true },
+                            { withCredentials: true }
                         )
                         .then(res => {
                             resolve(res.data);
@@ -96,7 +102,7 @@ export default {
                             reject(e);
                         });
                 });
-            },
+            }
         };
-    },
+    }
 };