<template>
<view class="page-container">
<view class="header-title">
<text>欢迎来到清廉其亚</text>
</view>
<!-- 轮播图区域 -->
<view class="banner-container">
<!-- 加载状态提示 -->
<view v-if="loading" class="loading-container">
<image src="/static/loading.gif" class="loading-icon" />
<text class="loading-text">轮播图数据加载中...</text>
</view>
<!-- 轮播图内容 -->
<swiper
v-else
class="banner-swiper"
:autoplay="true"
:interval="3000"
:circular="true"
:indicator-dots="true"
>
<swiper-item v-for="(item, index) in banners" :key="index" class="swiper-item">
<image :src="item.image" mode="aspectFill" class="banner-image" />
<view class="banner-text">
<text class="banner-title">{{ item.title }}</text>
<text class="banner-description">{{ item.description }}</text>
</view>
</swiper-item>
</swiper>
</view>
<!-- 图标菜单区域 - 添加内部滚动 -->
<view class="icon-menu-container">
<view class="section-title">
<text>清廉服务</text>
</view>
<!-- 内部滚动容器 -->
<scroll-view
class="scroll-container"
scroll-y
:show-scrollbar="false"
:enhanced="true"
:bounces="false"
>
<view class="icon-grid">
<view
v-for="(item, index) in iconMenus"
:key="index"
class="icon-item"
@click="navigateTo(item)"
>
<image :src="item.icon" class="icon-image" />
<text class="icon-text">{{ item.text }}</text>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { request } from '../../src/request';
// 轮播图数据 - 初始为空数组
const banners = ref([]);
const loading = ref(true);
const lastUpdated = ref('');
// 图标菜单数据
const iconMenus = ref([
{
icon: '/static/icons/ServiceHall.png',
text: '服务大厅',
name: '服务大厅',
path: '/pages/WebView/WebView'
},
{
icon: '/static/icons/IntegrityCulture.png',
text: '廉洁文化',
name: '廉洁文化',
path: '/pages/IntegrityCulture/IntegrityCulture'
},
{
icon: '/static/icons/IntegrityStandards.png',
text: '廉洁标准',
name: '廉洁标准',
path: '/pages/IntegrityStandards/IntegrityStandards'
},
{
icon: '/static/icons/ComplaintChannel.png',
text: '投诉渠道',
name: '投诉渠道',
path: '/pages/ComplaintChannel/ComplaintChannel'
},
{
icon: '/static/icons/ComplainCases.png',
text: '投诉案例',
name: '投诉案例',
path: '/pages/ComplainCases/ComplainCases'
},
{
icon: '/static/icons/ComplaintRecord.png',
text: '投诉记录',
name: '投诉记录',
path: '/pages/ComplaintRecord/ComplaintRecord'
},
{
icon: '/static/icons/OnlinComplaint.png',
text: '在线投诉',
name: '在线投诉',
path: '/pages/OnlinComplaint/OnlinComplaint'
}
]);
// 获取轮播图数据
const fetchBanners = async () => {
loading.value = true;
try {
const response = await request({
url: '/incorruptFront/public/index',
method: 'POST',
data: {
// 请求参数
}
});
console.log('API响应:', response);
// 处理响应数据
if (response && response.code === 200) {
banners.value = response.data.map(item => ({
image: item.imageUrl,
title: item.imageTitle,
description: item.imageText
}));
} else {
uni.showToast({
title: response.msg || '请求失败',
icon: 'none',
duration: 2000
});
}
} catch (error) {
console.error('获取轮播图数据失败:', error);
uni.showToast({
title: '网络请求失败: ' + error.message,
icon: 'error',
duration: 2000
});
} finally {
loading.value = false;
}
};
// 组件挂载时获取数据
onMounted(() => {
fetchBanners();
});
// 导航方法
const navigateTo = (item) => {
uni.navigateTo({
url: item.path, // 使用配置的路径
fail: (err) => console.error('跳转失败', err)
});
};
</script>
<style scoped>
.page-container {
display: flex;
flex-direction: column;
height: 100vh; /*使用视口高度 */
overflow: hidden; /* 防止全局溢出 */
padding: 20rpx;
box-sizing: border-box;
background: linear-gradient(135deg, #f5f7fa 0%, #e4edf9 100%);
}
.header-title {
display: flex;
justify-content: center;
align-items: center;
font-size: 36rpx;
font-weight: bold;
color: #1a3a8a;
margin: 20rpx 0;
position: relative;
flex-shrink: 0; /* 防止标题区域被压缩 */
}
.header-title::before,
.header-title::after {
content: "";
position: absolute;
top: 50%;
width: 25%;
height: 2rpx;
background: linear-gradient(90deg, transparent, #1a3a8a, transparent);
}
.header-title::before {
left: 5%;
}
.header-title::after {
right: 5%;
}
.banner-container {
width: 100%;
height: 350rpx;
border-radius: 20rpx;
overflow: hidden;
margin-bottom: 40rpx;
box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.1);
position: relative;
flex-shrink: 0; /* 防止轮播图区域被压缩 */
}
.loading-container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
background: #f0f4f9;
}
.loading-icon {
width: 80rpx;
height: 80rpx;
margin-bottom: 20rpx;
}
.loading-text {
font-size: 28rpx;
color: #1a3a8a;
}
.banner-swiper {
width: 100%;
height: 100%;
}
.banner-image {
width: 100%;
height: 100%;
}
.banner-text {
position: absolute;
bottom: 40rpx;
left: 30rpx;
color: #fff;
text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.5);
}
.banner-title {
font-size: 36rpx;
font-weight: bold;
display: block;
margin-bottom: 10rpx;
}
.banner-description {
font-size: 26rpx;
display: block;
width: 90%;
}
/* 图标菜单区域 */
.icon-menu-container {
background: #fff;
border-radius: 20rpx;
padding: 30rpx;
box-shadow: 0 5rpx 20rpx rgba(0, 0, 0, 0.05);
flex: 1; /* 占据剩余空间 */
display: flex;
flex-direction: column;
overflow: hidden; /* 防止溢出 */
}
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #1a3a8a;
margin-bottom: 30rpx;
padding-left: 20rpx;
border-left: 8rpx solid #1a3a8a;
flex-shrink: 0; /* 防止标题被压缩 */
}
/* 内部滚动容器 */
.scroll-container {
flex: 1; /*占据剩余空间 */
overflow: hidden; /* 隐藏滚动条 */
}
/* 隐藏滚动条 */
.scroll-container ::-webkit-scrollbar {
display: none;
width: 0;
height: 0;
color: transparent;
}
.icon-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20rpx;
padding-bottom: 20rpx;
}
.icon-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 20rpx 10rpx;
border-radius: 12rpx;
background: #f8fafd;
transition: all 0.3s ease;
}
.icon-item:active {
background: #e6f0ff;
transform: scale(0.98);
}
.icon-image {
width: 100rpx;
height: 100rpx;
margin-bottom: 15rpx;
}
.icon-text {
font-size: 24rpx;
color: #333;
text-align: center;
line-height: 1.4;
}
/* 响应式调整 */
@media (max-width: 480px) {
.icon-grid {
grid-template-columns: repeat(3, 1fr);
}
}
</style>
输出结果:[Request] POST /api/incorruptFront/public/index {}
request.js:39 [Response] /api/incorruptFront/public/index {data: {…}, statusCode: 200, header: {…}, cookies: Array(0), errMsg: 'request:ok'}cookies: Array(0)length: 0[[Prototype]]: Array(0)data: {code: 500, msg: '404 NOT_FOUND'}errMsg: "request:ok"header: {access-control-allow-origin: '*', connection: 'close', content-length: '34', content-type: 'application/json', date: 'Fri, 15 Aug 2025 07:01:47 GMT'}statusCode: 200[[Prototype]]: Object
index.vue:133 API响应: {code: 500, msg: '404 NOT_FOUND'}
(索引):1 Access to XMLHttpRequest at 'http://localhost:9500/' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
uni-h5.es.js:20597 GET http://localhost:9500/ net::ERR_FAILED 200 (OK)
最新发布