Files
YGChatCS/src/pages/DuohuaDiscovery/detail.vue
T
2026-09-05 12:28:49 +08:00

192 lines
6.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="flex h-screen min-w-0 flex-col overflow-hidden bg-[#f4f6f8]">
<TopNavBar
:title="item?.name || ''"
:subtitle="sectionTitle"
title-align="left"
background="#ffffff"
/>
<scroll-view v-if="item" class="min-h-0 flex-1" scroll-y>
<view class="h-[240px] overflow-hidden bg-[#dfe8e5]">
<DuohuaMediaSwiper :media-list="imageList" />
</view>
<view class="bg-white px-[16px] pb-[18px] pt-[16px]">
<view class="flex items-center gap-[8px]">
<text class="min-w-0 text-[22px] font-bold leading-[30px] text-[#172033]">
{{ item.name }}
</text>
<text
v-if="item.grade"
class="shrink-0 rounded-[5px] bg-[#e9f7f1] px-[7px] py-[3px] text-[11px] font-semibold text-[#149474]"
>
{{ item.grade }}
</text>
</view>
<text
v-if="item.name_en"
class="mt-[3px] block text-[12px] leading-[18px] text-[#808997]"
>
{{ item.name_en }}
</text>
<view v-if="displayAddress" class="mt-[10px] flex items-center">
<uni-icons class="shrink-0" type="location" size="15" color="#808997" />
<text class="ml-[4px] min-w-0 flex-1 text-[12px] leading-[19px] text-[#6f7884]">
{{ displayAddress }}
</text>
</view>
<view v-if="contactText || canOpenLocation" class="mt-[14px] flex items-center gap-[10px]">
<view v-if="contactText" class="flex min-w-0 items-center gap-[8px]">
<text class="min-w-0 text-[13px] font-medium text-[#4f5966]">
{{ contactText }}
</text>
<view
class="flex h-[36px] shrink-0 items-center rounded-full bg-[#ecf8f2] px-[14px]"
@click="makePhoneCall"
>
<uni-icons type="phone" size="15" color="#149474" />
<text class="ml-[5px] text-[12px] font-medium text-[#149474]">拨打电话</text>
</view>
</view>
<view
v-if="canOpenLocation"
class="flex h-[36px] items-center rounded-full bg-[#ecf8f2] px-[14px]"
@click="openLocation"
>
<uni-icons type="navigate" size="15" color="#149474" />
<text class="ml-[5px] text-[12px] font-medium text-[#149474]">地图导航</text>
</view>
</view>
<view v-if="item.tags?.length" class="mt-[14px] flex flex-wrap gap-[6px]">
<text
v-for="tag in item.tags"
:key="tag"
class="rounded-[4px] bg-[#e8f2ff] px-[6px] py-[3px] text-[10px] text-[#3474c7]"
>
{{ tag }}
</text>
</view>
</view>
<view v-if="item.description" class="mx-[12px] mt-[12px] rounded-[16px] bg-white p-[16px]">
<text class="block text-[16px] font-semibold text-[#202733]">介绍</text>
<text class="mt-[10px] block text-[14px] leading-[23px] text-[#5f6875]">
{{ item.description }}
</text>
</view>
<view
v-for="section in arraySections"
:key="section.title"
class="mx-[12px] mt-[12px] rounded-[16px] bg-white p-[16px]"
>
<text class="block text-[16px] font-semibold text-[#202733]">
{{ section.title }}
</text>
<view class="mt-[9px] flex flex-wrap gap-[7px]">
<text
v-for="(value, index) in section.values"
:key="`${section.title}-${index}`"
class="rounded-[6px] bg-[#f2f6f5] px-[9px] py-[6px] text-[12px] leading-[18px] text-[#52605c]"
>
{{ formatValue(value) }}
</text>
</view>
</view>
<view class="h-[24px]" />
</scroll-view>
<view v-else class="flex min-h-0 flex-1 items-center justify-center">
<text class="text-[14px] text-[#808997]">未找到对应内容</text>
</view>
</view>
</template>
<script setup>
import { computed, ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import TopNavBar from "@/components/TopNavBar/index.vue";
import DuohuaMediaSwiper from "./components/DuohuaMediaSwiper.vue";
import {
getItem,
getSectionForCollection,
normalizeImageList,
} from "./data";
const item = ref(null);
const collection = ref("");
const sectionTitle = computed(
() => getSectionForCollection(collection.value)?.title || ""
);
const imageList = computed(() => normalizeImageList(item.value));
const contactText = computed(
() => item.value?.contact?.normalized || item.value?.contact?.raw || ""
);
const displayAddress = computed(() => {
const address = item.value?.address;
if (!address) return "";
return address.normalized || "";
});
const canOpenLocation = computed(() => {
const latitudeValue = item.value?.address?.latitude;
const longitudeValue = item.value?.address?.longitude;
if (
latitudeValue === null ||
latitudeValue === undefined ||
latitudeValue === "" ||
longitudeValue === null ||
longitudeValue === undefined ||
longitudeValue === ""
) {
return false;
}
const latitude = Number(latitudeValue);
const longitude = Number(longitudeValue);
return Number.isFinite(latitude) && Number.isFinite(longitude);
});
const arraySections = computed(() => {
if (!item.value) return [];
return [
{ title: "房型", values: item.value.room_types },
{ title: "设施服务", values: item.value.facilities },
{ title: "主要食材", values: item.value.ingredients },
{ title: "烹饪方式", values: item.value.cooking_methods },
{ title: "营养信息", values: item.value.nutrition_facts },
].filter((section) => Array.isArray(section.values) && section.values.length);
});
const formatValue = (value) => {
if (value && typeof value === "object") {
return Object.entries(value)
.filter(([, itemValue]) => itemValue !== "" && itemValue !== null)
.map(([key, itemValue]) => `${key}:${itemValue}`)
.join(";");
}
return String(value ?? "");
};
const makePhoneCall = () => {
if (!contactText.value) return;
uni.makePhoneCall({ phoneNumber: contactText.value });
};
const openLocation = () => {
if (!canOpenLocation.value) return;
uni.openLocation({
latitude: Number(item.value.address.latitude),
longitude: Number(item.value.address.longitude),
name: item.value.name,
address: item.value.address.raw || item.value.address.normalized || "",
});
};
onLoad((options) => {
collection.value = options?.collection || "";
item.value = getItem(collection.value, options?.id || "");
});
</script>