Files
SmartParks_uniapp/pages/sys/home/home.vue
liyuanchao f541c0f191
Some checks failed
Uniapp 自动化打包 CI/CD / 打包 Uniapp 项目 (push) Has been cancelled
首页
2025-09-08 16:24:59 +08:00

523 lines
10 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="home-container">
<!-- 顶部Banner区域包含所有顶部内容 -->
<view class="home-header">
<swiper class="banner-swiper" :current="current" @change="onBannerChange" :autoplay="true" :interval="3000"
:circular="true">
<swiper-item v-for="(item, idx) in banners" :key="idx">
<image :src="item.img" class="banner-bg-img" mode="aspectFill" />
</swiper-item>
</swiper>
<!-- 自定义指示器 -->
<view class="banner-indicator">
<view v-for="(item, idx) in banners" :key="idx"
:class="['banner-dot', current === idx ? 'active' : '']"></view>
</view>
<view class="home-top">
<image class="icon3" src="/static/ic_tq.png" />
<text class="weather">21-36</text>
<view class="search-bar">
<image src="/static/ic_search.png" class="search-icon-img" />
<input class="search-input" placeholder="搜索" />
</view>
<view class="top-icons">
<image class="icon1" src="/static/ic_scan.png" @click="goToScan" />
<image class="icon2" src="/static/ic_msg.png" />
</view>
</view>
</view>
<!-- 白色圆角虚线面板 -->
<view class="main-panel">
<!-- 九宫格功能区 -->
<view class="grid-area">
<view class="grid-item" v-for="(item, idx) in gridList" :key="idx" @click="handleItemClick(item.url)">
<image :src="item.icon" class="grid-icon" />
<text class="grid-text">{{ item.text }}</text>
</view>
</view>
<!-- 滚动资讯条 -->
<view class="news-bar">
<image class="news-label" src="/static/ic_home_tt.png"></image>
<view class="news-scroll-container">
<scroll-view scroll-y class="news-scroll" :scroll-top="scrollTop">
<view class="news-list">
<!-- 重复列表以实现无缝循环 -->
<text v-for="(item, idx) in [...newsList, ...newsList]" :key="idx" class="news-item" @click="goNoticeDetail(item)">{{ item.title }}</text>
</view>
</scroll-view>
</view>
<text class="news-arrow"></text>
</view>
<!-- 热门活动区 -->
<view class="hot-section">
<view class="hot-title-row">
<text class="hot-title">热门活动</text>
<text class="hot-more">全部热门活动 ></text>
</view>
<view class="hot-list">
<view class="hot-card" v-for="(item, idx) in hotList" :key="idx">
<image :src="item.img" class="hot-img" mode="aspectFill" />
<view class="hot-info">
<text class="hot-tag">#热门活动</text>
<text class="hot-desc">{{ item.title }}</text>
<view class="hot-meta">
<text class="hot-date">{{ item.date }}</text>
<text class="hot-status">进行中</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import toast from '../../../uview-ui/libs/function/toast';
export default {
name: 'Home',
data() {
return {
banners: [{
img: '/static/aaa_banner1.png'
}
// ,
// {
// img: 'https://picsum.photos/750/300?random=2'
// }
],
current: 0,
gridList: [
{
icon: '/static/aaaa_gd.png',
text: '工单',
url:'/pages/sys/workbench/order/order'
},
{
icon: '/static/aaaa_yjcl.png',
text: '预警处理',
url:'/pages/sys/workbench/earlyWarning/earlyWarning'
},
{
icon: '/static/aaaa_jk.png',
text: '监控',
url:'/pages/sys/workbench/monitor/monitors'
},
{
icon: '/static/aaaa_bsbx.png',
text: '报事报修',
url:'/pages/sys/user/myRepair/myRepair'
},
],
newsList: [
'数智南川|最新资讯1',
'数智南川|最新资讯2',
'数智南川|最新资讯3'
],
scrollTop: 0,
scrollInterval: null,
scrollHeight: 0,
hotList: [{
img: '/static/aaa_hd1.png',
title: '世界骑行日 低碳出行 让城市更美好',
date: '2025-07-03'
},
{
img: '/static/aaa_hd2.png',
title: '仲夏之夜低碳出行·绿色生活让城市更美好',
date: '2025-07-03'
}
]
}
},
onLoad() {
this.getNotices()
},
methods: {
async getNotices() {
let res = await this.$u.api.getNotices();
if (res.code == '200') {
this.newsList = res.rows
}
},
goNoticeDetail(item){
let params = {}
params.title = item.title
params.content = item.afficheContent
params.time = item.startTime
const itemStr = encodeURIComponent(JSON.stringify(params));
uni.navigateTo({ url: '/pages/sys/user/serviceCenter/questionDetail?item=' + itemStr });
},
onBannerChange(e) {
this.current = e.detail.current;
},
// 扫码功能
goToScan() {
uni.scanCode({
success: (res) => {
console.log('扫码成功', res);
uni.showModal({
title: '扫码结果',
content: res.result,
showCancel: true,
confirmText: '确定',
cancelText: '取消',
success: (modalRes) => {
if (modalRes.confirm) {
console.log('用户点击确定');
// 可以在这里处理扫码结果
}
}
});
},
fail: (err) => {
}
});
},
handleItemClick(url) {
uni.navigateTo({
url: url
});
},
// 资讯跑马灯控制
startScroll() {
// 清除之前的定时器
if (this.scrollInterval) {
clearInterval(this.scrollInterval);
}
// 设置新的定时器
this.scrollHeight = this.newsList.length * 60;
this.scrollTop = 0;
this.scrollInterval = setInterval(() => {
this.scrollTop++;
// 当滚动到一半时重置位置,实现无缝循环
if (this.scrollTop >= this.scrollHeight) {
this.scrollTop = 0;
}
}, 50);
},
onScroll(e) {
// 滚动事件处理
}
},
mounted() {
// 页面加载完成后启动跑马灯
this.$nextTick(() => {
this.startScroll();
});
},
beforeDestroy() {
// 页面销毁前清除定时器
if (this.scrollInterval) {
clearInterval(this.scrollInterval);
}
}
}
</script>
<style scoped>
.home-container {
display: flex;
flex-direction: column;
height: 100vh;
background: #f8f8f8;
padding-bottom: 40rpx;
}
.home-header {
position: relative;
height: 446rpx;
width: 100vw;
margin-bottom: -40rpx;
flex-shrink: 0;
}
.banner-swiper {
width: 100vw;
height: 446rpx;
position: absolute;
left: 0;
top: 0;
z-index: 0;
}
.banner-bg-img {
width: 100vw;
height: 446rpx;
object-fit: cover;
}
.banner-indicator {
position: absolute;
left: 0;
bottom: 64rpx;
width: 100vw;
display: flex;
justify-content: center;
z-index: 2;
}
.banner-dot {
width: 14rpx;
height: 14rpx;
border-radius: 50%;
background: rgba(255, 255, 255, 0.6);
margin: 0 8rpx;
transition: background 0.2s;
}
.banner-dot.active {
background: #3B7BFF;
}
.home-top {
position: relative;
z-index: 3;
display: flex;
align-items: center;
color: #fff;
padding: 80rpx 20rpx 0 20rpx;
}
.weather {
font-size: 24rpx;
margin-left: 10rpx;
margin-right: 16rpx;
}
.search-bar {
flex: 1;
display: flex;
align-items: center;
background: rgba(255, 255, 255, 0.3);
border-radius: 30rpx;
padding: 0 20rpx;
height: 56rpx;
margin-right: 16rpx;
}
.search-input::placeholder {
color: #FFFFFF;
opacity: 1;
}
.search-icon-img {
width: 28rpx;
height: 28rpx;
margin-right: 8rpx;
}
.search-input {
border: none;
background: transparent;
font-size: 26rpx;
flex: 1;
color: #fff;
}
.top-icons {
display: flex;
align-items: center;
}
.icon1 {
width: 33rpx;
height: 33rpx;
margin-left: 19rpx;
}
.icon2 {
width: 38rpx;
height: 38rpx;
margin-left: 23rpx;
}
.icon3 {
width: 40rpx;
height: 40rpx;
}
.main-panel {
flex: 1;
overflow-y: auto;
background: #fff;
border-radius: 20rpx;
position: relative;
z-index: 10;
padding: 20rpx;
}
.grid-area {
display: flex;
flex-wrap: wrap;
padding: 20rpx 0 10rpx 0;
margin-top: 10rpx;
}
.grid-item {
width: 20%;
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 30rpx;
}
.grid-icon {
width: 90rpx;
height: 90rpx;
margin-bottom: 8rpx;
}
.grid-text {
font-size: 24rpx;
color: #1D1D1D;
}
.news-bar {
display: flex;
align-items: center;
padding: 40rpx 0;
border-top: 1rpx solid #f5f5f5;
margin-top: 10rpx;
height: 60rpx;
}
.news-label {
width: 54rpx;
height: 27rpx;
margin-left: 15rpx;
margin-right: 15rpx;
}
.news-scroll-container {
flex: 1;
height: 60rpx;
overflow: hidden;
}
.news-scroll {
height: 60rpx;
white-space: nowrap;
}
.news-list {
display: flex;
flex-direction: column;
}
.news-item {
height: 60rpx;
line-height: 60rpx;
color: #666;
font-size: 24rpx;
flex-shrink: 0;
}
.news-arrow {
color: #999;
font-size: 32rpx;
flex-shrink: 0;
}
.hot-section {
margin-top: 20rpx;
}
.hot-title-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
}
.hot-title {
font-size: 32rpx;
font-weight: bold;
color: #222;
position: relative;
padding-left: 16rpx;
}
.hot-title::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 6rpx;
height: 30rpx;
background: #3B7BFF;
border-radius: 3rpx;
}
.hot-more {
font-size: 24rpx;
color: #999;
}
.hot-list {
display: flex;
flex-direction: column;
gap: 20rpx;
}
.hot-card {
background: #fff;
border-radius: 20rpx;
overflow: hidden;
display: flex;
flex-direction: column;
border: 1rpx solid #f0f0f0;
}
.hot-img {
width: 100%;
height: 280rpx;
object-fit: cover;
}
.hot-info {
padding: 16rpx 20rpx 20rpx 20rpx;
}
.hot-tag {
color: #3B7BFF;
font-size: 22rpx;
margin-bottom: 6rpx;
display: block;
}
.hot-desc {
font-size: 28rpx;
color: #222;
margin-bottom: 10rpx;
display: block;
font-weight: 500;
}
.hot-meta {
display: flex;
justify-content: space-between;
align-items: center;
}
.hot-date {
color: #999;
font-size: 22rpx;
}
.hot-status {
color: #fff;
background: #3B7BFF;
font-size: 22rpx;
border-radius: 8rpx;
padding: 4rpx 12rpx;
}
</style>