Files
inkreach-uni/pages/index/index.vue
T

227 lines
6.3 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="index-page">
<!-- Hero 首屏 -->
<HeroBanner :stats="trustStats" />
<!-- 4步流程active 由页面统一管理跟下面 PlatformFeatures 共用同一个定时器 -->
<StepsFlow
:steps="stepList"
:active="currentStep"
@change="onStepChange"
/>
<!-- 全球POD货盘 -->
<PodCatalog
:countries="podCountries"
:products="podProducts"
@countryChange="onPodCountryChange"
@moreTap="onGoProducts"
@productTap="onGoDetail"
/>
<!-- 平台功能 + 集成平台active 由页面统一管理跟上面 StepsFlow 共用同一个定时器 -->
<PlatformFeatures
:features="featureList"
:active="currentFeat"
@change="onFeatChange"
/>
<!-- 为什么选择 -->
<WhyChoose :reasons="reasonList" />
<!-- 公司简介 + 底部CTA -->
<CompanyIntro :abilities="companyFeatures" />
</view>
</template>
<script>
import HeroBanner from './components/HeroBanner.vue'
import StepsFlow from './components/StepsFlow.vue'
import PodCatalog from './components/PodCatalog.vue'
import PlatformFeatures from './components/PlatformFeatures.vue'
import WhyChoose from './components/WhyChoose.vue'
import CompanyIntro from './components/CompanyIntro.vue'
import { getCountries, getGoods } from '@/api/public.js'
import { buildUrl } from '@/api/request.js'
import { truncateProductTitle } from '@/utils/product.js'
import {
trustStats,
stepList,
featureList,
reasonList,
companyFeatures
} from './mock.js'
// 统一轮播间隔:3 秒推进一次,同时驱动 StepsFlow + PlatformFeatures
const AUTO_PLAY_INTERVAL = 3000
export default {
components: {
HeroBanner,
StepsFlow,
PodCatalog,
PlatformFeatures,
WhyChoose,
CompanyIntro
},
data() {
return {
trustStats,
stepList,
featureList,
reasonList,
companyFeatures,
podCountries: [],
podProducts: [],
// 两个区块共用一个定时器,但各自独立轮播(互不干扰)
currentStep: 0,
currentFeat: 0,
_autoPlayTimer: null // 唯一一个定时器
}
},
async onLoad() {
this.loadGlobalFont()
await this.loadPodCountries()
await this.loadPodProducts('')
},
onShow() {
// 页面显示 → 启动轮播
this.startAutoPlay()
},
onHide() {
// 页面隐藏 → 回收定时器(切 Tab、跳详情、退后台等)
this.stopAutoPlay()
},
onUnload() {
this.stopAutoPlay()
},
methods: {
// 全局加载苹方子集字体(常用3500字+数字英文,约700KB)
// 必须在页面加载后调用(App onLaunch 里页面未创建会报 not font page
// family 用自定义名 PingFangSC(避免与系统苹方重名),已加到 app.css 字体栈首位;global: true 全局生效
// 加载失败自动回退系统字体,不影响使用
loadGlobalFont() {
uni.loadFontFace({
global: true,
family: 'CusPingFangSC',
source: `url("${buildUrl('/assets/miniprogram/fonts/PingFang-Regular.subset.ttf')}")`,
// source: 'url("https://raw.githubusercontent.com/googlefonts/zcool-kuaile/main/fonts/ttf/ZCOOLKuaiLe-Regular.ttf")' , // ✅ 正确
success: () => console.log('字体加载成功'),
fail: err => console.warn('字体加载失败,回退系统字体', err)
})
},
async loadPodCountries() {
try {
const res = await getCountries()
const data = (res.data && res.data.data) || []
const countries = [{ id: '', name: '全部' }]
data.forEach((c) => {
countries.push({ id: c.id, name: c.countryName })
})
this.podCountries = countries
} catch (err) {
console.error('[loadPodCountries Error]', err)
}
},
async loadPodProducts(countryId) {
try {
const params = { page: 1, pageSize: 4 }
if (countryId) {
params.countryId = countryId
}
const res = await getGoods(params)
const data = (res.data && res.data.data) || { items: [] }
const items = (data.items || []).slice(0, 4)
this.podProducts = items.map((item) => ({
id: item.goodId,
name: truncateProductTitle(item.goodName),
image: item.image
}))
} catch (err) {
console.error('[loadPodProducts Error]', err)
this.podProducts = []
}
},
async onPodCountryChange(id) {
await this.loadPodProducts(id)
},
onGoProducts() {
uni.switchTab({
url: '/pages/products/products'
})
},
onGoDetail(item) {
uni.navigateTo({
url: '/pages/product-detail/product-detail?id=' + item.id
})
},
/* ============================
* 统一轮播控制(单一入口)
* ============================ */
/**
* 启动统一轮播:单一 setInterval,3 秒一次,
* 同时推进 StepsFlow 的 currentStep 和 PlatformFeatures 的 currentFeat。
* 两个组件的 active 各自 mod 自己的 length,互不干扰。
*/
startAutoPlay() {
this.stopAutoPlay()
this._autoPlayTimer = setInterval(() => {
const stepTotal = (this.stepList || []).length
const featTotal = (this.featureList || []).length
if (stepTotal > 1) {
this.currentStep = (this.currentStep + 1) % stepTotal
}
if (featTotal > 1) {
this.currentFeat = (this.currentFeat + 1) % featTotal
}
}, AUTO_PLAY_INTERVAL)
},
/**
* 回收定时器:onHide / onUnload 时调用,避免后台运行浪费资源
*/
stopAutoPlay() {
if (this._autoPlayTimer) {
clearInterval(this._autoPlayTimer)
this._autoPlayTimer = null
}
},
/**
* 用户点击 StepsFlow 卡片:
* 先停定时器 → 更新 currentStep → 重启 3s 计数
* (同时 currentFeat 的计数被重置也无妨,体验上完全可接受)
*/
onStepChange(idx) {
this.stopAutoPlay()
this.currentStep = idx
this.startAutoPlay()
},
/**
* 用户点击 PlatformFeatures 卡片:同上逻辑,函数复用
*/
onFeatChange(idx) {
this.stopAutoPlay()
this.currentFeat = idx
this.startAutoPlay()
}
}
}
</script>
<style>
.index-page {
width: 100%;
min-height: 100vh;
background: #ffffff;
}
</style>