feat: 位置的组件字段对接

This commit is contained in:
2026-08-06 16:10:04 +08:00
parent b5206c18d1
commit cc1615162a
3 changed files with 76 additions and 22 deletions

View File

@@ -1,7 +1,8 @@
<template>
<view class="discovery-guide-map-tool-card" hover-class="is-pressed" hover-stay-time="80" @tap="handleSelect">
<view class="guide-map-visual">
<view class="guidepost-illustration">
<image v-if="normalizedItem.coverUrl" class="h-full w-full" :src="normalizedItem.coverUrl" mode="aspectFill" />
<view v-else class="guidepost-illustration">
<view class="guidepost-sign is-pink">
<view class="guidepost-line" />
</view>
@@ -25,12 +26,10 @@
<script setup>
import { computed } from "vue";
const DEFAULT_ITEM = {
id: "guide-map",
title: "卧龙潭电子导览图",
subTitle: "查看景区平面图与设施位置",
};
import {
getGuideMapNavigationOptions,
normalizeGuideMapItem,
} from "./model.mjs";
const props = defineProps({
item: {
@@ -39,21 +38,27 @@ const props = defineProps({
},
});
const emit = defineEmits(["didSelectItem"]);
const normalizedItem = computed(() => {
const source = Object.keys(props.item).length > 0 ? props.item : DEFAULT_ITEM;
return {
raw: source,
id: source.id ?? source.tabContentId ?? DEFAULT_ITEM.id,
title: source.title || DEFAULT_ITEM.title,
subTitle: source.subTitle || source.desc || DEFAULT_ITEM.subTitle,
};
});
const normalizedItem = computed(() => normalizeGuideMapItem(props.item));
const handleSelect = () => {
emit("didSelectItem", normalizedItem.value.raw);
const locationOptions = getGuideMapNavigationOptions(normalizedItem.value.raw);
if (!locationOptions) {
uni.showToast({
title: "暂无导航坐标",
icon: "none",
});
return;
}
uni.openLocation({
...locationOptions,
fail: () => {
uni.showToast({
title: "打开导航失败",
icon: "none",
});
},
});
};
</script>

View File

@@ -0,0 +1,50 @@
const normalizeGuideMapItem = (item) => {
const source = item && typeof item === "object" ? item : {};
const resource = source.resource || {};
const summary = resource.summary || {};
const payload = resource.payload || {};
const location = payload.location || {};
return {
raw: source,
id: resource.code || payload.poiCode || "",
resourceCode: resource.code || "",
resourceType: resource.type || "",
title: summary.title || payload.name || "",
subTitle: summary.subtitle || payload.description || "",
coverUrl: summary.coverUrl || "",
poiCode: payload.poiCode || "",
name: payload.name || summary.title || "",
categoryCode: payload.categoryCode || "",
address: payload.address || "",
description: payload.description || "",
latitude: location.latitude,
longitude: location.longitude,
};
};
const getGuideMapNavigationOptions = (item) => {
const normalizedItem = normalizeGuideMapItem(item);
const hasEmptyCoordinate = [normalizedItem.latitude, normalizedItem.longitude]
.some((value) => value === null || value === undefined || (typeof value === "string" && value.trim() === ""));
if (hasEmptyCoordinate) {
return null;
}
const latitude = Number(normalizedItem.latitude);
const longitude = Number(normalizedItem.longitude);
if (!Number.isFinite(latitude) || !Number.isFinite(longitude)) {
return null;
}
return {
latitude,
longitude,
name: normalizedItem.name || normalizedItem.title,
address: normalizedItem.address || normalizedItem.description,
};
};
export { getGuideMapNavigationOptions, normalizeGuideMapItem };

View File

@@ -27,8 +27,7 @@
@didSelectItem="handleToolCardClick" @didSelectOption="handleToolOptionClick" />
<DiscoveryAudioToolCard v-if="discoveryAudioToolData" :item="discoveryAudioToolData"
@didSelectItem="handleToolCardClick" />
<DiscoveryGuideMapToolCard v-if="discoveryGuideMapToolData" :item="discoveryGuideMapToolData"
@didSelectItem="handleToolCardClick" />
<DiscoveryGuideMapToolCard v-if="discoveryGuideMapToolData" :item="discoveryGuideMapToolData" />
<DiscoveryGoodsCard v-if="discoveryGoodsData.length > 0" :list="discoveryGoodsData" />
<QuickQuestions v-if="discoveryQuickQuestions.length > 0" :list="discoveryQuickQuestions"