qiuyuan 7854188d95 1
2026-01-21 16:16:41 +08:00

611 lines
16 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="container">
<view class="content-wrapper">
<!-- 顶部功能区 -->
<view class="quick-access">
<view class="access-item" @click="goDetail('serviceNoticeList')">
<view class="icon-wrapper">
<image src="/static/imgs/index/gonggao.png" mode="aspectFit"></image>
</view>
<text class="access-text">社区公告</text>
</view>
<view class="access-item" @click="goDetail('activeList')">
<view class="icon-wrapper">
<image src="/static/imgs/index/redian.png" mode="aspectFit"></image>
</view>
<text class="access-text">社区活动</text>
</view>
<view class="access-item" @click="goDetail('neighbor')">
<view class="icon-wrapper">
<image src="/static/imgs/index/linli.png" mode="aspectFit"></image>
</view>
<text class="access-text">周边服务</text>
</view>
</view>
<!-- 轮播图 -->
<view class="swiper-section">
<u-swiper :list="list1" height="320" indicator indicatorMode="dot" bgColor="#f8faff"></u-swiper>
</view>
<!-- 天气和穿搭建议 -->
<view class="weather-outfit-section">
<view class="weather-card">
<view class="weather-header">
<text class="location">{{weather.province || '--'}}·{{weather.area || '--'}}</text>
<text class="date">{{weather.date || '--'}} {{weather.week || '--'}}</text>
</view>
<view v-if="weatherLoading" class="loading-content">
<text class="loading-text">天气信息加载中...</text>
</view>
<view v-else-if="weatherError" class="error-content">
<text class="error-text">天气信息获取失败</text>
</view>
<view v-else class="weather-content">
<view class="weather-main">
<view class="current-weather">
<image class="weather-icon"
:src="weather.weather ? getWeatherIcon(weather.weather) : '/static/imgs/weather.png'"
mode="aspectFit"></image>
<text class="current-temp">{{weather.real || '--'}}°</text>
</view>
<text class="weather-desc">{{weather.weather || '--'}}</text>
</view>
<view class="temperature-range">
<text class="temp-item">最高温 {{weather.highest || '--'}}°</text>
<text class="temp-item">最低温 {{weather.lowest || '--'}}°</text>
</view>
</view>
<view v-if="!weatherLoading && !weatherError" class="weather-footer">
<view class="footer-item">
<text class="footer-icon">风向</text>
<text class="footer-text">{{weather.wind || '--'}}</text>
</view>
<view class="footer-item">
<text class="footer-icon">湿度</text>
<text class="footer-text">{{weather.humidity || '--'}}%</text>
</view>
<view class="footer-item">
<text class="footer-icon">空气质量</text>
<text class="footer-text">{{weather.quality || '--'}}</text>
</view>
<view class="footer-item">
<text class="footer-icon">紫外线</text>
<text class="footer-text">{{weather.uv_index || '--'}}</text>
</view>
</view>
</view>
</view>
<!-- 便捷服务中心 -->
<view class="service-section">
<view class="section-header">
<view class="header-decoration"></view>
<text class="section-title">便捷中心</text>
<text class="section-subtitle">一站式社区服务</text>
</view>
<view class="service-grid">
<view class="service-card card-1" @click="goDetail('neighborList')" hover-class="card-hover">
<view class="card-content">
<text class="card-title">邻里互助</text>
<text class="card-desc">近邻互帮互助</text>
<view class="card-bg"></view>
</view>
<image class="card-icon" src="/static/imgs/index/bangzhu.png"
style="width: 76rpx;height: 76rpx; bottom: 32rpx;"></image>
</view>
<view class="service-card card-2" @click="goDetail('serviceTickets')" hover-class="card-hover">
<view class="card-content">
<text class="card-title">物业报修</text>
<text class="card-desc">维修方便便捷</text>
<view class="card-bg"></view>
</view>
<image class="card-icon" src="/static/imgs/index/weixiu.png" style="width: 80rpx;height: 80rpx;bottom: 32rpx;"></image>
</view>
</view>
</view>
</view>
<!-- 底部导航 -->
<Copyright/>
<Footer></Footer>
</view>
</template>
<script>
import Copyright from '@/components/gx-copyright.vue';
import Footer from '@/components/footer_common.vue';
import { get, post } from '@/utils/request';
import { IMAGE_BASE_URL, BASE_URL } from '@/utils/config';
import {navigateTo} from '@/utils/router.js'
export default {
components: {
Footer,
Copyright
},
data() {
return {
list1: [],
currentDate: this.formatDate(new Date()),
weather: {
province: '',
area: '',
date: '',
week: '',
real: '',
highest: '',
lowest: '',
weather: '',
wind: '',
humidity: '',
quality: '',
uv_index: ''
},
weatherLoading: false,
weatherError: false
}
},
mounted() {
this.getBanners();
this.getWeather();
},
methods: {
goDetail(page) {
if(page==='neighbor'){
navigateTo({url: `/pages/${page}/index`})
}else{
uni.navigateTo({
url: `/pages/${page}/index`
});
}
},
formatDate(date) {
const weekdays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
const month = date.getMonth() + 1;
const day = date.getDate();
const weekday = weekdays[date.getDay()];
return `${weekday} ${month}${day}`;
},
// 获取轮播图接口
async getBanners() {
let params = {
current: 1,
pageSize: 4,
status: 1,
scene: 1
};
try {
const res = await get('/api/v1/apps/home/banners', params);
if (!res || !res.success) {
throw new Error('获取轮播图失败');
}
res.data.forEach(item => {
let imgUrl = item.img;
if (!imgUrl.startsWith('http') && !imgUrl.startsWith('https')) {
item.img = IMAGE_BASE_URL + imgUrl;
this.list1.push(item.img);
}
})
} catch (err) {
console.error('获取轮播图失败:', err);
}
},
// 获取天气
async getWeather() {
this.weatherLoading = true;
this.weatherError = false;
try {
const res = await get('/api/v1/apps/home/weather');
if (!res || !res.success) {
throw new Error('获取天气失败');
}
this.weather = {
province: res.data.province || '--',
area: res.data.area || '--',
date: res.data.date || '--',
week: res.data.week || '--',
real: res.data.real || '--',
highest: res.data.highest || '--',
lowest: res.data.lowest || '--',
weather: res.data.weather || '--',
wind: res.data.wind || '--',
humidity: res.data.humidity || '--',
quality: res.data.quality || '--',
uv_index: res.data.uv_index || '--'
};
} catch (err) {
console.error('获取天气失败:', err);
this.weatherError = true;
uni.showToast({
title: '天气信息获取失败',
icon: 'none'
});
} finally {
this.weatherLoading = false;
}
},
getWeatherIcon(weather) {
if (!weather || typeof weather !== 'string') {
return '/static/imgs/weather/default.png';
}
const weatherMap = {
'晴': '/static/imgs/index/sunny.png',
'多云': '/static/imgs/index/cloudy.png',
'阴': '/static/imgs/index/overcast.png',
'雨': '/static/imgs/index/rain.png',
'小雨': '/static/imgs/index/light-rain.png',
'中雨': '/static/imgs/index/moderate-rain.png',
'大雨': '/static/imgs/index/heavy-rain.png',
'暴雨': '/static/imgs/index/storm-rain.png',
'雪': '/static/imgs/index/snow.png',
'雾': '/static/imgs/index/fog.png',
'霾': '/static/imgs/index/fog.png',
};
// 遍历天气关键词,匹配最合适的图标
for (const key in weatherMap) {
if (weather.includes(key)) {
return weatherMap[key];
}
}
return '/static/imgs/weather/default.png';
}
}
}
</script>
<style lang="scss" scoped>
.container {
background: #f8faff;
// min-height: 100vh;
box-sizing: border-box;
background-color: #f5f7fa;
padding: 20rpx;
// min-height: 100vh;
box-sizing: border-box;
padding-bottom: calc(190rpx);
.content-wrapper {
width: 92%;
margin: 0 auto;
padding-top: 20rpx;
}
/* 快速访问区域 */
.quick-access {
display: flex;
justify-content: space-between;
margin-bottom: 40rpx;
.access-item {
width: 30%;
display: flex;
flex-direction: column;
align-items: center;
padding: 20rpx 0;
border-radius: 16rpx;
background: #fff;
box-shadow: 0 4rpx 12rpx rgba(128, 179, 255, 0.1);
transition: all 0.3s;
&:active {
transform: scale(0.96);
opacity: 0.9;
}
}
.icon-wrapper {
width: 80rpx;
height: 80rpx;
margin-bottom: 12rpx;
image {
width: 100%;
height: 100%;
}
}
.access-text {
font-size: 26rpx;
color: #666;
font-weight: 500;
}
}
/* 轮播图区域 */
.swiper-section {
border-radius: 20rpx;
overflow: hidden;
margin-bottom: 40rpx;
box-shadow: 0 8rpx 24rpx rgba(128, 179, 255, 0.15);
}
/* 天气和穿搭区域 */
.weather-outfit-section {
margin-bottom: 40rpx;
.weather-card {
width: 92%;
background: #85b0ed;
border-radius: 20rpx;
padding: 30rpx;
color: #fff;
box-shadow: 0 8rpx 24rpx rgba(133, 176, 237, 0.3);
.weather-header {
display: flex;
justify-content: space-between;
margin-bottom: 20rpx;
padding-bottom: 20rpx;
border-bottom: 1rpx solid rgba(255, 255, 255, 0.2);
.date {
font-size: 26rpx;
opacity: 0.9;
font-weight: bold;
}
.location {
font-size: 28rpx;
font-weight: 500;
}
}
.weather-content {
display: flex;
justify-content: space-between;
align-items: center;
margin: 20rpx 0;
padding: 20rpx 0;
.weather-main {
display: flex;
flex-direction: column;
align-items: center;
.current-weather {
display: flex;
align-items: center;
.weather-icon {
width: 80rpx;
height: 80rpx;
margin-right: 15rpx;
}
.current-temp {
font-size: 64rpx;
font-weight: bold;
line-height: 1;
}
}
.weather-desc {
font-size: 28rpx;
margin-top: 10rpx;
opacity: 0.9;
}
}
.temperature-range {
display: flex;
flex-direction: column;
align-items: flex-end;
.temp-item {
font-size: 28rpx;
margin-bottom: 10rpx;
opacity: 0.8;
&:last-child {
margin-bottom: 0;
}
}
}
}
.weather-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 20rpx;
border-top: 1rpx solid rgba(255, 255, 255, 0.2);
font-size: 24rpx;
.footer-item {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
.footer-icon {
font-size: 28rpx;
font-weight:500;
margin-bottom: 6rpx;
}
.footer-text {
opacity: 0.9;
text-align: center;
line-height: 1.2;
}
}
}
.loading-content, .error-content {
display: flex;
align-items: center;
justify-content: center;
height: 200rpx;
font-size: 28rpx;
color: #fff;
}
}
}
/* 便捷服务中心 - 优化后 */
.service-section {
margin-bottom: 40rpx;
.section-header {
display: flex;
align-items: center;
margin-bottom: 24rpx;
position: relative;
.header-decoration {
width: 8rpx;
height: 32rpx;
background: linear-gradient(to bottom, #5b9cf8, #3a7de8);
border-radius: 4rpx;
margin-right: 16rpx;
}
.section-title {
font-size: 36rpx;
font-weight: 700;
color: #333;
margin-right: 16rpx;
}
.section-subtitle {
font-size: 24rpx;
color: #999;
padding-top: 6rpx;
}
}
.service-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 24rpx;
.service-card {
background: #fff;
border-radius: 24rpx;
padding: 32rpx;
position: relative;
overflow: hidden;
box-shadow: 0 6rpx 18rpx rgba(74, 144, 226, 0.12);
transition: all 0.3s ease;
z-index: 1;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.6));
z-index: -1;
}
&.large {
grid-column: span 2;
}
.card-content {
position: relative;
z-index: 2;
.card-title {
display: block;
font-size: 34rpx;
font-weight: 700;
color: #333;
margin-bottom: 12rpx;
}
.card-desc {
font-size: 26rpx;
color: #666;
}
.card-bg {
position: absolute;
width: 120rpx;
height: 120rpx;
border-radius: 50%;
filter: blur(20rpx);
opacity: 0.15;
z-index: -1;
}
}
.card-icon {
position: absolute;
width: 90rpx;
height: 90rpx;
right: 24rpx;
bottom: 20rpx;
transition: all 0.3s ease;
}
/* 为每个卡片设置不同的主题色 */
&.card-1 {
.card-bg {
background: #5b9cf8;
top: -30rpx;
right: -30rpx;
}
.card-icon {
filter: drop-shadow(0 4rpx 8rpx rgba(91, 156, 248, 0.3));
}
}
&.card-2 {
.card-bg {
background: #5b9cf8;
top: -50rpx;
right: -30rpx;
}
.card-icon {
filter: drop-shadow(0 4rpx 8rpx rgba(91, 156, 248, 0.3));
}
}
&.card-3 {
.card-bg {
background: #6dd400;
top: -30rpx;
right: -30rpx;
}
.card-icon {
filter: drop-shadow(0 4rpx 8rpx rgba(109, 212, 0, 0.3));
}
}
}
.card-hover {
transform: translateY(-8rpx);
box-shadow: 0 12rpx 24rpx rgba(74, 144, 226, 0.2);
.card-icon {
transform: scale(1.1);
}
}
}
}
}
</style>