Files
property-resident-side/property-uniapp-project/pages/index/index.vue
2026-04-25 07:57:49 +08:00

594 lines
15 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="content-class">
<view class="nar-top">
<!-- 这里是状态栏占位 -->
<view class="status_bar"></view>
<!-- 导航栏 -->
<view class="nav-bar">
<text class="nav-title">首页</text>
</view>
<view class="tabbarClass">
<view class="header-container" @click="navigateToPage">
<!-- 左侧小区选择区域 -->
<view class="location-area">
<!-- 定位图标 -->
<view class="location-icon">
<!-- <uni-icons type="location-filled" size="14" color="#333333"></uni-icons> -->
<image src="http://47.104.199.163:9090/images/home/adress.png" style="height: 100%;width: 100%;"></image>
</view>
<!-- 小区名称和下拉箭头 -->
<view class="community-selector">
<text class="community-name">{{ currentCommunity }}</text>
<u-icon
name="arrow-down-fill"
size="16"
:color="isDropdownOpen ? '#2979ff' : '#222222'"
:class="['dropdown-arrow', { 'rotate': isDropdownOpen }]"
></u-icon>
</view>
</view>
</view>
</view>
</view>
<!-- banner -->
<view class="bannarClass">
<up-swiper :list="bannerList" indicator indicatorMode="dot" ></up-swiper>
</view>
<view class="noticeClass" @click="getNoticeMore">
<image src="http://47.104.199.163:9090/images/home/notice.png" style="width: 38px;height: 38px;position: absolute;top: 21px;left: 17px;"></image>
<view class="col-line"></view>
<uni-notice-bar show-icon :text="noticeText" type="line"
:showIcon="false" show-get-more scrollable color="#000" background-color="#fff" moreColor="#000">
</uni-notice-bar>
</view>
<!-- 一键开门 -->
<view class="u-demo-block__content bg-card-open">
<up-row justify="space-between" gutter="10">
<up-col span="3">
<view class="demo-layout bg-purple openClass" @click="openDoorClick">
<view class="iconClass">
<image src="http://47.104.199.163:9090/images/home/openDoor.png" mode="" style="width: 70px;height: 70px;border-radius: 8px;"></image>
</view>
<view class="title-dome-calss">一键开门</view>
</view>
</up-col>
<up-col span="3">
<view class="demo-layout bg-purple-light openClass" @click="payMentClick">
<view class="iconClass">
<image src="http://47.104.199.163:9090/images/home/lifePay.png" mode="" style="width: 70px;height: 70px;border-radius: 8px;"></image>
</view>
<view class="title-dome-calss">生活缴费</view>
</view>
</up-col>
<up-col span="3">
<view class="demo-layout bg-purple openClass" @click="onlineRepairClick">
<view class="iconClass">
<image src="http://47.104.199.163:9090/images/home/repair.png" mode="" style="width: 70px;height: 70px;border-radius: 8px;"></image>
</view>
<view class="title-dome-calss">在线报修</view>
</view>
</up-col>
<up-col span="3">
<view class="demo-layout bg-purple-light openClass" @click="visitorClick">
<view class="iconClass">
<image src="http://47.104.199.163:9090/images/home/visitorInvite.png" mode="" style="width: 70px;height: 70px;border-radius: 8px;"></image>
</view>
<view class="title-dome-calss">访客邀请</view>
</view>
</up-col>
</up-row>
</view>
<!-- 广告卡片 -->
<view class="adCardClass">
<!-- <uni-card :is-shadow="false" > -->
<view class="u-demo-block__content">
<up-row justify="space-between" customStyle="margin-bottom: 10px">
<up-col span="3">
<view class="demo-layout bg-purple iconRightClass">
<image src="http://47.104.199.163:9090/images/home/ad1.png" mode="" style="width: 100%;height: 100%;"></image>
</view>
</up-col>
<up-col span="8">
<view class="demo-layout bg-purple-light titleLeft">
<text style="color: #fff;font-size: 18px;font-weight: 700;">便民服务</text>
<view style="color: #fff;font-size: 16px;">邻里便民服务 全新上线</view>
</view>
</up-col>
</up-row>
</view>
<!-- </uni-card> -->
</view>
<!-- 活动列表 -->
<uni-card class="activity-card">
<view class="eventListClass">
<view>
<text class="activity-name">活动列表</text>
<!-- <u-title>活动列表</u-title> -->
</view>
<view class="nav-more">
<!-- <up-button type="primary" shape="circle" size="small" text="查看更多" @click="moreClick"></up-button> -->
<text class="look-more-title" @click="moreClick">查看更多</text>
</view>
</view>
<scroll-view :scroll-top="scrollTop" scroll-y="true" class="scroll-Y">
<view class="eventListCard" v-for="(activity, index) in activityList" :key="activity.id">
<!-- 状态标签 -->
<view class="status-tag" :class="{}">
{{ activity.statusText }}
<!-- 进行中 -->
</view>
<view class="u-demo-block__content ">
<up-row justify="space-between" customStyle="margin-bottom: 10px">
<up-col span="4">
<view class="demo-layout bg-purple-light activity-img">
<image :src="activity.coverImage" style="width: 100%;height: 100%;"></image>
</view>
</up-col>
<up-col span="10">
<view class="demo-layout bg-purple activity-info">
<view class="activity-title">{{activity.title}}</view>
<view class="activity-time">{{activity.startTime}}-{{activity.endTime}}</view>
<view class="activity-organizer">
<text>{{activity.createName}}</text>
</view>
<view class="activity-enrollment">
<text>活动名额{{activity.quota}}已报名{{activity.appliedCount}}</text>
</view>
</view>
</up-col>
</up-row>
</view>
</view>
</scroll-view>
</uni-card>
</view>
</template>
<script setup>
import { ref } from 'vue'
import {onLoad,onUnload,onShow} from '@dcloudio/uni-app'
import {getNoticeLatest,getCurrentVillage,getActivitylatest} from "/pageSubPack/api/api.js"
// 列表数据状态
const isDropdownOpen = ref(false)
const scrollTop = ref(0)
const activityList = ref([]) // 活动列表数据
const currentCommunity = ref('请认证小区')
const currentVillageId = ref('')
const bannerList = ref([
'http://47.104.199.163:9090/images/home/banner.png',
])
const noticeText = ref('暂无公告')
const noticeId = ref('')
// =======方法=======
// 公告跳转
const getNoticeMore = () =>{
uni.setStorageSync('sourcePage',"index")
uni.navigateTo({
url:"/pageSubPack/notice-list/noticeList"
})
}
// 接收选择小区返回的参数
const slelctHomeData = (data) =>{
console.log('收到B页面返回的数据', data)
if(data.name){
currentCommunity.value = data.name
}
if(data.villageId){
currentVillageId.value = data.villageId
}
getCurrentCommunityData()
getNoticeData()
getNewActivityList()
}
// 获取当前认证小区的方法
const getCurrentCommunityData = () => {
getCurrentVillage().then(res =>{
if(res.code === 200 && res.data && res.data.villageId){
currentCommunity.value = res.data.villageName || '未命名小区'
currentVillageId.value = res.data.villageId
uni.setStorageSync('currentVillageId',res.data.villageId)
}else{
currentCommunity.value = '请认证小区'
currentVillageId.value = ''
}
}).catch(err =>{
uni.showToast({
title: '网络异常',
icon: 'error'
});
})
}
// 获取首页最新小区公告
const getNoticeData = async() =>{
try{
const res = await getNoticeLatest()
if (res.code === 200) {
if(res.data){
noticeText.value = res.data.noticeTitle || ''
noticeId.value = res.data.noticeId || ''
}else{
noticeText.value = ''
noticeId.value = ''
}
} else {
uni.showToast({
title: res.msg || '获取通知失败',
icon: 'none',
duration: 2000
})
}
} catch (err) {
// console.error('获取通知数据异常:', err)
uni.showToast({
title: err.msg,
icon: 'error',
duration: 1000
})
noticeText.value = ''
noticeId.value = ''
}
}
onShow(() =>{
})
onLoad(() => {
// 绑定全局事件监听
uni.$on('confirm', slelctHomeData)
// 页面加载时先判断是否有token有则获取认证小区
const token = uni.getStorageSync('token') || '';
const currentVillageId = uni.getStorageSync('currentVillageId');
if (token && currentVillageId && currentVillageId !== '0' && currentVillageId !== 0) {
getCurrentCommunityData(); // 加载时获取认证小区
}
getNoticeData()
getNewActivityList()
})
// 页面销毁时移除监听(防止内存泄漏)
onUnload(() => {
uni.$off('confirm', slelctHomeData)
})
// 方法逻辑
const openDoorClick = () =>{
uni.setStorageSync('sourcePage',"index")
uni.navigateTo({
url:"/pageSubPack/notice-list/oneClickOpen"
})
}
// 生活缴费
const payMentClick =() =>{
uni.setStorageSync('sourcePage',"index")
uni.navigateTo({
url:"/pageSubPack/payment-list/paymentIndex"
})
}
// 点击小区选择
const navigateToPage = () => {
const token = uni.getStorageSync('token') || '';
const cachedVillageId = uni.getStorageSync('currentVillageId');
// 未登录 或 未绑定小区 → 去我的页面认证
if (!token || !cachedVillageId || cachedVillageId === '0' || cachedVillageId === 0) {
currentCommunity.value = '请去认证小区';
uni.setStorageSync('currentCommunity', '请去认证小区');
uni.showToast({
title: '请先绑定小区',
icon: 'none',
duration: 1500
});
setTimeout(() => {
uni.switchTab({
url: '/pages/myIndex/myIndex',
});
}, 1500);
} else {
// 已登录且已绑定小区 → 去选择小区
uni.navigateTo({
url: `/pageSubPack/notice-list/selectHome?villageId=${cachedVillageId}`
});
}
};
// 获取首页最新活动
const getNewActivityList = async() =>{
try{
const res = await getActivitylatest()
if(res.code === 200){
if(res.data){
activityList.value = res.data || []
}else{
activityList.value = []
}
}else{
activityList.value = []
uni.showToast({
title: err.msg,
icon: 'error',
duration: 1000
})
}
}catch{
uni.showToast({
title: err.msg,
icon: 'error',
duration: 1000
})
}
}
const onlineRepairClick = () =>{
uni.setStorageSync('sourcePage',"index")
uni.navigateTo({
url:'/pageSubPack/online-repair/onlineRepair'
})
}
// 访客邀请
const visitorClick = () =>{
uni.setStorageSync('sourcePage',"index")
uni.navigateTo({
url:"/pageSubPack/visitor/visitor-list"
})
}
// 活动列表的查看更多
const moreClick = () =>{
uni.setStorageSync('sourcePage',"index")
uni.navigateTo({
url:"/pageSubPack/activity-list/activityList"
})
}
</script>
<style lang="scss" scoped>
.content-class{
// margin: 0 20rpx;
// padding: 2rpx;
background-color: #f9f9f9;
padding-bottom: 100rpx;
box-sizing: border-box; /* 保证padding不会撑大容器 */
min-height: 110vh;
overflow-y: auto;
.nar-top{
height: 400rpx;
width: 100%;
// background-color: #C0E4FB;
background: repeating-linear-gradient(to right, #EDF4FA , #C0E4FB);
position: absolute;
}
.status_bar {
height: 46px;
width: 100%;
}
/* 导航栏 */
.nav-bar {
height: 44px;
line-height: 44px;
text-align: center;
}
.nav-title {
font-size: 14px;
font-weight: 400;
}
.header-container{
display: flex;
align-items: center;
justify-content: space-between;
padding: 4rpx 30rpx;
box-sizing: border-box;
// border-bottom: 1rpx solid #f0f0f0;
position:absolute;
top: 85px;
left: 0;
z-index: 9999;
}
// 左侧区域
.location-area {
display: flex;
align-items: center;
position: relative;
flex: 1;
min-width: 0;
.location-icon {
width: 45rpx;
height: 45rpx;
margin-right: 12rpx;
flex-shrink: 0;
}
.community-selector {
display: flex;
align-items: center;
max-width: 300rpx;
cursor: pointer;
.community-name {
font-size: 26rpx;
font-weight: 500;
color: #000;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 200rpx;
}
}
}
.bannarClass{
position: relative;
top: 110px;
left: 0;
padding: 40rpx;
}
.noticeClass{
position: relative;
top: 160rpx;
left: 0;
padding: 40rpx 36rpx;
}
// 修改通知栏样式
::v-deep .uni-noticebar__content-wrapper--scrollable{
left: 20px;
margin-right: 20px;
}
.noticeClass.uni-noticebar{
padding: 10px 15px 10px 45px;
}
.notice-bar::after {
color: #3E8EFF;
}
.bg-card-open{
position: relative;
top: 98rpx;
left: 0;
padding: 20rpx;
background-color: #fff;
border-radius: 8rpx;
margin: 20px 18px;
}
.openClass{
display: flex;
flex-direction: column;
align-items: center;
margin-top: 20rpx;
.iconClass{
width: 130rpx;
height: 130rpx;
border-radius: 10rpx;
// opacity: 0.4;
}
.title-dome-calss{
margin-top: 10rpx;
font-size: 13px;
color: #000;
}
}
.adCardClass{
// width: 100%;
height: 200rpx;
margin: 40rpx 30rpx;
background-color: #3E8EFF;
// margin-top: 30rpx;
border-radius: 28rpx;
position: relative;
top:45px;
left: 0;
.titleLeft{
text-align: left;
line-height: 2;
// margin-top: 32rpx;
// margin-left: 30rpx;
}
.iconRightClass{
width: 120rpx;
height: 120rpx;
border-radius: 50%;
// margin-top: 20rpx;
margin: 36rpx;
}
}
.activity-card{
position: relative;
top: 40px;
left: 0;
bottom: 20;
}
.uni-card{
margin: 18px !important;
}
.eventListClass{
margin: 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
}
.activity-name{
font-size: 16px;
font-weight: 600;
color: #222;
}
.eventListCard{
// min-height:200rpx ;
position: relative;
margin: 30rpx 0rpx;
// overflow: hidden;
.status-tag {
position: absolute;
top: 0;
left: 0;
// padding: 6px 18px;
padding: 0px 9px 10px 11px;
border-radius: 10px 0px 10px 0px;
font-size: 12px;
color: #fff;
font-weight: 500;
width: 80rpx;
height: 20rpx;
// background-color: #FD7373 ;
background: repeating-linear-gradient(to right, #FD7373 , #FB3F3F);
}
.activity-img{
width: 170rpx;
height: 230rpx;
// background-color: #333333;
}
.activity-title{
font-size: 16px;
font-weight: bold;
color: #333;
margin-bottom: 12px;
line-height: 1.4;
}
.activity-time,
.activity-organizer {
display: flex;
align-items: center;
font-size: 14px;
color: #999999;
margin-bottom: 8px;
}
.activity-enrollment{
display: flex;
align-items: center;
font-size: 15px;
margin-top: 20rpx;
color: #666666;
}
}
.look-more-title{
color: #3E8EFF;
font-size: 14px;
}
}
</style>