feat: 官网代码全量更新

覆盖最新版本代码,包含:
- 新增品牌百科、公司百科页面及CMS管理
- 新增微信引导组件(WechatCTA)
- 新增品牌/公司图片资源
- 全站组件/页面/数据/样式更新

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
这个提交包含在:
wx
2026-04-16 13:21:11 +08:00
共同撰写人 Claude Opus 4.6
父节点 bd0518eda6
当前提交 ac90205395
共修改 113 个文件,包含 4463 行新增和 405 行删除
+5 -3
查看文件
@@ -6,7 +6,7 @@
<div class="story-photo">
<div class="story-photo-card">
<img
:src="images.brandStory.photo"
:src="images?.brandStory?.photo"
alt="呼籁旅行创始人在呼伦贝尔草原"
width="600"
height="800"
@@ -32,8 +32,10 @@
</template>
<script setup>
import images from '~/data/images.json'
defineProps({ story: { type: Object, required: true } })
defineProps({
story: { type: Object, required: true },
images: { type: Object, default: () => ({}) },
})
</script>
<style lang="less" scoped>
+6 -4
查看文件
@@ -6,7 +6,7 @@
<div class="mascot-hero">
<div class="mascot-image">
<img
:src="images.mascot.front"
:src="images?.mascot?.front"
alt="籁小咩 - 呼籁旅行品牌IP吉祥物,一只可爱的小羊形象"
width="280"
height="380"
@@ -28,7 +28,7 @@
<!-- 草原场景 -->
<div class="mascot-banner">
<img
:src="images.mascot.banner"
:src="images?.mascot?.banner"
alt="籁小咩在呼伦贝尔草原上向你招手"
width="800"
height="300"
@@ -40,7 +40,7 @@
<div class="mascot-sticker">
<div class="mascot-sticker-qr">
<img
:src="images.mascot.stickerQr"
:src="images?.mascot?.stickerQr"
alt="籁小咩微信表情包二维码"
width="160"
height="160"
@@ -58,7 +58,9 @@
</template>
<script setup>
import images from '~/data/images.json'
defineProps({
images: { type: Object, default: () => ({}) },
})
</script>
<style lang="less" scoped>
+8 -6
查看文件
@@ -11,7 +11,7 @@
<div class="team-photo-card">
<div class="team-photo-wrap team-photo-wrap--survey">
<img
:src="images.team.guideGroup"
:src="images?.team?.guideGroup"
alt="2024呼籁文旅车队踩线全体领队合影"
loading="lazy"
/>
@@ -24,7 +24,7 @@
<div class="team-photo-card">
<div class="team-photo-wrap team-photo-wrap--survey">
<img
:src="images.team.routeSurvey"
:src="images?.team?.routeSurvey"
alt="2025秋呼籁文旅游牧的森林车队踩线全体领队合影"
loading="lazy"
/>
@@ -41,7 +41,7 @@
<div class="team-photo-card">
<div class="team-photo-wrap team-photo-wrap--misc">
<img
:src="images.team.guideTraining"
:src="images?.team?.guideTraining"
alt="呼籁文旅2026年司导线下培训"
loading="lazy"
/>
@@ -54,7 +54,7 @@
<div class="team-photo-card">
<div class="team-photo-wrap team-photo-wrap--misc">
<img
:src="images.team.ranchStore"
:src="images?.team?.ranchStore"
alt="呼籁牧场线下店开业团队合影"
loading="lazy"
/>
@@ -71,8 +71,10 @@
</template>
<script setup>
import images from '~/data/images.json'
defineProps({ team: { type: Object, required: true } })
defineProps({
team: { type: Object, required: true },
images: { type: Object, default: () => ({}) },
})
</script>
<style lang="less" scoped>
+5 -3
查看文件
@@ -7,7 +7,7 @@
<!-- 顶部:品牌主页截图作为横幅 -->
<div class="xhs-banner">
<img
:src="images.xiaohongshu.storefront"
:src="images?.xiaohongshu?.storefront"
alt="呼籁旅行小红书品牌主页 - Mr.小雷-呼籁旅行 50万家庭青睐的草原旅行品牌"
width="800"
height="300"
@@ -56,8 +56,10 @@
</template>
<script setup>
import images from '~/data/images.json'
defineProps({ xhs: { type: Object, required: true } })
defineProps({
xhs: { type: Object, required: true },
images: { type: Object, default: () => ({}) },
})
</script>
<style lang="less" scoped>
+138
查看文件
@@ -0,0 +1,138 @@
<template>
<section class="wechat-cta" :class="`wechat-cta--${bg}`">
<div class="container">
<div class="wechat-cta-inner">
<div class="wechat-cta-text">
<h2 class="wechat-cta-title">{{ title }}</h2>
<p class="wechat-cta-desc">{{ description }}</p>
<div v-if="links && links.length" class="wechat-cta-links">
<NuxtLink
v-for="link in links"
:key="link.to"
:to="link.to"
class="wechat-cta-link"
>
{{ link.text }} →
</NuxtLink>
</div>
</div>
<div class="wechat-cta-qr">
<img src="/images/contact/qrcode-wechat.jpg" alt="定制师微信二维码" class="wechat-cta-qrimg" />
<span class="wechat-cta-qrlabel">扫码添加定制师微信</span>
</div>
</div>
</div>
</section>
</template>
<script setup>
defineProps({
title: { type: String, default: '想聊聊行程?扫码找定制师' },
description: { type: String, default: '添加微信,定制师根据你的家庭情况和假期安排,1对1推荐合适的行程方案。' },
links: { type: Array, default: () => [] },
bg: { type: String, default: 'light' },
})
</script>
<style lang="less" scoped>
.wechat-cta {
.section-padding();
}
.wechat-cta--light {
background: @color-bg-gray;
}
.wechat-cta--white {
background: #fff;
}
.wechat-cta--green {
background: linear-gradient(135deg, @color-primary-dark 0%, @color-primary 100%);
.wechat-cta-title {
color: #fff;
&::after { display: none; }
}
.wechat-cta-desc { color: rgba(255, 255, 255, 0.85); }
.wechat-cta-link { color: rgba(255, 255, 255, 0.9); &:hover { color: #fff; } }
.wechat-cta-qrlabel { color: rgba(255, 255, 255, 0.8); }
}
.wechat-cta-inner {
display: flex;
align-items: center;
justify-content: center;
gap: @space-2xl;
max-width: 720px;
margin: 0 auto;
@media (max-width: 640px) {
flex-direction: column;
text-align: center;
gap: @space-lg;
}
}
.wechat-cta-text {
flex: 1;
}
.wechat-cta-title {
font-size: @font-size-xl;
font-weight: @font-weight-bold;
color: @color-text-primary;
margin-bottom: @space-sm;
&::after { display: none; }
}
.wechat-cta-desc {
font-size: @font-size-base;
line-height: @line-height-relaxed;
color: @color-text-secondary;
}
.wechat-cta-links {
margin-top: @space-md;
display: flex;
gap: @space-md;
@media (max-width: 640px) {
justify-content: center;
}
}
.wechat-cta-link {
font-size: @font-size-sm;
color: @color-primary;
text-decoration: none;
font-weight: @font-weight-medium;
&:hover {
color: @color-primary-dark;
}
}
.wechat-cta-qr {
flex-shrink: 0;
display: flex;
flex-direction: column;
align-items: center;
gap: @space-xs;
}
.wechat-cta-qrimg {
width: 140px;
height: 140px;
border-radius: @border-radius-sm;
background: #fff;
object-fit: contain;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
}
.wechat-cta-qrlabel {
font-size: @font-size-xs;
color: @color-text-muted;
}
</style>
+25 -12
查看文件
@@ -12,8 +12,8 @@
<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-label">{{ seo.h1 }}</p>
<h1 class="hero-emotional">{{ brand.slogan.emotional }}</h1>
<p class="hero-functional">{{ brand.slogan.functional }}</p>
<div class="hero-actions">
<NuxtLink to="/products" class="hero-btn hero-btn--primary">
@@ -106,22 +106,35 @@ useHead({
});
}
.hero-title {
color: #FFFFFF;
margin-bottom: @space-lg;
text-shadow: 0 2px 12px rgba(0, 0, 0, 0.2);
letter-spacing: 1px;
.hero-label {
font-size: @font-size-sm;
color: rgba(255, 255, 255, 0.7);
letter-spacing: 3px;
text-transform: uppercase;
margin-bottom: @space-md;
text-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
.respond-md({
font-size: @font-size-base;
letter-spacing: 4px;
});
}
.hero-emotional {
font-size: @font-size-xl;
color: rgba(255, 255, 255, 0.95);
font-weight: @font-weight-medium;
font-size: @font-size-2xl;
color: #FFFFFF;
font-weight: @font-weight-bold;
margin-bottom: @space-sm;
text-shadow: 0 1px 6px rgba(0, 0, 0, 0.2);
text-shadow: 0 2px 12px rgba(0, 0, 0, 0.2);
letter-spacing: 2px;
.respond-md({
font-size: @font-size-2xl;
font-size: @font-size-3xl;
letter-spacing: 3px;
});
.respond-lg({
font-size: @font-size-display;
});
}
+3 -3
查看文件
@@ -45,7 +45,7 @@ const productLines = [
duration: '4-7天 · V9系列',
to: '/products',
image: '/images/seasons/summer-hero.jpg',
description: '呼伦贝尔草原家庭定制游,一家一单一车,6个版本适配不同假期',
description: '呼伦贝尔草原家庭定制游,专车专属独立成团,6个版本适配不同假期',
highlights: ['莫日格勒河草原穿越', '专业骑马体验', '呼籁自有营地住宿'],
},
{
@@ -72,10 +72,10 @@ const productLines = [
},
{
id: 'summer-camp',
name: '小蒙马夏令营',
name: '小蒙马亲子游学营',
season: '夏季',
theme: 'camp',
duration: '7天6晚',
duration: '6天5晚',
to: '/summer-camp',
image: '/images/seasons/summer-river.jpg',
description: '亲子营模式,每期8组家庭结伴同行,孩子有伙伴大人能放松',
+28
查看文件
@@ -32,6 +32,15 @@
{{ h }}
</li>
</ul>
<!-- 价格区间 -->
<div v-if="product.pricing" class="product-price" itemprop="offers" itemscope itemtype="https://schema.org/AggregateOffer">
<meta itemprop="priceCurrency" content="CNY" />
<meta itemprop="lowPrice" :content="String(product.pricing.startPrice)" />
<meta itemprop="highPrice" :content="String(product.pricing.highPeakPrice || product.pricing.peakPrice)" />
<span class="product-price__from">{{ product.pricing.startPrice }}元起</span>
<span class="product-price__note">/人 · 价格因日期和住宿等级浮动</span>
</div>
</div>
<!-- 底部 CTA -->
@@ -202,6 +211,25 @@ const shortName = computed(() => {
margin-top: 2px;
}
// 价格区间
.product-price {
margin-top: @space-md;
padding-top: @space-md;
border-top: 1px dashed @color-border;
&__from {
font-size: @font-size-lg;
font-weight: @font-weight-bold;
color: @color-accent;
}
&__note {
font-size: @font-size-xs;
color: @color-text-muted;
margin-left: @space-xs;
}
}
// 底部 CTA
.product-cta {
display: block;
+1 -1
查看文件
@@ -34,7 +34,7 @@ const guideGroups = computed(() => [
])
function getProductName(id) {
if (id === 'summer-camp') return '小蒙马夏令营'
if (id === 'summer-camp') return '小蒙马亲子游学营'
const v = props.versions.find(v => v.id === id)
return v ? v.name : id
}
+1 -1
查看文件
@@ -8,7 +8,7 @@
<div class="camp-mascot">
<img
:src="images.mascot.xiaomengma"
alt="小蒙马 - 小蒙马夏令营团宠,一只可爱的蒙古小马形象"
alt="小蒙马 - 小蒙马亲子游学营团宠,一只可爱的蒙古小马形象"
width="200"
height="200"
loading="lazy"