559 lines
14 KiB
Vue
559 lines
14 KiB
Vue
<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 class="weather-content">
|
||
<view class="weather-main">
|
||
<view class="current-weather">
|
||
<image class="weather-icon" :src="weather.weather ? getWeatherIcon(weather.weather) : '/static/imgs/weather/default.png'" mode="aspectFit"></image>
|
||
</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 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"></image>
|
||
</view>
|
||
|
||
<!-- <view class="service-card large card-3" @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"></image>
|
||
</view> -->
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 底部导航 -->
|
||
<Footer></Footer>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import Footer from '@/components/footer_common.vue';
|
||
import {
|
||
get,
|
||
post
|
||
} from '@/utils/request';
|
||
import {
|
||
IMAGE_BASE_URL,
|
||
BASE_URL
|
||
} from '@/utils/config';
|
||
|
||
export default {
|
||
components: {
|
||
Footer
|
||
},
|
||
data() {
|
||
return {
|
||
list1: [],
|
||
currentDate: this.formatDate(new Date()),
|
||
weather: {},
|
||
}
|
||
},
|
||
mounted() {
|
||
this.getBanners();
|
||
this.getWeather();
|
||
},
|
||
methods: {
|
||
goDetail(page) {
|
||
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() {
|
||
|
||
try {
|
||
const res = await get('/api/v1/apps/home/weather');
|
||
if (!res || !res.success) {
|
||
throw new Error('获取天气失败');
|
||
}
|
||
this.weather = {
|
||
...res.data
|
||
};
|
||
} catch (err) {
|
||
console.error('获取轮播图失败:', err);
|
||
}
|
||
},
|
||
|
||
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',
|
||
};
|
||
|
||
// 默认图标
|
||
const defaultIcon = '/static/imgs/weather/default.png';
|
||
|
||
// 遍历天气关键词,匹配最合适的图标
|
||
for (const key in weatherMap) {
|
||
if (weather.includes(key)) {
|
||
return weatherMap[key];
|
||
}
|
||
}
|
||
|
||
return defaultIcon;
|
||
}
|
||
|
||
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.container {
|
||
background: #f8faff;
|
||
min-height: 100vh;
|
||
padding-bottom: 120rpx;
|
||
box-sizing: border-box;
|
||
|
||
.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;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 便捷服务中心 - 优化后 */
|
||
.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: #ff7e7e;
|
||
top: -30rpx;
|
||
right: -30rpx;
|
||
}
|
||
|
||
.card-icon {
|
||
filter: drop-shadow(0 4rpx 8rpx rgba(255, 126, 126, 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> |