<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';
// 轮播图数据 - 初始为空数组
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 {
// 使用POST方法调用API
const response = await uni.request({
url: '/api/incorruptFront/public/index',
method: 'POST',
timeout: 10000,
header: {
'Content-Type': 'application/json'
},
data: {
// 添加必要的请求参数(根据API文档)
// 例如: page: 1, size: 10
}
});
// 处理响应数据
console.log('API响应:', response);
if (response && response.length >= 2) {
const res = response[1]; // uni.request 返回 [err, res]
// 检查响应状态码和数据格式
if (res && res.statusCode === 200 && res.data && res.data.code === 200) {
// 提取所需字段,根据提供的JSON结构
banners.value = res.data.data.map(item => ({
image: item.imageUrl, // 图片URL
title: item.imageTitle, // 图片标题
description: item.imageText // 图片描述文本
}));
console.log('成功获取轮播图数据:', banners.value);
return; // 成功获取数据,直接返回
} else if (res && res.data && res.data.msg) {
console.error('API返回错误:', res.data.msg);
// 显示错误提示
uni.showToast({
title: `API错误: ${res.data.msg}`,
icon: 'none',
duration: 3000
});
}
}
// 不使用默认数据,保持空数组
banners.value = [];
} catch (error) {
console.error('获取轮播图数据失败:', error);
// 显示错误提示
uni.showToast({
title: '网络请求失败,请检查连接',
icon: 'error',
duration: 2000
});
banners.value = [];
} finally {
loading.value = false;
lastUpdated.value = new Date().toLocaleString();
}
};
// 组件挂载时获取数据
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>
还是报错: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)
我的manifest.json代理配置如下:{
"name" : "清廉其亚",
"appid" : "__UNI__772DBEF",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App特有相关 */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* 模块配置 */
"modules" : {},
/* 应用发布信息 */
"distribute" : {
/* android打包配置 */
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios打包配置 */
"ios" : {},
/* SDK配置 */
"sdkConfigs" : {}
}
},
/* 快应用特有相关 */
"quickapp" : {},
/* 小程序特有相关 */
"mp-weixin" : {
"appid" : "",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "3",
"fallbackLocale" : "zh-Hans",
"h5" : {
"title" : "清廉其亚",
"router" : {
"mode" : "history"
},
"devServer": {
"port": 8080, // 端口
"disableHostCheck": true,
"proxy": {
"/api": {
"target": "http://172.26.26.34:8080", // 目标服务器地址
"changeOrigin": true,
"secure": false, // 如果是https,需要设置为true
"pathRewrite": {
"^/api": "" // 重写路径,去掉请求路径中的/api
}
}
}
}
}
}
最新发布