| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- <template>
- <div class="select-location">
- <custom-header :name="headerName"></custom-header>
- <div class="select-location-content">
- <div class="search-bar">
- <location-search
- class="location-search"
- :user-location="userLocation"
- @change="handleLocationChange"
- />
- </div>
- <div class="map-container" ref="mapContainer"></div>
- <div class="locate-btn" @click="handleLocate">
- <img class="locate-icon" src="@/assets/img/map/map-icon.png" alt="" />
- </div>
- </div>
- <div class="custom-bottom-fixed-btns">
- <div class="bottom-btn primary-btn" @click="handleSubmit">确认点位</div>
- </div>
- <add-zone-info-popup
- v-if="fromAgriAlbum"
- v-model:show="showZoneInfoPopup"
- :county-code="pendingZoneLocation?.adcode"
- :point-location="pendingZoneLocation?.point || ''"
- @confirm="handleZoneInfoConfirm"
- />
- </div>
- </template>
- <script setup>
- import { onMounted, onUnmounted, ref } from "vue";
- import { useRouter, useRoute } from "vue-router";
- import { useStore } from "vuex";
- import { ElMessage } from "element-plus";
- import customHeader from "@/components/customHeader.vue";
- import locationSearch from "@/components/pageComponents/locationSearch.vue";
- import SelectLocationMap, { mapLocation, POINT_ICON } from "./map/selectLocationMap.js";
- import { convertPointToArray } from "@/utils/index";
- import addZoneInfoPopup from "@/views/old_mini/agri_file/components/addZoneInfoPopup.vue";
- const SESSION_KEY_RESIDENT = "ENTRY_RESIDENT_LOCATION";
- const SESSION_KEY_GROWTH = "GROWTH_REPORT_LOCATION";
- const DEFAULT_POINT = "POINT(113.6142086995688 23.585836479509055)";
- const MAP_KEY = "CZLBZ-LJICQ-R4A5J-BN62X-YXCRJ-GNBUT";
- const router = useRouter();
- const route = useRoute();
- const store = useStore();
- const mapContainer = ref(null);
- const isPlantPoint = route.query.pointType === "plant";
- const fromGrowthReport = route.query.from === "growth_report";
- const fromService = route.query.from === "entry_service";
- const fromAgriAlbum = route.query.from === "agri_album";
- const headerName = fromGrowthReport ? "切换位置" : fromService ? "选择位置" : "选择种植点位";
- const sessionKey = fromGrowthReport ? SESSION_KEY_GROWTH : SESSION_KEY_RESIDENT;
- const iconSrc =
- route.query.iconType && POINT_ICON[route.query.iconType]
- ? POINT_ICON[route.query.iconType]
- : isPlantPoint
- ? POINT_ICON.plant
- : POINT_ICON.resident;
- const userLocation = ref(
- store.state.home.miniUserLocation || localStorage.getItem("MINI_USER_LOCATION") || "113.61702297075017,23.584863449735067"
- );
- /** 搜索选中时带出的区县编码 */
- const selectedAdcode = ref("");
- /** 搜索选中时带出的地址文案 */
- const selectedAddress = ref("");
- const showZoneInfoPopup = ref(false);
- const pendingZoneLocation = ref(null);
- const selectLocationMap = new SelectLocationMap({
- iconSrc,
- onMapClick: () => {
- selectedAdcode.value = "";
- selectedAddress.value = "";
- },
- });
- function getDefaultPoint() {
- if (route.query.mapCenter) return route.query.mapCenter;
- return (
- localStorage.getItem("MINI_USER_LOCATION_POINT") ||
- store.state.home.miniUserLocationPoint ||
- DEFAULT_POINT
- );
- }
- function toPointWkt(coordinate) {
- const lng = Number(coordinate[0]);
- const lat = Number(coordinate[1]);
- return `POINT(${lng} ${lat})`;
- }
- async function fetchLocationInfoByCoordinate(coordinate) {
- if (!coordinate?.length) return { adcode: "", address: "" };
- try {
- const { result } = await VE_API.old_mini_map.location({
- key: MAP_KEY,
- location: `${coordinate[1]},${coordinate[0]}`,
- });
- const adcode = result?.ad_info?.adcode;
- const address =
- result?.formatted_addresses?.recommend ||
- result?.address ||
- (result?.address_component
- ? `${result.address_component.city || ""}${result.address_component.district || ""}`
- : "");
- return {
- adcode: adcode != null && adcode !== "" ? String(adcode) : "",
- address: address || "",
- };
- } catch {
- return { adcode: "", address: "" };
- }
- }
- onMounted(() => {
- const point = getDefaultPoint();
- selectLocationMap.initMap(point, mapContainer.value);
- });
- onUnmounted(() => {
- selectLocationMap.clearLayer();
- });
- const handleLocationChange = (payload) => {
- if (!payload?.coordinateArray) {
- selectedAdcode.value = "";
- selectedAddress.value = "";
- return;
- }
- selectedAdcode.value = payload.adcode ? String(payload.adcode) : "";
- selectedAddress.value = payload.address || payload.pointAddress || "";
- selectLocationMap.setMapPosition(payload.coordinateArray);
- };
- const handleLocate = () => {
- selectedAdcode.value = "";
- selectedAddress.value = "";
- const point =
- localStorage.getItem("MINI_USER_LOCATION_POINT") ||
- store.state.home.miniUserLocationPoint ||
- DEFAULT_POINT;
- const coordinate = convertPointToArray(point).map(Number);
- selectLocationMap.setMapPosition(coordinate);
- };
- const handleSubmit = async () => {
- const coordinate = mapLocation.data;
- if (!coordinate) {
- ElMessage.warning(
- fromGrowthReport || fromService ? "请选择位置" : isPlantPoint ? "请选择种植点位" : "请选择常驻点位"
- );
- return;
- }
- const point = toPointWkt(coordinate);
- let adcode = selectedAdcode.value;
- let address = selectedAddress.value;
- if (!adcode || !address) {
- const info = await fetchLocationInfoByCoordinate(coordinate);
- if (!adcode) adcode = info.adcode;
- if (!address) address = info.address;
- }
- const payload = {
- point,
- coordinate: [Number(coordinate[0]), Number(coordinate[1])],
- adcode: adcode || "",
- address: address || "",
- };
- if (fromAgriAlbum) {
- payload.zoneType = route.query.zoneType || "region";
- pendingZoneLocation.value = payload;
- showZoneInfoPopup.value = true;
- return;
- }
- sessionStorage.setItem(sessionKey, JSON.stringify(payload));
- router.back();
- };
- const handleZoneInfoConfirm = () => {
- pendingZoneLocation.value = null;
- router.back();
- };
- </script>
- <style lang="scss" scoped>
- .select-location {
- width: 100%;
- height: 100vh;
- overflow: hidden;
- background: #fff;
- display: flex;
- flex-direction: column;
- .select-location-content {
- position: relative;
- flex: 1;
- overflow: hidden;
- .search-bar {
- position: absolute;
- top: 12px;
- left: 12px;
- right: 12px;
- z-index: 2;
- }
- .map-container {
- width: 100%;
- height: 100%;
- }
- .locate-btn {
- position: absolute;
- right: 12px;
- bottom: 40px;
- z-index: 2;
- width: 32px;
- height: 32px;
- display: flex;
- align-items: center;
- justify-content: center;
- background: #fff;
- border-radius: 8px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
- .locate-icon {
- width: 16px;
- height: 18px;
- }
- }
- }
- .custom-bottom-fixed-btns {
- position: relative;
- background: #fff;
- box-shadow: 2px 2px 5px 0px rgba(0, 0, 0, 0.4);
- .bottom-btn {
- padding: 0 30px;
- height: 40px;
- line-height: 40px;
- font-size: 14px;
- border-radius: 25px;
- }
- .primary-btn {
- background: #2199f8;
- color: #fff;
- }
- }
- }
- </style>
|