All checks were successful
continuous-integration/drone/push Build is passing
160 lines
3.4 KiB
Vue
160 lines
3.4 KiB
Vue
<template>
|
||
<view class="index-page">
|
||
<!-- 自定义导航栏 -->
|
||
<view class="custom-navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
|
||
<view class="navbar-content" :style="{ height: navBarHeight + 'px' }">
|
||
<text class="navbar-title">首页</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 占位,防止内容被导航栏遮挡 -->
|
||
<view :style="{ height: (statusBarHeight + navBarHeight) + 'px' }"></view>
|
||
|
||
<!-- Banner 轮播区域 -->
|
||
<swiper v-if="banners.length > 0" class="banner-swiper" indicator-dots autoplay circular
|
||
indicator-color="rgba(255,255,255,0.5)" indicator-active-color="#ffffff">
|
||
<swiper-item v-for="item in banners" :key="item.id" @click="onBannerClick(item)">
|
||
<image class="banner-image" :src="item.imageUrl" mode="aspectFill"></image>
|
||
</swiper-item>
|
||
</swiper>
|
||
|
||
<!-- 服务入口卡片列表 -->
|
||
<view class="service-list">
|
||
<view class="service-card" v-for="entry in serviceEntries" :key="entry.id" @click="onServiceClick(entry)">
|
||
<image class="service-bg" :src="entry.iconUrl" mode="aspectFit"></image>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
getBanners,
|
||
getServiceEntries
|
||
} from '../../utils/api'
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
banners: [],
|
||
serviceEntries: [],
|
||
statusBarHeight: 0,
|
||
navBarHeight: 44
|
||
}
|
||
},
|
||
onLoad() {
|
||
const sysInfo = uni.getSystemInfoSync()
|
||
this.statusBarHeight = sysInfo.statusBarHeight || 0
|
||
},
|
||
onShow() {
|
||
this.loadData()
|
||
},
|
||
methods: {
|
||
/** 加载 Banner 和服务入口数据 */
|
||
async loadData() {
|
||
try {
|
||
const [bannerRes, entryRes] = await Promise.all([
|
||
getBanners(),
|
||
getServiceEntries()
|
||
])
|
||
this.banners = bannerRes || []
|
||
this.serviceEntries = entryRes || []
|
||
} catch (e) {
|
||
// 静默处理
|
||
}
|
||
},
|
||
|
||
/** Banner 点击处理 */
|
||
onBannerClick(item) {
|
||
if (!item.linkUrl) return
|
||
if (item.linkType === 'External') {
|
||
uni.navigateTo({
|
||
url: `/pages/webview/webview?url=${encodeURIComponent(item.linkUrl)}`
|
||
})
|
||
} else {
|
||
// tabBar 页面需要用 switchTab 跳转
|
||
const tabPages = [
|
||
'/pages/index/index',
|
||
'/pages/order-hall/order-hall',
|
||
'/pages/message/message',
|
||
'/pages/mine/mine'
|
||
]
|
||
if (tabPages.includes(item.linkUrl)) {
|
||
uni.switchTab({ url: item.linkUrl })
|
||
} else {
|
||
uni.navigateTo({ url: item.linkUrl })
|
||
}
|
||
}
|
||
},
|
||
|
||
/** 服务入口点击跳转 */
|
||
onServiceClick(entry) {
|
||
if (!entry.pagePath) return
|
||
uni.navigateTo({
|
||
url: entry.pagePath
|
||
})
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.index-page {
|
||
padding-bottom: 20rpx;
|
||
background-color: #f5f5f5;
|
||
}
|
||
|
||
/* 自定义导航栏 */
|
||
.custom-navbar {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
z-index: 999;
|
||
background: linear-gradient(to right, #FFB700, #FFD59B);
|
||
}
|
||
|
||
.navbar-content {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.navbar-title {
|
||
font-size: 34rpx;
|
||
font-weight: bold;
|
||
color: #363636;
|
||
}
|
||
|
||
.banner-swiper {
|
||
width: 100%;
|
||
height: 374rpx;
|
||
}
|
||
|
||
.banner-image {
|
||
width: 100%;
|
||
height: 374rpx;
|
||
}
|
||
|
||
/* 服务入口卡片列表 */
|
||
.service-list {
|
||
padding: 20rpx 24rpx;
|
||
}
|
||
|
||
.service-card {
|
||
position: relative;
|
||
width: 100%;
|
||
height: 180rpx;
|
||
overflow: hidden;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.service-bg {
|
||
width: 100%;
|
||
height: 100%;
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
}
|
||
|
||
</style> |