Initial commit: gmTouringMiniApp project

This commit is contained in:
周瑞哲
2026-07-30 16:04:34 +08:00
commit ebcae02d35
201 changed files with 49545 additions and 0 deletions
+195
View File
@@ -0,0 +1,195 @@
<script setup lang="ts">
import type { PoiResolved } from '@/domain/poi'
import PoiImage from '@/components/poi/PoiImage.vue'
import PoiTagList from '@/components/poi/PoiTagList.vue'
interface Props {
poi: PoiResolved
index?: number
timeText?: string
reason?: string
activity?: string
}
withDefaults(defineProps<Props>(), {
index: 0,
timeText: '',
reason: '',
activity: '',
})
const emit = defineEmits<{
detail: [poiId: string]
map: [poiId: string]
}>()
</script>
<template>
<view class="travel-poi-card">
<view class="travel-poi-card__media">
<PoiImage
:src="poi.coverImage.url"
:alt="poi.coverImage.alt"
width="176rpx"
height="160rpx"
radius="16rpx"
/>
<text v-if="index > 0" class="travel-poi-card__index">{{ index }}</text>
</view>
<view class="travel-poi-card__content">
<view class="travel-poi-card__heading">
<text class="travel-poi-card__name">{{ poi.name }}</text>
<text class="travel-poi-card__category">{{ poi.category.name }}</text>
</view>
<text v-if="timeText" class="travel-poi-card__time">{{ timeText }}</text>
<text class="travel-poi-card__activity">{{ activity || poi.summary }}</text>
<PoiTagList class="travel-poi-card__tags" :tags="poi.tags" :limit="2" compact />
<view v-if="reason" class="travel-poi-card__reason">
<text class="travel-poi-card__spark">推荐</text>
<text>{{ reason }}</text>
</view>
<view class="travel-poi-card__actions">
<button @click="emit('detail', poi.id)">查看详情</button>
<button class="travel-poi-card__map" @click="emit('map', poi.id)">地图定位</button>
</view>
</view>
</view>
</template>
<style scoped lang="scss">
.travel-poi-card {
display: flex;
gap: 20rpx;
padding: 24rpx;
background: #fff;
border: 1rpx solid #dce6e1;
border-radius: 22rpx;
box-shadow: 0 10rpx 28rpx rgb(20 78 53 / 6%);
}
.travel-poi-card__media {
position: relative;
flex: none;
}
.travel-poi-card__index {
position: absolute;
top: 10rpx;
left: 10rpx;
display: flex;
align-items: center;
justify-content: center;
width: 46rpx;
height: 46rpx;
font-size: 22rpx;
font-weight: 700;
line-height: 46rpx;
color: #fff;
background: #167a5b;
border: 3rpx solid #fff;
border-radius: 50%;
}
.travel-poi-card__content {
display: flex;
flex: 1;
flex-direction: column;
min-width: 0;
}
.travel-poi-card__heading {
display: flex;
gap: 12rpx;
align-items: flex-start;
justify-content: space-between;
}
.travel-poi-card__name {
flex: 1;
font-size: 29rpx;
font-weight: 700;
line-height: 40rpx;
color: #18201d;
}
.travel-poi-card__category {
flex: none;
padding: 4rpx 10rpx;
font-size: 18rpx;
line-height: 28rpx;
color: #167a5b;
background: #eaf5f0;
border-radius: 8rpx;
}
.travel-poi-card__time {
margin-top: 4rpx;
font-size: 21rpx;
font-weight: 600;
line-height: 32rpx;
color: #167a5b;
}
.travel-poi-card__activity {
display: -webkit-box;
margin-top: 8rpx;
overflow: hidden;
font-size: 22rpx;
line-height: 33rpx;
color: #637069;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.travel-poi-card__tags {
margin-top: 10rpx;
}
.travel-poi-card__reason {
display: flex;
gap: 8rpx;
padding: 10rpx 12rpx;
margin-top: 12rpx;
font-size: 19rpx;
line-height: 29rpx;
color: #436154;
background: #f0f8f4;
border-radius: 10rpx;
}
.travel-poi-card__spark {
flex: none;
font-size: 17rpx;
font-weight: 800;
color: #078e55;
}
.travel-poi-card__actions {
display: flex;
gap: 12rpx;
margin-top: 14rpx;
}
.travel-poi-card__actions button {
width: auto;
height: 54rpx;
padding: 0 18rpx;
margin: 0;
font-size: 20rpx;
line-height: 54rpx;
color: #435149;
background: #f1f4f2;
border: 0;
border-radius: 27rpx;
}
.travel-poi-card__actions button::after {
border: 0;
}
.travel-poi-card__actions .travel-poi-card__map {
color: #fff;
background: #167a5b;
}
</style>
+1
View File
@@ -0,0 +1 @@
export { default as TravelPoiCard } from './TravelPoiCard.vue'