campus-errand/miniapp/pages/index/index.vue
2026-03-12 18:12:10 +08:00

152 lines
2.7 KiB
Vue

<template>
<view class="index-page">
<!-- 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-section">
<view class="service-title">下订单</view>
<view class="service-grid">
<view
class="service-item"
v-for="entry in serviceEntries"
:key="entry.id"
@click="onServiceClick(entry)"
>
<image class="service-icon" :src="entry.iconUrl" mode="aspectFit"></image>
<text class="service-name">{{ entry.name }}</text>
</view>
</view>
</view>
</view>
</template>
<script>
import { getBanners, getServiceEntries } from '../../utils/api'
export default {
data() {
return {
banners: [],
serviceEntries: []
}
},
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 点击处理
* 外部链接通过 web-view 打开
* 内部页面直接跳转
*/
onBannerClick(item) {
if (!item.linkUrl) return
if (item.linkType === 'External') {
// 外部链接,通过 web-view 打开
uni.navigateTo({
url: `/pages/webview/webview?url=${encodeURIComponent(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;
}
.banner-swiper {
width: 100%;
height: 320rpx;
}
.banner-image {
width: 100%;
height: 320rpx;
}
.service-section {
margin: 30rpx 24rpx 0;
background-color: #ffffff;
border-radius: 16rpx;
padding: 30rpx;
}
.service-title {
font-size: 32rpx;
font-weight: bold;
color: #333333;
margin-bottom: 30rpx;
}
.service-grid {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.service-item {
display: flex;
flex-direction: column;
align-items: center;
width: 20%;
margin-bottom: 20rpx;
}
.service-icon {
width: 88rpx;
height: 88rpx;
margin-bottom: 12rpx;
}
.service-name {
font-size: 24rpx;
color: #666666;
}
</style>