487 lines
15 KiB
JavaScript
487 lines
15 KiB
JavaScript
import AMapLoader from "@amap/amap-jsapi-loader";
|
|
import { LicenseMixin, UNAUTHORIZED_TIP } from "../../utils/license-util";
|
|
import props from "./props";
|
|
function normalizeComponent(scriptExports, render2, staticRenderFns, functionalTemplate, injectStyles, scopeId, moduleIdentifier, shadowMode) {
|
|
var options = typeof scriptExports === "function" ? scriptExports.options : scriptExports;
|
|
if (render2) {
|
|
options.render = render2;
|
|
options.staticRenderFns = staticRenderFns;
|
|
options._compiled = true;
|
|
}
|
|
if (functionalTemplate) {
|
|
options.functional = true;
|
|
}
|
|
if (scopeId) {
|
|
options._scopeId = "data-v-" + scopeId;
|
|
}
|
|
var hook;
|
|
if (moduleIdentifier) {
|
|
hook = function(context) {
|
|
context = context || this.$vnode && this.$vnode.ssrContext || this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext;
|
|
if (!context && typeof __VUE_SSR_CONTEXT__ !== "undefined") {
|
|
context = __VUE_SSR_CONTEXT__;
|
|
}
|
|
if (injectStyles) {
|
|
injectStyles.call(this, context);
|
|
}
|
|
if (context && context._registeredComponents) {
|
|
context._registeredComponents.add(moduleIdentifier);
|
|
}
|
|
};
|
|
options._ssrRegister = hook;
|
|
} else if (injectStyles) {
|
|
hook = shadowMode ? function() {
|
|
injectStyles.call(
|
|
this,
|
|
(options.functional ? this.parent : this).$root.$options.shadowRoot
|
|
);
|
|
} : injectStyles;
|
|
}
|
|
if (hook) {
|
|
if (options.functional) {
|
|
options._injectStyles = hook;
|
|
var originalRender = options.render;
|
|
options.render = function renderWithStyleInjection(h, context) {
|
|
hook.call(context);
|
|
return originalRender(h, context);
|
|
};
|
|
} else {
|
|
var existing = options.beforeCreate;
|
|
options.beforeCreate = existing ? [].concat(existing, hook) : [hook];
|
|
}
|
|
}
|
|
return {
|
|
exports: scriptExports,
|
|
options
|
|
};
|
|
}
|
|
const ICON_CLASS = "ele-map-picker-main-icon";
|
|
const _sfc_main = {
|
|
name: "MapView",
|
|
mixins: [LicenseMixin],
|
|
props,
|
|
emits: ["done", "map-done"],
|
|
data() {
|
|
return {
|
|
loading: true,
|
|
poiLoading: false,
|
|
confirmLoading: false,
|
|
data: [],
|
|
suggestionData: [],
|
|
centerIconClass: ["ele-map-picker-main-icon"],
|
|
keywords: "",
|
|
lastSuggestion: "",
|
|
selectedSuggestion: null,
|
|
isItemClickMove: false,
|
|
mapIns: null,
|
|
placeSearchIns: null,
|
|
autoCompleteIns: null,
|
|
centerMarker: null
|
|
};
|
|
},
|
|
computed: {
|
|
searchPopClass() {
|
|
const classes = ["ele-map-picker-search-pop"];
|
|
if (this.searchType !== 0) {
|
|
classes.push("ele-map-picker-hide");
|
|
}
|
|
return classes.join(" ");
|
|
}
|
|
},
|
|
methods: {
|
|
renderMap() {
|
|
if (!this.mapKey || this.mapIns) {
|
|
return;
|
|
}
|
|
AMapLoader.load({
|
|
key: this.mapKey,
|
|
version: this.mapVersion,
|
|
plugins: ["AMap.PlaceSearch", "AMap.AutoComplete"]
|
|
}).then((AMap) => {
|
|
this.destroyAll();
|
|
this.autoCompleteIns = new AMap.AutoComplete({
|
|
city: this.suggestionCity
|
|
});
|
|
this.placeSearchIns = new AMap.PlaceSearch({
|
|
type: this.poiType,
|
|
pageSize: this.poiSize,
|
|
pageIndex: 1
|
|
});
|
|
const mapStyle = (() => {
|
|
if (this.mapStyle) {
|
|
return this.mapStyle;
|
|
}
|
|
if (this.darkMode) {
|
|
return "amap://styles/dark";
|
|
}
|
|
})();
|
|
this.mapIns = new AMap.Map(this.$refs.mapRef, {
|
|
zoom: this.zoom,
|
|
center: this.center,
|
|
resizeEnable: true,
|
|
mapStyle
|
|
});
|
|
this.mapIns.on("complete", () => {
|
|
this.loading = false;
|
|
const { lng, lat } = this.mapIns.getCenter();
|
|
this.searchPoi(lng, lat);
|
|
});
|
|
this.mapIns.on("moveend", () => {
|
|
if (this.isItemClickMove) {
|
|
this.isItemClickMove = false;
|
|
} else if (this.searchType === 0) {
|
|
this.bounceIcon();
|
|
const { lng, lat } = this.mapIns.getCenter();
|
|
this.searchPoi(lng, lat);
|
|
}
|
|
});
|
|
this.centerMarker = new AMap.Marker({
|
|
icon: new AMap.Icon({
|
|
image: this.markerSrc,
|
|
size: new AMap.Size(26, 36.5),
|
|
imageSize: new AMap.Size(26, 36.5)
|
|
}),
|
|
offset: new AMap.Pixel(-13, -36.5)
|
|
});
|
|
this.$emit("map-done", this.mapIns);
|
|
}).catch((e) => {
|
|
console.error(e);
|
|
});
|
|
},
|
|
onSearch(value, callback) {
|
|
if (!value || this.lastSuggestion === value) {
|
|
callback(this.suggestionData);
|
|
return;
|
|
}
|
|
this.lastSuggestion = value;
|
|
if (this.searchType !== 0) {
|
|
this.poiLoading = true;
|
|
}
|
|
this.searchKeywords(value).then((result) => {
|
|
if (this.searchType !== 0) {
|
|
this.data = result;
|
|
this.poiLoading = false;
|
|
this.removeCenterMarker();
|
|
callback([]);
|
|
} else {
|
|
this.suggestionData = result;
|
|
callback(this.suggestionData);
|
|
}
|
|
}).catch((e) => {
|
|
console.error(e);
|
|
this.poiLoading = false;
|
|
});
|
|
},
|
|
onSelect(item) {
|
|
if (!this.data.length || this.data[0].name !== item.name) {
|
|
this.data = [
|
|
{ ...item, selected: true },
|
|
...this.data.map((d) => {
|
|
return { ...d, selected: false };
|
|
})
|
|
];
|
|
}
|
|
this.setMapCenter(
|
|
item.location.lng,
|
|
item.location.lat,
|
|
this.chooseZoom
|
|
);
|
|
this.selectedSuggestion = item;
|
|
},
|
|
onChoose(item) {
|
|
this.isItemClickMove = true;
|
|
this.data = this.data.map((d) => {
|
|
return {
|
|
...d,
|
|
selected: d === item
|
|
};
|
|
});
|
|
const { lng, lat } = item.location;
|
|
this.setMapCenter(lng, lat, this.chooseZoom);
|
|
if (this.searchType === 0) {
|
|
this.bounceIcon();
|
|
} else {
|
|
this.showCenterMarker(lng, lat);
|
|
}
|
|
},
|
|
onSuggestionBlur() {
|
|
if (this.searchType === 0) {
|
|
this.suggestionKeyWords = "";
|
|
}
|
|
},
|
|
onDone() {
|
|
if (!this.authenticated) {
|
|
console.warn(UNAUTHORIZED_TIP);
|
|
return;
|
|
}
|
|
const selected = this.getSelected();
|
|
if (!selected) {
|
|
if (this.forceChoose) {
|
|
this.$message.error(this.tipMessage);
|
|
return;
|
|
}
|
|
this.confirmLoading = true;
|
|
this.getMapCenter(this.needCity).then((result) => {
|
|
this.confirmLoading = false;
|
|
this.$emit("done", result);
|
|
}).catch((e) => {
|
|
console.error(e);
|
|
this.confirmLoading = false;
|
|
this.$emit("done", {});
|
|
});
|
|
return;
|
|
}
|
|
const location = {
|
|
...selected.location,
|
|
name: selected.name,
|
|
address: selected.address || ""
|
|
};
|
|
if (this.needCity) {
|
|
this.confirmLoading = true;
|
|
this.setMapCenter(location.lng, location.lat);
|
|
this.getMapCenter(true).then(({ city }) => {
|
|
this.confirmLoading = false;
|
|
location.city = city;
|
|
this.$emit("done", location);
|
|
}).catch((e) => {
|
|
console.error(e);
|
|
this.confirmLoading = false;
|
|
this.$emit("done", location);
|
|
});
|
|
} else {
|
|
this.$emit("done", location);
|
|
}
|
|
},
|
|
searchKeywords(value) {
|
|
return new Promise((resolve, reject) => {
|
|
if (!this.autoCompleteIns) {
|
|
reject(new Error("AutoComplete instance is null"));
|
|
return;
|
|
}
|
|
this.autoCompleteIns.search(value, (_status, result) => {
|
|
if (!(result == null ? void 0 : result.tips)) {
|
|
resolve([]);
|
|
return;
|
|
}
|
|
const data = result.tips.filter((d) => !!d.location).map((d, i) => {
|
|
const label = `${d.name}(${d.district})`;
|
|
return {
|
|
...d,
|
|
text: label,
|
|
value: label,
|
|
key: d.id || label + "-" + i,
|
|
address: Array.isArray(d.address) ? d.address[0] : d.address
|
|
};
|
|
});
|
|
resolve(data);
|
|
});
|
|
});
|
|
},
|
|
searchPoi(lng, lat) {
|
|
this.poiLoading = true;
|
|
this.searchNearBy(lng, lat).then((result) => {
|
|
if (this.selectedSuggestion) {
|
|
if (result.length === 0 || result[0].name !== this.selectedSuggestion.name) {
|
|
this.data = [
|
|
{ ...this.selectedSuggestion, selected: true },
|
|
...result
|
|
];
|
|
} else {
|
|
this.data = result.map((d, i) => {
|
|
return { ...d, selected: i === 0 };
|
|
});
|
|
}
|
|
} else {
|
|
this.data = result;
|
|
}
|
|
this.poiLoading = false;
|
|
}).catch((e) => {
|
|
console.error(e);
|
|
this.poiLoading = false;
|
|
this.data = [];
|
|
});
|
|
},
|
|
searchNearBy(lng, lat) {
|
|
return new Promise((resolve, reject) => {
|
|
if (!this.placeSearchIns) {
|
|
reject(new Error("PlaceSearch instance is null"));
|
|
return;
|
|
}
|
|
this.placeSearchIns.searchNearBy(
|
|
this.poiKeywords,
|
|
[lng, lat],
|
|
this.poiRadius,
|
|
(status, result) => {
|
|
var _a;
|
|
if (status === "complete" && ((_a = result == null ? void 0 : result.poiList) == null ? void 0 : _a.pois)) {
|
|
const data = result.poiList.pois.filter((d) => !!d.location).map((d, i) => {
|
|
return { ...d, key: d.id || d.name + "-" + i };
|
|
});
|
|
resolve(data);
|
|
} else if (status === "no_data") {
|
|
resolve([]);
|
|
} else {
|
|
reject(new Error(status));
|
|
}
|
|
}
|
|
);
|
|
});
|
|
},
|
|
getSelected() {
|
|
return this.data.find((d) => d.selected);
|
|
},
|
|
bounceIcon() {
|
|
this.centerIconClass = [ICON_CLASS];
|
|
this.$nextTick(() => {
|
|
setTimeout(() => {
|
|
this.centerIconClass = [ICON_CLASS, "ele-map-picker-anim-bounce"];
|
|
}, 0);
|
|
});
|
|
},
|
|
removeCenterMarker() {
|
|
if (this.centerMarker && this.mapIns) {
|
|
this.mapIns.remove(this.centerMarker);
|
|
}
|
|
},
|
|
showCenterMarker(lng, lat) {
|
|
if (!this.centerMarker) {
|
|
console.error("centerMarker is null");
|
|
return;
|
|
}
|
|
if (!this.mapIns) {
|
|
console.error("map instance is null");
|
|
return;
|
|
}
|
|
if (lng != null && lat != null) {
|
|
this.centerMarker.setPosition([lng, lat]);
|
|
this.mapIns.add(this.centerMarker);
|
|
} else {
|
|
this.removeCenterMarker();
|
|
}
|
|
},
|
|
setMapCenter(lng, lat, zoom) {
|
|
if (this.mapIns && lng != null && lat != null) {
|
|
if (zoom == null) {
|
|
this.mapIns.setCenter([lng, lat]);
|
|
} else {
|
|
this.mapIns.setZoomAndCenter(zoom, [lng, lat]);
|
|
}
|
|
}
|
|
},
|
|
getMapCenter(needCity) {
|
|
return new Promise((resolve, reject) => {
|
|
if (!this.mapIns) {
|
|
reject(new Error("map instance is null"));
|
|
return;
|
|
}
|
|
const result = this.mapIns.getCenter();
|
|
if (needCity) {
|
|
this.mapIns.getCity((city) => {
|
|
result.city = city;
|
|
resolve(result);
|
|
});
|
|
} else {
|
|
resolve(result);
|
|
}
|
|
});
|
|
},
|
|
changeMapStyle(value) {
|
|
if (this.mapIns) {
|
|
if (typeof value === "boolean") {
|
|
if (value) {
|
|
this.mapIns.setMapStyle("amap://styles/dark");
|
|
} else {
|
|
this.mapIns.setMapStyle("amap://styles/normal");
|
|
}
|
|
} else if (value) {
|
|
this.mapIns.setMapStyle(value);
|
|
}
|
|
}
|
|
},
|
|
destroyMap() {
|
|
this.mapIns && this.mapIns.destroy();
|
|
this.centerMarker = null;
|
|
this.placeSearchIns = null;
|
|
this.autoCompleteIns = null;
|
|
this.mapIns = null;
|
|
},
|
|
destroyAll() {
|
|
this.destroyMap();
|
|
this.data = [];
|
|
this.suggestionData = [];
|
|
this.keywords = "";
|
|
this.lastSuggestion = "";
|
|
this.selectedSuggestion = null;
|
|
this.isItemClickMove = false;
|
|
},
|
|
getMapIns() {
|
|
return this.mapIns;
|
|
}
|
|
},
|
|
watch: {
|
|
darkMode(darkMode) {
|
|
if (!this.mapStyle) {
|
|
this.changeMapStyle(darkMode);
|
|
}
|
|
},
|
|
mapStyle(mapStyle) {
|
|
if (mapStyle) {
|
|
this.changeMapStyle(mapStyle);
|
|
}
|
|
},
|
|
searchType(searchType) {
|
|
this.keywords = "";
|
|
this.suggestionData = [];
|
|
this.selectedSuggestion = null;
|
|
this.lastSuggestion = "";
|
|
this.removeCenterMarker();
|
|
if (searchType === 1) {
|
|
const selected = this.getSelected();
|
|
if (selected) {
|
|
const { lng, lat } = selected.location;
|
|
this.showCenterMarker(lng, lat);
|
|
}
|
|
}
|
|
},
|
|
mapKey() {
|
|
this.destroyAll();
|
|
this.renderMap();
|
|
}
|
|
},
|
|
mounted() {
|
|
this.renderMap();
|
|
},
|
|
unmounted() {
|
|
this.destroyAll();
|
|
}
|
|
};
|
|
var _sfc_render = function render() {
|
|
var _vm = this, _c = _vm._self._c;
|
|
return _c("div", { directives: [{ name: "loading", rawName: "v-loading", value: _vm.loading, expression: "loading" }] }, [_c("div", { staticClass: "ele-map-picker-header" }, [_c("div", { staticClass: "ele-map-picker-header-search" }, [_c("el-autocomplete", { attrs: { "size": "small", "fetch-suggestions": _vm.onSearch, "placeholder": _vm.searchPlaceholder || _vm.t("ele.map.placeholder"), "popper-class": _vm.searchPopClass }, on: { "select": _vm.onSelect, "blur": _vm.onSuggestionBlur }, scopedSlots: _vm._u([{ key: "suffix", fn: function() {
|
|
return [_c("i", { staticClass: "el-icon-search el-input__icon" })];
|
|
}, proxy: true }, { key: "default", fn: function({ item }) {
|
|
return [_c("div", { staticClass: "ele-map-picker-suggestion-item", attrs: { "title": item.text } }, [_vm._v(" " + _vm._s(item.text) + " ")])];
|
|
} }]), model: { value: _vm.keywords, callback: function($$v) {
|
|
_vm.keywords = $$v;
|
|
}, expression: "keywords" } })], 1), _c("el-button", { staticClass: "ele-btn-icon", attrs: { "size": "small", "type": "primary", "icon": "el-icon-check", "loading": _vm.confirmLoading }, on: { "click": _vm.onDone } }, [_vm._v(" " + _vm._s(_vm.okText) + " ")])], 1), _c("div", { staticClass: "ele-map-picker-body" }, [_c("div", { staticClass: "ele-map-picker-main" }, [_c("div", { ref: "mapRef", style: { height: _vm.height } }), _vm.searchType === 0 ? [_c("i", { staticClass: "ele-map-picker-main-plus el-icon-plus" }), _c("img", { class: _vm.centerIconClass, attrs: { "src": _vm.markerSrc, "alt": "" } })] : _vm._e()], 2), _c("div", { directives: [{ name: "loading", rawName: "v-loading", value: _vm.poiLoading, expression: "poiLoading" }], staticClass: "ele-map-picker-poi-list", style: { height: _vm.height } }, _vm._l(_vm.data, function(item) {
|
|
return _c("div", { key: item.key, class: ["ele-map-picker-poi-item", { active: item.selected }], on: { "click": function($event) {
|
|
return _vm.onChoose(item);
|
|
} } }, [_c("i", { staticClass: "ele-map-picker-poi-item-icon el-icon-location-outline" }), _c("div", { staticClass: "ele-map-picker-poi-item-title" }, [_vm._v(_vm._s(item.name))]), item.address ? _c("div", { staticClass: "ele-map-picker-poi-item-address" }, [_vm._v(" " + _vm._s(item.address) + " ")]) : _vm._e(), _c("i", { staticClass: "el-icon-circle-check ele-map-picker-poi-item-check" })]);
|
|
}), 0)])]);
|
|
};
|
|
var _sfc_staticRenderFns = [];
|
|
var __component__ = /* @__PURE__ */ normalizeComponent(
|
|
_sfc_main,
|
|
_sfc_render,
|
|
_sfc_staticRenderFns,
|
|
false,
|
|
null,
|
|
null,
|
|
null,
|
|
null
|
|
);
|
|
const mapView = __component__.exports;
|
|
export {
|
|
mapView as default
|
|
};
|