Files
property-manager-side/wuye-manager-uniapp/pages/index/index.vue
2026-07-20 14:16:46 +08:00

624 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="bg-gradient"></view>
<!-- 页面内容区 -->
<view class="page-content">
<!-- 粘性顶部区域(状态栏 + 导航栏 + 小区选择) -->
<view class="sticky-header">
<!-- 状态栏占位 -->
<view class="status_bar" :style="{ height: statusBarHeight + 'px' }"></view>
<!-- 导航栏 -->
<view class="nav-bar">
<text class="nav-title">首页</text>
</view>
<!-- 小区选择 -->
<view class="header-container" @click="navigateToPage">
<view class="location-area">
<view class="location-icon">
<image
src="https://wuyeadmin.bugtc.com/images/imgs/adress.png"
style="height: 100%; width: 100%"
></image>
</view>
<view class="community-selector">
<text class="community-name">{{ currentCommunity }}</text>
<view class="community-icon">
<image
src="https://wuyeadmin.bugtc.com/images/imgs/三角形.png"
style="height: 100%; width: 100%"
></image>
</view>
</view>
</view>
</view>
</view>
<!-- 可滚动内容区 -->
<view class="scroll-content">
<!-- banner -->
<view class="bannarClass" v-if="bannerList && bannerList.length > 0">
<up-swiper
:list="bannerList"
indicator
indicatorMode="dot"
radius="15"
height="180"
keyName="url"
>
<template #default="{ item, index }">
<image :src="item.url || item" mode="aspectFill" class="banner-img"></image>
</template>
</up-swiper>
</view>
<!-- 巡检 -->
<view class="inspectionClass">
<!-- 消息通知栏 -->
<view class="noticeClass">
<view class="notice-left">
<image
src="https://wuyeadmin.bugtc.com/images/imgs/notice.png"
class="notice-icon"
></image>
<view class="notice-line"></view>
</view>
<view class="notice-right" @click="getNoticeMore">
<uni-notice-bar
:text="noticeText"
type="line"
:showIcon="false"
show-get-more
scrollable
color="#fff"
background-color="transparent"
moreColor="#fff"
no-border
>
</uni-notice-bar>
</view>
</view>
<!-- 巡检数据统计区 -->
<view class="statistics-wrap">
<view class="statistics-item" @click="goToInspectionRecord">
<text class="num">{{ allCount }}</text>
<text class="label">全部巡检</text>
</view>
<view class="statistics-item" @click="goToDaysInspection">
<text class="num">{{ pendingCount }}</text>
<text class="label">待巡检</text>
</view>
<view class="statistics-item">
<text class="num">{{ InspectedCount }}</text>
<text class="label">已巡检</text>
</view>
</view>
</view>
<!-- 网格布局功能 -->
<view class="function-container">
<!-- 第一行功能:故障上报、一键开门、工单大厅、我的工单 -->
<view class="function-row">
<view class="function-item" @click="goToReport" v-if="hasPermi('butler:fault:report')">
<image
class="item-icon"
src="https://wuyeadmin.bugtc.com/images/imgs/fault-report.png"
mode="aspectFit"
></image>
<text class="item-text">故障上报</text>
</view>
<view
class="function-item"
@click="goToOneOpenDoor"
v-if="hasPermi('butler:door:open')"
>
<image
class="item-icon"
src="https://wuyeadmin.bugtc.com/images/imgs/open.png"
mode="aspectFit"
></image>
<text class="item-text">一键开门</text>
</view>
<view
class="function-item"
@tap="goToTicketHall"
v-if="hasPermi('butler:workOrder:hall')"
>
<image
class="item-icon"
src="https://wuyeadmin.bugtc.com/images/imgs/work-order.png"
mode="aspectFit"
></image>
<text class="item-text">工单大厅</text>
</view>
<view
class="function-item"
@tap="goToMyTicket"
v-if="hasPermi('butler:workOrder:mine')"
>
<image
class="item-icon"
src="https://wuyeadmin.bugtc.com/images/imgs/my-work.png"
mode="aspectFit"
></image>
<text class="item-text">我的工单</text>
</view>
</view>
<!-- 第二行 -->
<view class="function-row" style="margin-top: 2px">
<view
class="function-item"
@tap="goToComplaint"
v-if="hasPermi('butler:complaint:handle')"
>
<image
class="item-icon"
src="https://wuyeadmin.bugtc.com/images/imgs/complaint.png"
mode="aspectFit"
></image>
<text class="item-text">投诉处理</text>
</view>
<view
class="function-item"
@tap="goToReplacement_record"
v-if="hasPermi('butler:,meter:replace')"
>
<image
class="item-icon"
src="https://wuye.ckdzkj.com/images/home/updateDevice.png"
mode="aspectFit"
></image>
<text class="item-text">仪表换新</text>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
import { onLoad, onUnload, onShow } from '@dcloudio/uni-app'
import {
getCurrentVillage,
getTodayInspection,
getNewNoticeData,
getBannarList
} from '../../api/api.js'
import { hasPermi } from '../../utils/permissions.js'
// 列表数据状态
const currentCommunity = ref('请先绑定房屋')
const bannerList = ref([])
const noticeText = ref('暂无公告')
const allCount = ref(0) // 全部巡检
const pendingCount = ref(0) //待巡检
const InspectedCount = ref(0) //已巡检
const statusBarHeight = ref(uni.getSystemInfoSync().statusBarHeight || 0)
// =======方法=======
// 跳转小区
const navigateToPage = () => {
const curVillageId = uni.getStorageSync('currentVillage')
let villageId = ''
if (curVillageId) {
try {
villageId = JSON.parse(curVillageId).villageId || JSON.parse(curVillageId).id || ''
} catch (e) {}
}
uni.navigateTo({
url: `/pageSubPack/notice-list/select-community?villageId=${villageId}`
})
}
// 跳转公告
const getNoticeMore = () => {
uni.navigateTo({
url: '/pageSubPack/notice-list/notice-list'
})
}
// 跳转一键开门
const goToOneOpenDoor = () => {
uni.navigateTo({
url: '/pageSubPack/oneClickOpen/oneClickOpen'
})
}
// 工单大厅
const goToTicketHall = () => {
uni.navigateTo({
url: '/pageSubPack/ticket/hall'
})
}
// 我的工单
const goToMyTicket = () => {
uni.navigateTo({
url: '/pageSubPack/ticket/myticket'
})
}
// 跳转到 今日巡检
const goToDaysInspection = () => {
uni.navigateTo({
url: '/pageSubPack/inspection/toDays_inscpection?type=0'
})
}
// 跳转到 巡检记录
const goToInspectionRecord = () => {
uni.navigateTo({
url: '/pageSubPack/inspection/inspection_record'
})
}
// 跳转到 投诉处理
const goToComplaint = () => {
uni.navigateTo({
url: '/pageSubPack/complaint/Details'
})
}
// 故障上报
const goToReport = () => {
uni.navigateTo({
url: '/pageSubPack/fault-reporting/fault-reporting'
})
}
// 跳转到仪表换新
const goToReplacement_record = () => {
uni.navigateTo({
url: '/pageSubPack/instrument/replacement_record'
})
}
// 获取当前小区
const currentVillageData = () => {
// 先重置,避免新账号无小区时仍显示旧账号的小区
currentCommunity.value = '请先绑定房屋'
getCurrentVillage()
.then(res => {
const data = res.data
if (data) {
currentCommunity.value = data.villageName
uni.setStorageSync('currentVillage', JSON.stringify(data))
getNoticeData()
}
})
.catch(() => {})
}
// 获取今日巡检数据
const getInspectionData = () => {
getTodayInspection()
.then(res => {
if (res.code === 200) {
if (res.data) {
allCount.value = res.data.totalTasks
pendingCount.value = res.data.unfinishedTasks
InspectedCount.value = res.data.completedTasks
} else {
allCount.value = 0
pendingCount.value = 0
InspectedCount.value = 0
}
} else {
uni.showToast({ title: res.msg || '获取失败', icon: 'none' })
}
})
.catch(err => {
uni.showToast({ title: err.msg || '获取失败', icon: 'none' })
})
}
// 获取消息通知
const getNoticeData = () => {
getNewNoticeData()
.then(res => {
if (res.code === 200 && res.data) {
noticeText.value = res.data.notice || ''
} else {
noticeText.value = '暂无公告'
}
})
.catch(() => {})
}
// 获取bannar图
function getbannarData() {
getBannarList()
.then(res => {
if (res.code === 200 && res.data) {
// 只有数据真正变化时才更新,避免 swiper 重新渲染导致闪动
const newData = res.data
const oldData = bannerList.value
if (JSON.stringify(newData) !== JSON.stringify(oldData)) {
bannerList.value = newData
}
} else {
bannerList.value = []
}
})
.catch(() => {
bannerList.value = []
})
}
// 接收选择小区返回的参数
const slelctHomeData = data => {
currentCommunity.value = data.villageName
uni.setStorageSync('currentVillage', JSON.stringify(data))
getNoticeData()
getInspectionData()
}
onShow(() => {
getbannarData()
getInspectionData()
currentVillageData()
})
onLoad(() => {
uni.$on('confirm', slelctHomeData)
// 优先调用接口获取当前小区,失败时再读缓存
currentVillageData()
getInspectionData()
// getbannarData()
})
onUnload(() => {
uni.$off('confirm', slelctHomeData)
})
</script>
<style lang="scss" scoped>
.content-class {
background-color: #f9f9f9;
min-height: 100vh;
position: relative;
}
/* 顶部渐变背景 - 增加高度确保覆盖粘性头部区域 */
.bg-gradient {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 600rpx;
background: repeating-linear-gradient(to right, #edf4fa, #c0e4fb);
z-index: 0;
}
/* 页面内容容器 */
.page-content {
position: relative;
z-index: 1;
padding: 0 40rpx 40rpx;
}
/* 粘性头部区域 - 滚动时固定在顶部 */
.sticky-header {
position: sticky;
top: 0;
z-index: 100;
/* 与顶部渐变背景一致,保证滚动时视觉效果连贯 */
background: repeating-linear-gradient(to right, #edf4fa, #c0e4fb);
margin: 0 -40rpx; /* 抵消父容器内边距,使背景完全延伸 */
padding: 0 40rpx;
/* 可选:添加轻微阴影增强层次感 */
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.02);
}
.status_bar {
width: 100%;
}
/* 导航栏 */
.nav-bar {
height: 88rpx;
line-height: 88rpx;
text-align: center;
}
.nav-title {
font-size: 32rpx;
font-weight: 400;
}
.header-container {
display: flex;
align-items: center;
justify-content: space-between;
padding: 4rpx 0;
}
/* 左侧区域 */
.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;
}
.community-icon {
width: 20rpx;
height: 20rpx;
margin-left: 20rpx;
margin-top: -22rpx;
}
}
}
/* 可滚动内容区域 */
.scroll-content {
/* 确保内部元素正常布局 */
width: 100%;
}
.bannarClass {
padding: 20rpx 0;
}
.banner-img {
width: 100%;
height: 100%;
border-radius: 15rpx;
}
.inspectionClass {
background: linear-gradient(to right, #7b87fa, #4d5dfa);
border-radius: 16rpx;
box-sizing: border-box;
padding: 30rpx;
}
/* 消息通知栏 */
.noticeClass {
display: flex;
align-items: center;
height: 80rpx;
background: rgba(255, 255, 255, 0.1);
border-radius: 16rpx;
padding: 6rpx 20rpx;
margin-bottom: 30rpx;
border: 1rpx solid rgba(255, 255, 255, 0.1);
}
/* 左侧"消息通知"文字 */
.notice-left {
display: flex;
align-items: center;
margin-right: 16rpx;
.notice-icon {
width: 48rpx;
height: 48rpx;
margin-right: 15rpx;
}
.notice-line {
width: 1rpx;
height: 40rpx;
background-color: rgba(255, 255, 255, 0.4);
}
}
/* 右侧公告滚动区 */
.notice-right {
flex: 1;
}
/* 深度修改uni-notice-bar样式 */
:deep(.uni-noticebar) {
background-color: transparent !important;
height: 100% !important;
line-height: 80rpx !important;
padding: 0 !important;
margin: 0 !important;
}
/* 公告文字样式 */
:deep(.uni-noticebar__content) {
font-size: 26rpx !important;
color: #fff !important;
padding: 0 !important;
}
/* 右侧箭头按钮 */
:deep(.uni-noticebar__more) {
color: #fff !important;
font-size: 24rpx !important;
padding: 0 0 0 10rpx !important;
}
/* 隐藏默认滚动动画的多余样式 */
:deep(.uni-noticebar__content-wrapper--scrollable) {
left: 0 !important;
width: calc(100% - 30rpx) !important;
}
/* 统计区布局 */
.statistics-wrap {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20rpx;
}
/* 统计项样式 */
.statistics-item {
text-align: center;
}
.statistics-item .num {
font-size: 36rpx;
font-weight: bold;
color: #fff;
display: block;
line-height: 1;
margin-bottom: 10rpx;
}
.statistics-item .label {
font-size: 24rpx;
color: #fff;
opacity: 0.9;
}
.function-container {
background-color: #ffffff;
border-radius: 16rpx;
padding: 30rpx 0;
box-sizing: border-box;
margin-top: 20rpx;
}
/* 功能行布局 */
.function-row {
display: flex;
align-items: center;
margin-bottom: 20rpx;
&:last-child {
margin-bottom: 0;
}
}
.function-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 25%;
padding: 10rpx 0;
}
/* 功能图标样式 */
.item-icon {
width: 88rpx;
height: 88rpx;
margin-bottom: 10rpx;
}
/* 功能文字样式 */
.item-text {
font-size: 24rpx;
color: #333333;
font-weight: 400;
text-align: center;
}
</style>