2025-07-16 15:07:16 +08:00

496 lines
12 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="temperature">
<text class="temp-value">{{weather.lowest}}~{{weather.highest}}</text>
<!-- <text class="temp-unit">°C</text> -->
</view>
<view class="weather-info">
<text class="weather-desc">{{weather.weather}}</text>
</view>
</view>
<view class="weather-footer">
<view class="weather-detail-item">
<text>东风 {{weather.wind}}</text>
</view>
<view class="weather-detail-item">
<text>湿度 {{weather.humidity}}%</text>
</view>
<view class="weather-detail-item">
<text>空气质量 {{weather.quality}}</text>
</view>
<view class="weather-detail-item">
<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;"></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);
}
},
}
}
</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;
align-items: center;
justify-content: space-between;
margin: 30rpx 0;
padding: 20rpx 0;
.temperature {
display: flex;
align-items: flex-start;
.temp-value {
font-size: 60rpx;
font-weight: 600;
line-height: 1;
}
.temp-unit {
font-size: 36rpx;
margin-top: 8rpx;
}
}
.weather-info {
display: flex;
flex-direction: column;
align-items: center;
.weather-icon {
width: 80rpx;
height: 80rpx;
margin-bottom: 10rpx;
}
.weather-desc {
font-size: 28rpx;
opacity: 0.9;
}
}
}
.weather-footer {
display: flex;
justify-content: space-between;
padding-top: 20rpx;
border-top: 1rpx solid rgba(255, 255, 255, 0.2);
font-size: 24rpx;
.weather-detail-item {
display: flex;
align-items: center;
opacity: 0.9;
.detail-icon {
width: 28rpx;
height: 28rpx;
margin-right: 8rpx;
}
}
}
}
}
/* 便捷服务中心 - 优化后 */
.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: 24rpx;
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>