Files
property-resident-side/property-uniapp-project/pageSubPack/inspection-revenue/public-revenue.vue
2026-07-30 15:35:02 +08:00

253 lines
5.7 KiB
Vue

<template>
<view class="page">
<!-- <view class="status_bar" :style="{ height: statusBarHeight + 'px' }"></view>
<uni-nav-bar
left-icon="left"
title="公区收益"
background-color="#F9F9F9"
@clickLeft="narBack"
/> -->
<!-- 滚动区域 -->
<scroll-view
scroll-y
class="scroll-box"
:refresher-enabled="true"
:refresher-triggered="refreshing"
@refresherrefresh="onRefresh"
@scrolltolower="loadMore"
>
<view class="list-wrap">
<!-- 下拉刷新 -->
<view class="refresh" v-if="refreshing">
<uni-icons type="spinner-cycle" class="spin"/> 刷新中...
</view>
<!-- 列表 -->
<view
v-for="revenue in revenueList"
:key="revenue.noticeId"
class="item">
<view class="title-box">
<view class="title">{{ revenue.noticeTitle }}</view>
<view class="dot" v-if="revenue.readStatus === '0'"></view>
</view>
<view class="info">{{ revenue.publishTime }}</view>
<view class="content" v-html="revenue.noticeContent"></view>
<view class="detail" @click="goToDetail(revenue)">
<text style="color:#2F77FD;font-size: 24rpx;">详情</text>
<uni-icons type="right" size="13" color="#007AFF"/>
</view>
</view>
<!-- 加载中 / 无更多 / 空布局 -->
<view class="load-more" v-if="loadingMore">加载中...</view>
<view class="no-more" v-if="noMoreData && revenueList.length">没有更多通知了</view>
<view v-if="revenueList.length === 0 && !loading" class="empty-state">
<uni-icons type="info" size="30" color="#ccc"></uni-icons>
<text class="empty-text">暂无通知</text>
</view>
</view>
</scroll-view>
</view>
</template>
<script setup>
import { ref } from 'vue'
import { onLoad ,onShow,onUnload} from '@dcloudio/uni-app'
import { getRevenueList } from '../api/apiSub.js'
const revenueList = ref([])
const refreshing = ref(false)
const loadingMore = ref(false)
const noMoreData = ref(false)
const loading = ref(false)
const pageNum = ref(1)
const pageSize = 10
const isFirstShow = ref(true) // 详情返回列表刷新状态
const statusBarHeight = ref(uni.getSystemInfoSync().statusBarHeight || 0)
const goToDetail = (notice) => {
uni.navigateTo({
url: `/pageSubPack/inspection-revenue/public-revenue-details?id=${notice.noticeId}`
})
}
const loadRevenue = async (isRefresh = false) => {
if (loading.value) return
loading.value = true
if (isRefresh) {
pageNum.value = 1
noMoreData.value = false
}
try {
const res = await getRevenueList({ pageNum: pageNum.value, pageSize })
if (res.code === 200) {
const list = res.data.rows || []
revenueList.value = isRefresh ? list : [...revenueList.value, ...list]
if (list.length < pageSize) noMoreData.value = true
}
} catch (e) {}
finally {
loading.value = false
refreshing.value = false
loadingMore.value = false
}
}
// 更新单条已读状态
const updateReadStatus = ({ noticeId, readStatus }) => {
const item = revenueList.value.find(n => String(n.noticeId) === String(noticeId))
if (item) {
item.readStatus = readStatus
}
}
onShow(() =>{
if(isFirstShow.value) return
// loadRevenue(true)
})
const onRefresh = () => {
refreshing.value = true
// loadRevenue(true)
}
const loadMore = () => {
if (noMoreData.value || loadingMore.value) return
loadingMore.value = true
pageNum.value++
// loadRevenue()
}
const narBack = () => {
uni.switchTab({ url: '/pages/serviceIndex/serviceIndex' })
}
onLoad(() => {
isFirstShow.value = false
uni.$on('noticeRead',updateReadStatus)
loadRevenue(true)
})
onUnload(()=>{
uni.$off('noticeRead',updateReadStatus)
})
</script>
<style lang="scss">
page {
background: #f9f9f9;
}
.page {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
flex-direction: column;
}
.status_bar {
width: 100%;
flex-shrink: 0;
}
.scroll-box {
flex: 1;
height: 0; /* 让滚动区域生效 */
}
.list-wrap {
padding: 40rpx;
}
.item {
background: #fff;
border-radius: 12rpx;
padding: 30rpx;
margin-bottom: 20rpx;
}
.title-box {
display: flex;
justify-content: space-between;
align-items: center;
}
.title {
font-size: 32rpx;
font-weight: bold;
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dot {
width: 16rpx;
height: 16rpx;
background: red;
border-radius: 50%;
}
.info {
color: #999;
font-size: 24rpx;
margin: 10rpx 0;
}
.content {
color: #222;
font-size: 24rpx;
line-height: 1.5;
margin: 20rpx 0;
background-color: #f9f9f9;
padding: 24rpx;
word-break: break-all;
/* 按高度截断,避免 line-clamp 导致文字重叠 */
max-height: 160rpx;
overflow: hidden;
/* 富文本里的图片不超出屏幕 */
:deep(img),
:deep(image) {
max-width: 100% !important;
height: auto !important;
display: block;
}
}
.detail {
display: flex;
justify-content: space-between;
align-items: center;
}
.refresh, .load-more, .no-more {
text-align: center;
padding: 20rpx;
color: #999;
font-size: 24rpx;
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
color: #ccc;
}
.empty-text {
font-size: 28rpx;
color: #999;
margin-top: 20rpx;
margin-bottom: 10rpx;
}
.refresh-btn {
background: #007AFF;
color: #fff;
border-radius: 50rpx;
padding: 10rpx 30rpx;
margin-top: 20rpx;
}
.spin {
animation: rotate 1s linear infinite;
}
@keyframes rotate {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>