sync: 同步最新呼籁官网代码到仓库

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
这个提交包含在:
刘涛
2026-03-22 21:57:35 +08:00
共同撰写人 Claude Sonnet 4.6
当前提交 a25f3a77ce
共修改 319 个文件,包含 46379 行新增和 0 行删除
+284
查看文件
@@ -0,0 +1,284 @@
<template>
<section class="section">
<div class="container">
<CommonSectionTitle :title="data.title" :subtitle="data.subtitle" />
<p class="compare-intro">{{ data.intro }}</p>
<!-- 对比表格 -->
<div class="compare-table">
<!-- 表头:三个目的地 -->
<div class="compare-header">
<div class="compare-label-col"></div>
<div
v-for="dest in data.destinations"
:key="dest.id"
class="compare-dest-col"
:class="{ 'compare-dest-col--highlight': dest.highlight }"
>
<h3 class="dest-name">{{ dest.name }}</h3>
<span class="dest-tag">{{ dest.tag }}</span>
</div>
</div>
<!-- 对比行 -->
<div v-for="dim in data.dimensions" :key="dim.label" class="compare-row">
<div class="compare-label-col">
<span class="dim-icon">{{ dim.icon }}</span>
<span class="dim-label">{{ dim.label }}</span>
</div>
<div
v-for="(val, i) in dim.values"
:key="i"
class="compare-value-col"
:class="{ 'compare-value-col--highlight': data.destinations[i]?.highlight }"
>
<span class="dim-label-mobile">{{ dim.icon }} {{ dim.label }}</span>
{{ val }}
</div>
</div>
</div>
<!-- 坦诚说明 -->
<div class="honest-block">
<h3 class="honest-title">{{ data.honestNote.title }}</h3>
<p class="honest-subtitle">{{ data.honestNote.subtitle }}</p>
<ul class="honest-list">
<li v-for="(item, i) in data.honestNote.items" :key="i">{{ item }}</li>
</ul>
</div>
<!-- 结语 -->
<div class="closing-block">
<h3 class="closing-title">{{ data.closing.title }}</h3>
<p class="closing-text">{{ data.closing.text }}</p>
</div>
<!-- 数据来源 -->
<p class="data-source">{{ data.dataSources }}</p>
</div>
</section>
</template>
<script setup>
import data from '~/data/destinations.json'
</script>
<style lang="less" scoped>
.compare-intro {
max-width: 800px;
margin: 0 auto @space-xl;
font-size: @font-size-base;
color: @color-text-secondary;
line-height: @line-height-loose;
text-align: center;
}
// 对比表格
.compare-table {
margin-bottom: @space-2xl;
border: 1px solid @color-border;
border-radius: @border-radius-lg;
overflow: hidden;
}
.compare-header {
display: none;
.respond-md({
display: grid;
grid-template-columns: 120px repeat(3, 1fr);
background: @color-bg-gray;
border-bottom: 1px solid @color-border;
});
}
.compare-label-col {
padding: @space-md @space-lg;
display: flex;
align-items: center;
gap: @space-sm;
font-weight: @font-weight-medium;
color: @color-text-muted;
font-size: @font-size-sm;
}
.compare-dest-col {
padding: @space-lg;
text-align: center;
&--highlight {
background: @color-primary-bg;
position: relative;
&::after {
content: '推荐';
position: absolute;
top: @space-xs;
right: @space-sm;
padding: 2px @space-sm;
font-size: 11px;
font-weight: @font-weight-bold;
color: #fff;
background: @color-primary;
border-radius: @border-radius-sm;
}
}
}
.dest-name {
font-size: @font-size-lg;
font-weight: @font-weight-bold;
color: @color-text-primary;
margin-bottom: @space-xs;
}
.dest-tag {
font-size: @font-size-xs;
color: @color-text-muted;
}
// 对比行
.compare-row {
display: flex;
flex-direction: column;
border-bottom: 1px solid @color-border;
&:last-child {
border-bottom: none;
}
.respond-md({
display: grid;
grid-template-columns: 120px repeat(3, 1fr);
flex-direction: row;
});
}
.compare-value-col {
padding: @space-md @space-lg;
font-size: @font-size-sm;
color: @color-text-secondary;
line-height: @line-height-base;
border-bottom: 1px solid fadeout(@color-border, 50%);
.respond-md({
border-bottom: none;
border-left: 1px solid fadeout(@color-border, 50%);
});
&:last-child {
border-bottom: none;
}
&--highlight {
background: fadeout(@color-primary-bg, 30%);
color: @color-text-primary;
font-weight: @font-weight-medium;
}
}
// 移动端:每个值前显示维度标签
.dim-label-mobile {
display: block;
font-size: @font-size-xs;
font-weight: @font-weight-bold;
color: @color-text-muted;
margin-bottom: @space-xs;
.respond-md({
display: none;
});
}
.dim-icon {
font-size: @font-size-base;
}
.dim-label {
font-size: @font-size-sm;
}
// 移动端隐藏左侧标签列
.compare-label-col {
display: none;
.respond-md({
display: flex;
});
}
// 坦诚说明
.honest-block {
max-width: 800px;
margin: 0 auto @space-xl;
padding: @space-xl;
background: #FFF7ED;
border-radius: @border-radius-lg;
border-left: 4px solid #F59E0B;
}
.honest-title {
font-size: @font-size-lg;
font-weight: @font-weight-bold;
color: #B45309;
margin-bottom: @space-xs;
}
.honest-subtitle {
font-size: @font-size-sm;
color: @color-text-muted;
margin-bottom: @space-md;
}
.honest-list {
display: flex;
flex-direction: column;
gap: @space-sm;
li {
font-size: @font-size-sm;
color: @color-text-secondary;
line-height: @line-height-base;
padding-left: @space-md;
position: relative;
&::before {
content: '•';
position: absolute;
left: 0;
color: #F59E0B;
font-weight: bold;
}
}
}
// 结语
.closing-block {
max-width: 800px;
margin: 0 auto @space-xl;
padding: @space-xl;
background: @color-primary-bg;
border-radius: @border-radius-lg;
border-left: 4px solid @color-primary;
}
.closing-title {
font-size: @font-size-lg;
font-weight: @font-weight-bold;
color: @color-primary;
margin-bottom: @space-md;
}
.closing-text {
font-size: @font-size-base;
color: @color-text-secondary;
line-height: @line-height-loose;
}
// 数据来源
.data-source {
text-align: center;
font-size: @font-size-xs;
color: @color-text-muted;
}
</style>
+129
查看文件
@@ -0,0 +1,129 @@
<template>
<section class="section section--warm">
<div class="container">
<CommonSectionTitle title="为什么选择呼籁" label="WHY HULAI" subtitle="不只是包车,是一套成熟的旅行服务体系" />
<div class="diff-grid">
<div
v-for="(item, index) in items"
:key="item.title"
class="diff-item"
>
<div
v-if="item.image"
class="diff-bg"
:style="{ backgroundImage: `url(${item.image})` }"
/>
<div class="diff-content">
<div class="diff-icon" v-html="icons[index % icons.length]" />
<h3 class="diff-title">{{ item.title }}</h3>
<p class="diff-desc">{{ item.description }}</p>
</div>
</div>
</div>
</div>
</section>
</template>
<script setup>
defineProps({
items: { type: Array, required: true },
})
// SVG icons for each differentiator
const icons = [
// 营地
'<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 21l9-18 9 18"/><path d="M12 3v18"/><path d="M3 21h18"/></svg>',
// 车队
'<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="1" y="3" width="15" height="13" rx="2"/><polygon points="16 8 20 8 23 11 23 16 16 16 16 8"/><circle cx="5.5" cy="18.5" r="2.5"/><circle cx="18.5" cy="18.5" r="2.5"/></svg>',
// 体验
'<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>',
// 旅拍
'<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M23 19a2 2 0 01-2 2H3a2 2 0 01-2-2V8a2 2 0 012-2h4l2-3h6l2 3h4a2 2 0 012 2z"/><circle cx="12" cy="13" r="4"/></svg>',
// 团队
'<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 00-3-3.87"/><path d="M16 3.13a4 4 0 010 7.75"/></svg>',
// 研学
'<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 014 4v14a3 3 0 00-3-3H2z"/><path d="M22 3h-6a4 4 0 00-4 4v14a3 3 0 013-3h7z"/></svg>',
]
</script>
<style lang="less" scoped>
.diff-grid {
display: grid;
grid-template-columns: 1fr;
gap: @space-lg;
.respond-md({
grid-template-columns: repeat(2, 1fr);
});
.respond-lg({
grid-template-columns: repeat(3, 1fr);
});
}
.diff-item {
position: relative;
border-radius: @border-radius-lg;
border: 1px solid @color-border;
overflow: hidden;
background: @color-bg-white;
transition: box-shadow 0.35s cubic-bezier(0.23, 1, 0.32, 1), transform 0.35s cubic-bezier(0.23, 1, 0.32, 1);
&:hover {
box-shadow: @shadow-md;
transform: translateY(-3px);
.diff-icon {
color: @color-primary;
background: @color-primary-bg;
}
.diff-bg {
opacity: 0.45;
transform: scale(1.05);
}
}
}
.diff-bg {
position: absolute;
inset: 0;
background-size: cover;
background-position: center;
opacity: 0.35;
filter: saturate(0.5) brightness(1.1);
transition: opacity 0.5s ease, transform 0.5s ease;
}
.diff-content {
position: relative;
z-index: 1;
padding: @space-xl @space-lg;
background: linear-gradient(150deg, rgba(255, 255, 255, 0.97) 30%, rgba(255, 255, 255, 0.85) 60%, rgba(255, 255, 255, 0.65) 100%);
}
.diff-icon {
display: flex;
align-items: center;
justify-content: center;
width: 56px;
height: 56px;
border-radius: @border-radius-lg;
background: @color-bg-gray;
color: @color-primary-light;
margin-bottom: @space-lg;
transition: color @transition-base, background @transition-base;
}
.diff-title {
font-size: @font-size-lg;
color: @color-text-primary;
margin-bottom: @space-sm;
}
.diff-desc {
font-size: @font-size-base;
color: @color-text-secondary;
line-height: @line-height-relaxed;
}
</style>
+206
查看文件
@@ -0,0 +1,206 @@
<template>
<section class="hero">
<div class="hero-bg">
<img
:src="images.hero.background"
alt="呼伦贝尔草原风光 莫日格勒河蜿蜒穿过辽阔草原"
class="hero-bg-img"
width="1600"
height="900"
fetchpriority="high"
/>
<div class="hero-overlay" />
</div>
<div class="container hero-inner">
<h1 class="hero-title">{{ seo.h1 }}</h1>
<p class="hero-emotional">{{ brand.slogan.emotional }}</p>
<p class="hero-functional">{{ brand.slogan.functional }}</p>
<div class="hero-actions">
<NuxtLink to="/products" class="hero-btn hero-btn--primary">
<span>查看产品</span>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<path d="M6 3l5 5-5 5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</NuxtLink>
<NuxtLink to="/faq" class="hero-btn hero-btn--outline">常见问答</NuxtLink>
</div>
</div>
<!-- 底部弧形裁切 -->
<div class="hero-curve">
<svg viewBox="0 0 1440 64" fill="none" preserveAspectRatio="none" aria-hidden="true">
<path d="M0 64h1440V32C1200 0 240 0 0 32v32z" fill="currentColor" />
</svg>
</div>
</section>
</template>
<script setup>
import brand from '~/data/brand.json'
import images from '~/data/images.json'
defineProps({
seo: { type: Object, required: true },
})
// 仅在首页 preload Hero 图片,避免全站加载
useHead({
link: [
{ rel: 'preload', href: images.hero.background, as: 'image' },
],
})
</script>
<style lang="less" scoped>
.hero {
position: relative;
overflow: hidden;
min-height: 480px;
display: flex;
align-items: center;
justify-content: center;
.respond-md({
min-height: 580px;
});
.respond-lg({
min-height: 640px;
});
}
.hero-bg {
position: absolute;
inset: 0;
z-index: 0;
}
.hero-bg-img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center 40%;
display: block;
}
// 更丰富的渐变遮罩
.hero-overlay {
position: absolute;
inset: 0;
background:
linear-gradient(180deg, rgba(26, 26, 46, 0.35) 0%, rgba(26, 26, 46, 0.15) 40%, rgba(26, 26, 46, 0.5) 100%),
linear-gradient(135deg, rgba(45, 106, 79, 0.3) 0%, transparent 60%);
}
.hero-inner {
position: relative;
z-index: 1;
padding-top: @space-4xl;
padding-bottom: 100px;
text-align: center;
max-width: 720px;
margin: 0 auto;
.respond-md({
padding-top: @space-4xl;
padding-bottom: 120px;
});
}
.hero-title {
color: #FFFFFF;
margin-bottom: @space-lg;
text-shadow: 0 2px 12px rgba(0, 0, 0, 0.2);
letter-spacing: 1px;
}
.hero-emotional {
font-size: @font-size-xl;
color: rgba(255, 255, 255, 0.95);
font-weight: @font-weight-medium;
margin-bottom: @space-sm;
text-shadow: 0 1px 6px rgba(0, 0, 0, 0.2);
.respond-md({
font-size: @font-size-2xl;
});
}
.hero-functional {
font-size: @font-size-md;
color: rgba(255, 255, 255, 0.75);
margin-bottom: @space-xl;
.respond-md({
font-size: @font-size-lg;
});
}
.hero-actions {
display: flex;
gap: @space-md;
flex-wrap: wrap;
justify-content: center;
}
.hero-btn {
display: inline-flex;
align-items: center;
gap: @space-sm;
padding: 14px 32px;
border-radius: @border-radius-full;
font-size: @font-size-base;
font-weight: @font-weight-medium;
text-decoration: none;
transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
.respond-md({
padding: 16px 40px;
font-size: @font-size-md;
});
&--primary {
background: #fff;
color: @color-primary;
border: 2px solid #fff;
&:hover {
background: rgba(255, 255, 255, 0.92);
transform: translateY(-2px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
color: @color-primary;
}
}
&--outline {
border: 2px solid rgba(255, 255, 255, 0.5);
color: #fff;
&:hover {
background: rgba(255, 255, 255, 0.15);
border-color: rgba(255, 255, 255, 0.8);
color: #fff;
transform: translateY(-2px);
}
}
}
// 底部弧形
.hero-curve {
position: absolute;
bottom: -1px;
left: 0;
right: 0;
z-index: 2;
line-height: 0;
color: @color-bg-gray;
svg {
width: 100%;
height: 40px;
.respond-md({
height: 64px;
});
}
}
</style>
+218
查看文件
@@ -0,0 +1,218 @@
<template>
<section class="section">
<div class="container">
<CommonSectionTitle title="旅行产品" label="PRODUCTS" subtitle="四季不同风景,总有一条线路适合你的家庭" />
<div class="product-grid">
<NuxtLink v-for="line in productLines" :key="line.id" :to="line.to" class="product-line-card">
<div class="line-img-wrap">
<img :src="line.image" :alt="line.name + ' ' + line.season + '旅行'" class="line-img" loading="lazy" width="400" height="240" />
<span class="line-season-tag" :class="`line-season-tag--${line.theme}`">{{ line.season }}</span>
</div>
<div class="line-body">
<div class="line-meta">
<span class="line-duration">{{ line.duration }}</span>
</div>
<h3 class="line-name">{{ line.name }}</h3>
<p class="line-desc">{{ line.description }}</p>
<ul class="line-highlights">
<li v-for="(h, i) in line.highlights" :key="i">{{ h }}</li>
</ul>
<span class="line-cta" :class="`line-cta--${line.theme}`">
了解详情
<svg width="14" height="14" viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="M6 3l5 5-5 5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</span>
</div>
</NuxtLink>
</div>
</div>
</section>
</template>
<script setup>
const productLines = [
{
id: 'summer',
name: '额吉的故乡',
season: '夏季',
theme: 'summer',
duration: '4-7天 · V9系列',
to: '/products',
image: '/images/seasons/summer-hero.jpg',
description: '呼伦贝尔草原家庭定制游,一家一单一车,6个版本适配不同假期',
highlights: ['莫日格勒河草原穿越', '专业骑马体验', '呼籁自有营地住宿'],
},
{
id: 'autumn',
name: '游牧的森林',
season: '秋季',
theme: 'autumn',
duration: '4-7天 · V3系列',
to: '/products/autumn',
image: '/images/seasons/autumn-forest.jpg',
description: '金秋草原+阿尔山/大兴安岭,南北两线专属私家团',
highlights: ['大兴安岭金秋林海', '阿尔山火山天池', '扎罗木得断崖秘境'],
},
{
id: 'winter',
name: '嗨冰雪',
season: '冬季',
theme: 'winter',
duration: '5-7天 · V3系列',
to: '/products/winter',
image: '/images/seasons/winter-hero.jpg',
description: '呼伦贝尔冬季定制游,南北两线,冰雪那达慕+驯鹿部落',
highlights: ['冰雪那达慕体验', '雪地狼群投喂', '大雪原日出日落'],
},
{
id: 'camp',
name: '小蒙马亲子营',
season: '夏+冬',
theme: 'camp',
duration: '夏6天 / 冬7天',
to: '/summer-camp',
image: '/images/summer-camp/grassland-group.jpg',
description: '亲子营模式,每期8组家庭结伴同行,孩子有伙伴大人能放松',
highlights: ['专业研学领队带队', '随团摄影师全程跟拍', '草原写生+非遗研学'],
},
]
</script>
<style lang="less" scoped>
.product-grid {
display: grid;
grid-template-columns: 1fr;
gap: @space-lg;
.respond-md({
grid-template-columns: repeat(2, 1fr);
});
.respond-lg({
grid-template-columns: repeat(4, 1fr);
});
}
.product-line-card {
display: flex;
flex-direction: column;
background: @color-bg-white;
border-radius: @border-radius-lg;
overflow: hidden;
text-decoration: none;
box-shadow: @shadow-card;
transition: box-shadow 0.35s cubic-bezier(0.23, 1, 0.32, 1), transform 0.35s cubic-bezier(0.23, 1, 0.32, 1);
&:hover {
box-shadow: @shadow-lg;
transform: translateY(-6px);
.line-img {
transform: scale(1.05);
}
}
}
.line-img-wrap {
position: relative;
overflow: hidden;
aspect-ratio: 5 / 3;
}
.line-img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.5s cubic-bezier(0.23, 1, 0.32, 1);
}
.line-season-tag {
position: absolute;
top: @space-md;
left: @space-md;
padding: @space-xs @space-sm;
font-size: @font-size-xs;
font-weight: @font-weight-bold;
border-radius: @border-radius-sm;
backdrop-filter: blur(4px);
&--summer { color: #fff; background: rgba(45, 106, 79, 0.85); }
&--autumn { color: #fff; background: rgba(217, 119, 6, 0.85); }
&--winter { color: #fff; background: rgba(59, 130, 246, 0.85); }
&--camp { color: #fff; background: rgba(139, 92, 246, 0.85); }
}
.line-body {
display: flex;
flex-direction: column;
padding: @space-lg;
flex: 1;
}
.line-meta {
margin-bottom: @space-sm;
}
.line-duration {
font-size: @font-size-xs;
color: @color-text-muted;
}
.line-name {
font-size: @font-size-xl;
font-weight: @font-weight-bold;
color: @color-text-primary;
margin-bottom: @space-sm;
}
.line-desc {
font-size: @font-size-sm;
color: @color-text-secondary;
line-height: @line-height-base;
margin-bottom: @space-md;
}
.line-highlights {
display: flex;
flex-direction: column;
gap: @space-xs;
margin-bottom: @space-lg;
flex: 1;
li {
font-size: @font-size-sm;
color: @color-text-secondary;
padding-left: @space-md;
position: relative;
&::before {
content: '';
position: absolute;
left: 2px;
top: 8px;
width: 5px;
height: 5px;
border-radius: 50%;
background: @color-primary-lighter;
}
}
}
.line-cta {
display: inline-flex;
align-items: center;
gap: @space-xs;
font-size: @font-size-sm;
font-weight: @font-weight-medium;
margin-top: auto;
transition: gap @transition-fast;
.product-line-card:hover & {
gap: @space-sm;
}
&--summer { color: @color-primary; }
&--autumn { color: #D97706; }
&--winter { color: #3B82F6; }
&--camp { color: #8B5CF6; }
}
</style>
+129
查看文件
@@ -0,0 +1,129 @@
<template>
<section class="section section--gray">
<div class="container">
<CommonSectionTitle title="客户怎么说" label="REVIEWS" subtitle="来自真实家庭的旅行评价" />
<div class="review-grid">
<div v-for="r in reviews" :key="r.id" class="review-card">
<div class="review-quote-mark">"</div>
<blockquote class="review-text">{{ r.content }}</blockquote>
<div class="review-footer">
<div class="review-avatar">{{ r.nickname.charAt(0) }}</div>
<div class="review-info">
<span class="review-name">{{ r.nickname }}</span>
<span class="review-date">{{ r.travelDate }}</span>
</div>
</div>
<p class="review-product">{{ r.productVersion }}</p>
</div>
</div>
<div class="review-more">
<CommonInternalLink to="/reviews" text="查看更多客户评价" />
</div>
</div>
</section>
</template>
<script setup>
defineProps({
reviews: { type: Array, required: true },
})
</script>
<style lang="less" scoped>
.review-grid {
display: grid;
grid-template-columns: 1fr;
gap: @space-lg;
.respond-md({
grid-template-columns: repeat(2, 1fr);
});
.respond-lg({
grid-template-columns: repeat(3, 1fr);
});
}
.review-card {
background: @color-bg-white;
border-radius: @border-radius-lg;
padding: @space-xl;
border: 1px solid @color-border;
border-left: 3px solid @color-primary-lighter;
position: relative;
transition: box-shadow 0.35s cubic-bezier(0.23, 1, 0.32, 1), transform 0.35s cubic-bezier(0.23, 1, 0.32, 1);
&:hover {
box-shadow: @shadow-md;
transform: translateY(-3px);
border-left-color: @color-primary;
}
}
.review-quote-mark {
font-family: Georgia, 'Times New Roman', serif;
font-size: 64px;
line-height: 1;
color: @color-primary-lighter;
margin-bottom: -@space-md;
user-select: none;
}
.review-text {
font-size: @font-size-base;
color: @color-text-secondary;
line-height: @line-height-relaxed;
margin-bottom: @space-lg;
.text-clamp(4);
}
.review-footer {
display: flex;
align-items: center;
gap: @space-md;
}
.review-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
background: linear-gradient(135deg, @color-primary-bg, @color-primary-lighter);
color: @color-primary;
display: flex;
align-items: center;
justify-content: center;
font-size: @font-size-sm;
font-weight: @font-weight-bold;
flex-shrink: 0;
}
.review-info {
display: flex;
flex-direction: column;
gap: 2px;
}
.review-name {
font-size: @font-size-sm;
color: @color-text-primary;
font-weight: @font-weight-medium;
}
.review-date {
font-size: @font-size-xs;
color: @color-text-muted;
}
.review-product {
font-size: @font-size-xs;
color: @color-text-muted;
margin-top: @space-sm;
padding-top: @space-sm;
border-top: 1px solid @color-divider;
}
.review-more {
text-align: center;
margin-top: @space-2xl;
}
</style>
+45
查看文件
@@ -0,0 +1,45 @@
<template>
<section class="trust-section">
<div class="container">
<div class="trust-grid">
<CommonTrustBadge
v-for="stat in stats"
:key="stat.label"
:value="stat.value"
:unit="stat.unit"
:label="stat.label"
:attribution="stat.attribution"
dark
/>
</div>
</div>
</section>
</template>
<script setup>
defineProps({
stats: { type: Array, required: true },
})
</script>
<style lang="less" scoped>
.trust-section {
background: linear-gradient(135deg, @color-primary-dark 0%, @color-primary 100%);
padding: @space-xl 0;
.respond-md({
padding: @space-2xl 0;
});
}
.trust-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: @space-md;
.respond-md({
grid-template-columns: repeat(4, 1fr);
gap: @space-xl;
});
}
</style>