drew 5 лет назад
Родитель
Сommit
b19bfbe0ee

+ 256 - 0
src/main/vue/src/components/CoordPick.vue

@@ -0,0 +1,256 @@
+<template>
+    <div class="map-wrapper">
+        <el-amap
+                ref="map"
+                :center="mapCenter"
+                :zoom="zoom"
+                class="map-view"
+                :events="mapEvents"
+                :expandZoomRange="true"
+        >
+            <el-amap-marker
+                    v-if="myPosition"
+                    :position="myPosition"
+                    content="<div class='my-position'><div>"
+                    cursor="default"
+            >
+            </el-amap-marker>
+            <el-amap-marker
+                    v-if="marker"
+                    :position="marker"
+                    :draggable="true"
+                    :events="markerEvents"
+                    cursor="default"
+            >
+            </el-amap-marker>
+        </el-amap>
+        <el-amap-search-box
+                class="search-box"
+                :search-option="searchOption"
+                :on-search-result="onSearchResult"
+        >
+        </el-amap-search-box>
+        <div class="btn-locate" @click="locate">
+            <i
+                    :class="{
+                    'el-icon-loading': locating,
+                    'el-icon-location-outline': !locating
+                }"
+            ></i>
+        </div>
+        <div class="btn-minus" @click="setZoom(-1)">
+            <i class="el-icon-minus"></i>
+        </div>
+        <div class="btn-plus" @click="setZoom(1)">
+            <i class="el-icon-plus"></i>
+        </div>
+    </div>
+</template>
+<script>
+    export default {
+        props: {
+            searchOption: {
+                type: Object,
+                default() {
+                    return {
+                        city: "全国",
+                        citylimit: false
+                    };
+                }
+            },
+            center: {
+                type: Array
+            },
+            zoom: {
+                type: Number,
+                default: 15
+            },
+            value: {
+                type: Array
+            }
+        },
+        data() {
+            let self = this;
+            return {
+                locating: false,
+                myPosition: null,
+                marker: null,
+                mapEvents: {
+                    complete() {
+                        self.$refs.map.$$getInstance().setDefaultCursor("default");
+                    },
+                    click(e) {
+                        self.marker = [e.lnglat.O, e.lnglat.P];
+                        self.mapCenter = [e.lnglat.O, e.lnglat.P];
+                        self.getGeolocation();
+                    }
+                },
+                markerEvents: {
+                    dragend(e) {
+                        self.marker = [e.lnglat.O, e.lnglat.P];
+                        self.mapCenter = [e.lnglat.O, e.lnglat.P];
+                        self.getGeolocation();
+                    }
+                },
+                mapCenter: [121.480342, 31.236339]
+            };
+        },
+        created() {
+            if (this.center) {
+                this.mapCenter = this.center;
+            }
+            if (this.value) {
+                this.mapCenter = this.value;
+                this.marker = this.value;
+            }
+        },
+        methods: {
+            locate() {
+                this.locating = true;
+                let geolocation = new AMap.Geolocation({
+                    enableHighAccuracy: true,
+                    timeout: 10000
+                });
+                geolocation.getCurrentPosition();
+                AMap.event.addListener(geolocation, "complete", data => {
+                    this.locating = false;
+                    this.mapCenter = [data.position.O, data.position.P];
+                    this.myPosition = [data.position.O, data.position.P];
+                });
+                AMap.event.addListener(geolocation, "error", err => {
+                    this.locating = false;
+                    console.log(err);
+                });
+            },
+            onSearchResult(pois) {
+                let latSum = 0;
+                let lngSum = 0;
+                if (pois.length > 0) {
+                    pois.forEach(poi => {
+                        let { lng, lat } = poi;
+                        lngSum += lng;
+                        latSum += lat;
+                    });
+                    let center = {
+                        lng: lngSum / pois.length,
+                        lat: latSum / pois.length
+                    };
+                    this.mapCenter = [center.lng, center.lat];
+                }
+            },
+            setZoom(d) {
+                this.$refs.map
+                    .$$getInstance()
+                    .setZoom(this.$refs.map.$$getInstance().getZoom() + d);
+            },
+            getGeolocation() {
+                let lnglat = this.marker;
+                AMap.plugin("AMap.Geocoder", () => {
+                    let geocoder = new AMap.Geocoder();
+                    geocoder.getAddress(lnglat, (status, result) => {
+                        if (status === "complete" && result.info === "OK") {
+                            this.$emit("selected", {
+                                lnglat: {
+                                    lng: lnglat[0],
+                                    lat: lnglat[1]
+                                },
+                                ...result.regeocode
+                            });
+                        }
+                    });
+                });
+            }
+        },
+        watch: {
+            value(val) {
+                this.mapCenter = val;
+                this.marker = val;
+            }
+        }
+    };
+</script>
+<style lang="less" scoped>
+    .map-wrapper {
+        position: relative;
+        .map-view {
+            width: 100%;
+            height: 400px;
+        }
+        .btn-locate {
+            width: 30px;
+            height: 30px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            font-size: 16px;
+            color: #666;
+            position: absolute;
+            left: 10px;
+            bottom: 10px;
+            background: #fff;
+            border-radius: 2px;
+            box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3);
+            &:active {
+                background: #f2f3f4;
+            }
+        }
+        .btn-minus {
+            width: 30px;
+            height: 30px;
+            font-size: 16px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            color: #666;
+            position: absolute;
+            left: 10px;
+            bottom: 50px;
+            background: #fff;
+            border-radius: 2px;
+            box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3);
+            &:active {
+                background: #f2f3f4;
+            }
+        }
+        .btn-plus {
+            width: 30px;
+            height: 30px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            font-size: 16px;
+            color: #666;
+            position: absolute;
+            left: 10px;
+            bottom: 90px;
+            background: #fff;
+            border-radius: 2px;
+            box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3);
+            &:active {
+                background: #f2f3f4;
+            }
+        }
+        .search-box {
+            position: absolute;
+            top: 10px;
+            left: 10px;
+        }
+    }
+</style>
+<style lang="less">
+    .anchorBL,
+    .amap-logo,
+    .amap-copyright {
+        display: none !important;
+    }
+
+    .my-position {
+        width: 14px;
+        height: 14px;
+        border-radius: 50%;
+        border: 3px solid #fff;
+        background: #20a0ff;
+        box-shadow: 0 2px 2px rgba(0, 0, 0, 0.15);
+        position: relative;
+    }
+</style>

+ 83 - 25
src/main/vue/src/components/FileUpload.vue

@@ -1,37 +1,95 @@
 <template>
-    <el-upload class="upload-demo" :action="$baseUrl + '/assets/uploadFile'"
-        :on-success="onSuccess" :on-remove="onRemove">
-        <el-button type="primary" v-if="!single || fileList.length===0">点击上传
+    <el-upload
+            class="upload-demo"
+            :action="$baseUrl + '/upload/file'"
+            :on-success="onSuccess"
+            :on-remove="onRemove"
+            :headers="headers"
+            :file-list="fileList"
+    >
+        <el-button
+                type="primary"
+                :disabled="!(!single || fileList.length === 0)"
+                size="mini"
+        >点击上传
         </el-button>
     </el-upload>
 </template>
 
 <script>
-export default {
-    name: "FileUpload",
-    props: {
-        single: {
-            type: Boolean,
-            default() {
-                return false;
+    export default {
+        name: "FileUpload",
+        props: {
+            single: {
+                type: Boolean,
+                default() {
+                    return false;
+                }
+            },
+            value: {}
+        },
+        data() {
+            return {
+                fileList: [],
+                watchValue: true
+            };
+        },
+        computed: {
+            headers() {
+                return {
+                    Authorization: "Bearer " + localStorage.getItem("token")
+                };
             }
-        }
-    },
-    data() {
-        return {
-            fileList: []
-        };
-    },
-    methods: {
-        onSuccess(res, file, fileList) {
-            this.fileList = fileList;
-            this.$emit("input", res.data[0]);
         },
-        onRemove(file, fileList) {
-            this.fileList = fileList;
+        created() {
+            this.update(this.value);
+        },
+        methods: {
+            onSuccess(res, file, fileList) {
+                file.url = res;
+                this.fileList = fileList;
+            },
+            onRemove(file, fileList) {
+                this.fileList = fileList;
+            },
+            update(value) {
+                if (this.single) {
+                    this.fileList = value
+                        ? [{ name: value.split("/").pop(), url: value }]
+                        : [];
+                } else {
+                    if (!value) {
+                        this.fileList = [];
+                    } else {
+                        this.fileList = value.map(i => {
+                            return { name: i.split("/").pop(), url: i };
+                        });
+                    }
+                }
+            }
+        },
+        watch: {
+            value(oldValue, value) {
+                if (!this.watchValue) return;
+                console.log("watch::");
+                this.update(value);
+            },
+            fileList(fileList) {
+                this.watchValue = false;
+                if (this.single) {
+                    this.$emit("input", fileList[0] ? fileList[0].url : null);
+                } else {
+                    this.$emit(
+                        "input",
+                        fileList.map(i => i.url)
+                    );
+                }
+                this.$nextTick(() => {
+                    this.watchValue = true;
+                });
+            }
         }
-    }
-};
+    };
 </script>
 
 <style scoped>

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

@@ -14,6 +14,25 @@ import Formatters from '@/mixins/formatters';
 import 'normalize.css/normalize.css';
 import 'element-ui/lib/theme-chalk/index.css';
 
+// import VueAMap from "vue-amap";
+// Vue.use(VueAMap);
+// VueAMap.initAMapApiLoader({
+//     key: "bf91055058a47a7dc387e40ab6256a5f",
+//     plugin: [
+//         "Autocomplete",
+//         "PlaceSearch",
+//         "Scale",
+//         "OverView",
+//         "ToolBar",
+//         "MapType",
+//         "PolyEditor",
+//         "AMap.CircleEditor",
+//         "AMap.Geolocation",
+//     ],
+//     uiVersion: "1.0.11",
+//     v: "1.4.4",
+// });
+
 Vue.config.productionTip = false;
 Vue.use(ElementUI, { size: 'small' });
 Vue.use(http);