收费总览页面
This commit is contained in:
@@ -4,6 +4,7 @@ import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
|
|||||||
let pushCIDRetryCount = 0
|
let pushCIDRetryCount = 0
|
||||||
const MAX_RETRY = 5
|
const MAX_RETRY = 5
|
||||||
let retryTimer = null
|
let retryTimer = null
|
||||||
|
let pushCIDFetching = false // 防止并发请求
|
||||||
|
|
||||||
// 应用启动时执行
|
// 应用启动时执行
|
||||||
onLaunch(() => {
|
onLaunch(() => {
|
||||||
@@ -13,27 +14,32 @@ onLaunch(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// #ifdef APP-PLUS
|
// #ifdef APP-PLUS
|
||||||
// 只有 App 平台才获取 CID,延迟 1 秒等推送服务就绪
|
// 延迟 2 秒等推送服务完全就绪后再获取 CID
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
getPushCID()
|
getPushCID()
|
||||||
}, 1000)
|
}, 2000)
|
||||||
// #endif
|
// #endif
|
||||||
})
|
})
|
||||||
|
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
console.log('App Show')
|
console.log('App Show')
|
||||||
// #ifdef APP-PLUS
|
// #ifdef APP-PLUS
|
||||||
// 每次回到前台都重新获取 CID,防止 CID 过期失效
|
// 从后台恢复时,如果 CID 已经获取过且未过期,不再重复请求
|
||||||
|
const existingCid = uni.getStorageSync('push_cid')
|
||||||
|
if (existingCid) {
|
||||||
|
console.log('已有缓存 CID,跳过重复获取')
|
||||||
|
return
|
||||||
|
}
|
||||||
pushCIDRetryCount = 0
|
pushCIDRetryCount = 0
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
refreshPushCID()
|
refreshPushCID()
|
||||||
}, 500)
|
}, 1000)
|
||||||
// #endif
|
// #endif
|
||||||
})
|
})
|
||||||
|
|
||||||
onHide(() => {
|
onHide(() => {
|
||||||
console.log('App Hide')
|
console.log('App Hide')
|
||||||
// 清除重试定时器,避免后台无效重试
|
pushCIDFetching = false
|
||||||
if (retryTimer) {
|
if (retryTimer) {
|
||||||
clearTimeout(retryTimer)
|
clearTimeout(retryTimer)
|
||||||
retryTimer = null
|
retryTimer = null
|
||||||
@@ -43,9 +49,12 @@ onHide(() => {
|
|||||||
|
|
||||||
// 刷新 CID(每次 onShow 调用,比对更新)
|
// 刷新 CID(每次 onShow 调用,比对更新)
|
||||||
function refreshPushCID() {
|
function refreshPushCID() {
|
||||||
|
if (pushCIDFetching) return
|
||||||
const oldCid = uni.getStorageSync('push_cid') || ''
|
const oldCid = uni.getStorageSync('push_cid') || ''
|
||||||
|
pushCIDFetching = true
|
||||||
uni.getPushClientId({
|
uni.getPushClientId({
|
||||||
success: res => {
|
success: res => {
|
||||||
|
pushCIDFetching = false
|
||||||
const newCid = res.cid
|
const newCid = res.cid
|
||||||
if (!newCid) {
|
if (!newCid) {
|
||||||
console.warn('获取到的 CID 为空,视为失败')
|
console.warn('获取到的 CID 为空,视为失败')
|
||||||
@@ -62,6 +71,7 @@ function refreshPushCID() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
fail: err => {
|
fail: err => {
|
||||||
|
pushCIDFetching = false
|
||||||
console.error('获取推送 CID 失败', err)
|
console.error('获取推送 CID 失败', err)
|
||||||
scheduleRetry()
|
scheduleRetry()
|
||||||
}
|
}
|
||||||
@@ -70,8 +80,11 @@ function refreshPushCID() {
|
|||||||
|
|
||||||
// 启动时首次获取 CID(重试更积极)
|
// 启动时首次获取 CID(重试更积极)
|
||||||
function getPushCID() {
|
function getPushCID() {
|
||||||
|
if (pushCIDFetching) return
|
||||||
|
pushCIDFetching = true
|
||||||
uni.getPushClientId({
|
uni.getPushClientId({
|
||||||
success: res => {
|
success: res => {
|
||||||
|
pushCIDFetching = false
|
||||||
const cid = res.cid
|
const cid = res.cid
|
||||||
if (!cid) {
|
if (!cid) {
|
||||||
console.warn('获取到的 CID 为空,视为失败')
|
console.warn('获取到的 CID 为空,视为失败')
|
||||||
@@ -84,6 +97,7 @@ function getPushCID() {
|
|||||||
// TODO: 将 CID 上报到服务器
|
// TODO: 将 CID 上报到服务器
|
||||||
},
|
},
|
||||||
fail: err => {
|
fail: err => {
|
||||||
|
pushCIDFetching = false
|
||||||
console.error('获取推送 CID 失败', err)
|
console.error('获取推送 CID 失败', err)
|
||||||
scheduleRetry()
|
scheduleRetry()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export default function request(url, data = {}, method = 'GET') {
|
|||||||
url: baseUrl + url,
|
url: baseUrl + url,
|
||||||
data: data,
|
data: data,
|
||||||
method: method,
|
method: method,
|
||||||
|
timeout: 15000,
|
||||||
header: {
|
header: {
|
||||||
Authorization: 'Bearer ' + (uni.getStorageSync('token') || ''),
|
Authorization: 'Bearer ' + (uni.getStorageSync('token') || ''),
|
||||||
clientid: 'butler',
|
clientid: 'butler',
|
||||||
|
|||||||
@@ -24,3 +24,11 @@ export const getFeeSummary = data => {
|
|||||||
export const getParkingFee = data => {
|
export const getParkingFee = data => {
|
||||||
return get('/api/butler/feeOverview/parking', data)
|
return get('/api/butler/feeOverview/parking', data)
|
||||||
}
|
}
|
||||||
|
// 押金余额统计
|
||||||
|
export const getDepositBalance = data => {
|
||||||
|
return get('/api/butler/feeOverview/depositBalance', data)
|
||||||
|
}
|
||||||
|
// 巡检总览
|
||||||
|
export const getInspection = data => {
|
||||||
|
return get('/api/butler/feeOverview/inspection', data)
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
"nvueStyleCompiler" : "uni-app",
|
"nvueStyleCompiler" : "uni-app",
|
||||||
"compilerVersion" : 3,
|
"compilerVersion" : 3,
|
||||||
"splashscreen" : {
|
"splashscreen" : {
|
||||||
"alwaysShowBeforeRender" : true,
|
"alwaysShowBeforeRender" : false,
|
||||||
"waiting" : true,
|
"waiting" : true,
|
||||||
"autoclose" : true,
|
"autoclose" : true,
|
||||||
"delay" : 0,
|
"delay" : 0,
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="setting-container">
|
<view class="setting-container">
|
||||||
<view class="status_bar"></view>
|
<!-- <view class="status_bar"></view> -->
|
||||||
<!-- 顶部导航栏 -->
|
<!-- 顶部导航栏 -->
|
||||||
<view class="nav-bar">
|
<!-- <view class="nav-bar">
|
||||||
<view class="nav-left" @tap="goBack">
|
<view class="nav-left" @tap="goBack">
|
||||||
<uni-icons type="left" size="22" color="#000"></uni-icons>
|
<uni-icons type="left" size="22" color="#000"></uni-icons>
|
||||||
</view>
|
</view>
|
||||||
<view class="nav-title">设置</view>
|
<view class="nav-title">设置</view>
|
||||||
<view class="nav-right"></view>
|
<view class="nav-right"></view>
|
||||||
</view>
|
</view> -->
|
||||||
|
|
||||||
<!-- 内容区域 -->
|
<!-- 内容区域 -->
|
||||||
<scroll-view class="content" scroll-y="true">
|
<scroll-view class="content" scroll-y="true">
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="deposit-chart">
|
<view class="deposit-chart">
|
||||||
<qiun-data-charts type="column" :chartData="depositColumnData" :opts="depositColumnOpts" />
|
<qiun-data-charts type="column" :chartData="depositColumnData" :opts="depositColumnOpts" />
|
||||||
|
<view class="deposit-empty-mask" v-if="depositItems.length === 0">
|
||||||
|
<text class="empty-text">暂无数据</text>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
@@ -15,16 +18,17 @@ import { computed } from 'vue'
|
|||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
depositBalance: { type: String, default: '0' },
|
depositBalance: { type: String, default: '0' },
|
||||||
depositRenovation: { type: Number, default: 0 },
|
depositItems: { type: Array, default: () => [] }
|
||||||
depositRental: { type: Number, default: 0 }
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const depositColumnData = computed(() => ({
|
const depositColumnData = computed(() => {
|
||||||
categories: ['装修押金', '租赁押金'],
|
const categories = props.depositItems.map(item => item.typeName)
|
||||||
series: [
|
const data = props.depositItems.map(item => (item.balance / 10000))
|
||||||
{ name: '余额', data: [props.depositRenovation, props.depositRental] }
|
return {
|
||||||
]
|
categories,
|
||||||
}))
|
series: [{ name: '余额', data }]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const depositColumnOpts = computed(() => ({
|
const depositColumnOpts = computed(() => ({
|
||||||
color: ['#4D5DFA'],
|
color: ['#4D5DFA'],
|
||||||
@@ -34,22 +38,24 @@ const depositColumnOpts = computed(() => ({
|
|||||||
xAxis: {
|
xAxis: {
|
||||||
disableGrid: true,
|
disableGrid: true,
|
||||||
axisLineColor: '#EAEAEA',
|
axisLineColor: '#EAEAEA',
|
||||||
|
dashLength: 4,
|
||||||
fontColor: '#666',
|
fontColor: '#666',
|
||||||
fontSize: 12
|
fontSize: 12
|
||||||
},
|
},
|
||||||
yAxis: {
|
yAxis: {
|
||||||
|
showTitle: true,
|
||||||
data: [{
|
data: [{
|
||||||
title: '万元',
|
title: '金额(万)',
|
||||||
min: 0,
|
min: 0,
|
||||||
max: 80,
|
|
||||||
axisLineColor: '#EAEAEA',
|
axisLineColor: '#EAEAEA',
|
||||||
fontColor: '#666',
|
fontColor: '#666',
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
titleFontSize: 12,
|
titleFontSize: 12,
|
||||||
titleFontColor: '#666'
|
titleFontColor: '#666'
|
||||||
}],
|
}],
|
||||||
splitLine: { show: true, lineStyle: { color: '#F2F2F2' } },
|
gridType: 'dash',
|
||||||
calibration: { step: 0.5 }
|
dashLength: 4,
|
||||||
|
gridColor: '#F2F2F2',
|
||||||
},
|
},
|
||||||
extra: {
|
extra: {
|
||||||
column: {
|
column: {
|
||||||
@@ -88,6 +94,16 @@ const depositColumnOpts = computed(() => ({
|
|||||||
.deposit-chart {
|
.deposit-chart {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 420rpx;
|
height: 420rpx;
|
||||||
|
position: relative;
|
||||||
|
.deposit-empty-mask {
|
||||||
|
position: absolute;
|
||||||
|
top: 0; left: 0; right: 0; bottom: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: #fff;
|
||||||
|
.empty-text { font-size: 26rpx; color: #999; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -58,8 +58,7 @@
|
|||||||
<!-- 押金余额统计 -->
|
<!-- 押金余额统计 -->
|
||||||
<DepositCard
|
<DepositCard
|
||||||
:deposit-balance="depositBalance"
|
:deposit-balance="depositBalance"
|
||||||
:deposit-renovation="depositRenovation"
|
:deposit-items="depositItems"
|
||||||
:deposit-rental="depositRental"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 巡检总览 -->
|
<!-- 巡检总览 -->
|
||||||
@@ -77,7 +76,7 @@ import FeeOverviewCard from './components/FeeOverviewCard.vue'
|
|||||||
import ParkingFeeCard from './components/ParkingFeeCard.vue'
|
import ParkingFeeCard from './components/ParkingFeeCard.vue'
|
||||||
import DepositCard from './components/DepositCard.vue'
|
import DepositCard from './components/DepositCard.vue'
|
||||||
import InspectionOverview from './components/InspectionOverview.vue'
|
import InspectionOverview from './components/InspectionOverview.vue'
|
||||||
import { getManagedArea, getRate, getFeeSummary, getParkingFee } from '@/api/statisticsApi.js'
|
import { getManagedArea, getRate, getFeeSummary, getParkingFee, getDepositBalance, getInspection } from '@/api/statisticsApi.js'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -109,16 +108,15 @@ const parkingYearReceived = ref(0)
|
|||||||
const parkingArcbarPercent = ref(0)
|
const parkingArcbarPercent = ref(0)
|
||||||
|
|
||||||
// 押金余额统计
|
// 押金余额统计
|
||||||
const depositBalance = ref('33322')
|
const depositBalance = ref('0')
|
||||||
const depositRenovation = ref(18)
|
const depositItems = ref([])
|
||||||
const depositRental = ref(23)
|
|
||||||
|
|
||||||
// 巡检总览
|
// 巡检总览
|
||||||
const inspectionList = ref([
|
const inspectionList = ref([
|
||||||
{ label: '巡检任务', value: 124, icon: 'https://wuye.ckdzkj.com/images/imgs/inspection-task.png' },
|
{ label: '巡检任务', value: 0, icon: 'https://wuye.ckdzkj.com/images/imgs/inspection-task.png' },
|
||||||
{ label: '已完成', value: 98, icon: 'https://wuye.ckdzkj.com/images/imgs/inspection-done.png' },
|
{ label: '已完成', value: 0, icon: 'https://wuye.ckdzkj.com/images/imgs/inspection-done.png' },
|
||||||
{ label: '已过期', value: 12, icon: 'https://wuye.ckdzkj.com/images/imgs/inspection-expire.png' },
|
{ label: '已过期', value: 0, icon: 'https://wuye.ckdzkj.com/images/imgs/inspection-expire.png' },
|
||||||
{ label: '待处理', value: 14, icon: 'https://wuye.ckdzkj.com/images/imgs/inspection-pending.png' }
|
{ label: '待处理', value: 0, icon: 'https://wuye.ckdzkj.com/images/imgs/inspection-pending.png' }
|
||||||
])
|
])
|
||||||
|
|
||||||
const switchTab = (tab) => {
|
const switchTab = (tab) => {
|
||||||
@@ -134,6 +132,8 @@ const onProjectChange = (e) => {
|
|||||||
fetchRate(opt.value)
|
fetchRate(opt.value)
|
||||||
fetchFeeSummary()
|
fetchFeeSummary()
|
||||||
fetchParkingFee(opt.value)
|
fetchParkingFee(opt.value)
|
||||||
|
fetchDepositBalance(opt.value)
|
||||||
|
fetchInspection(opt.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onFeeTypeChange = (opt) => {
|
const onFeeTypeChange = (opt) => {
|
||||||
@@ -169,19 +169,20 @@ const fetchRate = (villageId) => {
|
|||||||
}
|
}
|
||||||
}).catch(() => {})
|
}).catch(() => {})
|
||||||
}
|
}
|
||||||
|
// 车位收费总览
|
||||||
const fetchParkingFee = (villageId) => {
|
const fetchParkingFee = (villageId) => {
|
||||||
getParkingFee({ villageId: villageId || '' }).then(res => {
|
getParkingFee({ villageId: villageId || '' }).then(res => {
|
||||||
if (res.code === 200 && res.data) {
|
if (res.code === 200 && res.data) {
|
||||||
const d = res.data
|
const d = res.data
|
||||||
parkingCount.value = d.parkingCount || 0
|
parkingCount.value = Number(d.parkingCount) || 0
|
||||||
parkingYearReceivable.value = d.receivableAmount || 0
|
parkingYearReceivable.value = Number(d.receivableAmount) || 0
|
||||||
parkingYearReceived.value = d.receivedAmount || 0
|
parkingYearReceived.value = Number(d.receivedAmount) || 0
|
||||||
parkingArcbarPercent.value = d.receivedPercent != null ? d.receivedPercent / 100 : 0
|
parkingArcbarPercent.value = d.receivedPercent != null ? Number(d.receivedPercent) / 100 : 0
|
||||||
}
|
}
|
||||||
}).catch(() => {})
|
}).catch(() => {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 收费总览
|
||||||
const fetchFeeSummary = () => {
|
const fetchFeeSummary = () => {
|
||||||
getFeeSummary({
|
getFeeSummary({
|
||||||
villageId: selectedProject.value || '',
|
villageId: selectedProject.value || '',
|
||||||
@@ -190,19 +191,21 @@ const fetchFeeSummary = () => {
|
|||||||
}).then(res => {
|
}).then(res => {
|
||||||
if (res.code === 200 && res.data) {
|
if (res.code === 200 && res.data) {
|
||||||
const d = res.data
|
const d = res.data
|
||||||
arcbarPercent.value = d.receivedPercent != null ? d.receivedPercent / 100 : 0
|
arcbarPercent.value = Number(d.receivedPercent) || 0
|
||||||
metricList.value = [
|
metricList.value = [
|
||||||
{ label: '应收总额', value: d.receivableAmount != null ? d.receivableAmount.toFixed(2) : '0.00', yoy: formatRate(d.receivableYoyRate), mom: formatRate(d.receivableMomRate) },
|
{ label: '应收总额', value: (Number(d.receivableAmount) || 0).toFixed(2), yoy: formatRate(d.receivableYoyRate), mom: formatRate(d.receivableMomRate) },
|
||||||
{ label: '实收总额', value: d.receivedAmount != null ? d.receivedAmount.toFixed(2) : '0.00', yoy: formatRate(d.receivedYoyRate), mom: formatRate(d.receivedMomRate) },
|
{ label: '实收总额', value: (Number(d.receivedAmount) || 0).toFixed(2), yoy: formatRate(d.receivedYoyRate), mom: formatRate(d.receivedMomRate) },
|
||||||
{ label: '欠收总额', value: d.unpaidAmount != null ? d.unpaidAmount.toFixed(2) : '0.00', yoy: formatRate(d.unpaidYoyRate), mom: formatRate(d.unpaidMomRate) }
|
{ label: '欠收总额', value: (Number(d.unpaidAmount) || 0).toFixed(2), yoy: formatRate(d.unpaidYoyRate), mom: formatRate(d.unpaidMomRate) }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}).catch(() => {})
|
}).catch(() => {})
|
||||||
}
|
}
|
||||||
|
|
||||||
const formatRate = (val) => {
|
const formatRate = (val) => {
|
||||||
if (val == null) return '-'
|
if (val == null || val === '') return '-'
|
||||||
return (val >= 0 ? '+' : '') + val.toFixed(2) + '%'
|
const num = Number(val)
|
||||||
|
if (isNaN(num)) return '-'
|
||||||
|
return (num >= 0 ? '+' : '') + num.toFixed(2) + '%'
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchFeeTypes = () => {
|
const fetchFeeTypes = () => {
|
||||||
@@ -214,6 +217,30 @@ const fetchFeeTypes = () => {
|
|||||||
}
|
}
|
||||||
}).catch(() => {})
|
}).catch(() => {})
|
||||||
}
|
}
|
||||||
|
// 押金余额统计
|
||||||
|
const fetchDepositBalance = (villageId) => {
|
||||||
|
getDepositBalance({ villageId: villageId}).then(res => {
|
||||||
|
if (res.code === 200 && res.data) {
|
||||||
|
const d = res.data
|
||||||
|
depositBalance.value = d.totalBalance
|
||||||
|
depositItems.value = d.items || []
|
||||||
|
}
|
||||||
|
}).catch(() => {})
|
||||||
|
}
|
||||||
|
// 巡检总览
|
||||||
|
const fetchInspection = (villageId) => {
|
||||||
|
getInspection({ villageId: villageId || '' }).then(res => {
|
||||||
|
if (res.code === 200 && res.data) {
|
||||||
|
const d = res.data
|
||||||
|
inspectionList.value = [
|
||||||
|
{ label: '巡检任务', value: d.taskCount || 0, icon: 'https://wuye.ckdzkj.com/images/imgs/inspection-task.png' },
|
||||||
|
{ label: '已完成', value: d.completedCount || 0, icon: 'https://wuye.ckdzkj.com/images/imgs/inspection-done.png' },
|
||||||
|
{ label: '已过期', value: d.expiredCount || 0, icon: 'https://wuye.ckdzkj.com/images/imgs/inspection-expire.png' },
|
||||||
|
{ label: '待处理', value: d.pendingCount || 0, icon: 'https://wuye.ckdzkj.com/images/imgs/inspection-pending.png' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}).catch(() => {})
|
||||||
|
}
|
||||||
|
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
Promise.all([fetchVillageList(), fetchFeeTypes()]).then(() => {
|
Promise.all([fetchVillageList(), fetchFeeTypes()]).then(() => {
|
||||||
@@ -221,6 +248,8 @@ onShow(() => {
|
|||||||
fetchRate(selectedProject.value)
|
fetchRate(selectedProject.value)
|
||||||
fetchFeeSummary()
|
fetchFeeSummary()
|
||||||
fetchParkingFee(selectedProject.value)
|
fetchParkingFee(selectedProject.value)
|
||||||
|
fetchDepositBalance(selectedProject.value)
|
||||||
|
fetchInspection(selectedProject.value)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -262,8 +262,7 @@
|
|||||||
"pages": [{
|
"pages": [{
|
||||||
"path": "setting",
|
"path": "setting",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "设置",
|
"navigationBarTitleText": "设置"
|
||||||
"navigationStyle": "custom"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -136,6 +136,13 @@ import { usePermStore } from '@/stores/usePermStore'
|
|||||||
|
|
||||||
const permStore = usePermStore()
|
const permStore = usePermStore()
|
||||||
|
|
||||||
|
// 首次加载标记:onLoad 和 onShow 在首次进入时都会触发,用此标记避免重复请求
|
||||||
|
const hasInit = ref(false)
|
||||||
|
|
||||||
|
// banner 缓存 key 和缓存时长(30分钟)
|
||||||
|
const BANNER_CACHE_KEY = 'home_banner_cache'
|
||||||
|
const BANNER_CACHE_TIME = 30 * 60 * 1000
|
||||||
|
|
||||||
// 列表数据状态
|
// 列表数据状态
|
||||||
const currentCommunity = ref('请先绑定房屋')
|
const currentCommunity = ref('请先绑定房屋')
|
||||||
const bannerList = ref([])
|
const bannerList = ref([])
|
||||||
@@ -342,17 +349,34 @@ const getNoticeData = () => {
|
|||||||
})
|
})
|
||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
}
|
}
|
||||||
// 获取bannar图
|
// 获取bannar图(带缓存:30分钟内优先用缓存,请求成功后更新缓存)
|
||||||
function getbannarData() {
|
function getbannarData(forceRefresh = false) {
|
||||||
|
// 非强制刷新时,优先读缓存
|
||||||
|
if (!forceRefresh) {
|
||||||
|
try {
|
||||||
|
const cached = uni.getStorageSync(BANNER_CACHE_KEY)
|
||||||
|
if (cached) {
|
||||||
|
const { data, time } = JSON.parse(cached)
|
||||||
|
if (data && data.length > 0 && Date.now() - time < BANNER_CACHE_TIME) {
|
||||||
|
bannerList.value = data
|
||||||
|
return // 缓存有效,不发起请求
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
getBannarList()
|
getBannarList()
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (res.code === 200 && res.data) {
|
if (res.code === 200 && res.data) {
|
||||||
// 只有数据真正变化时才更新,避免 swiper 重新渲染导致闪动
|
|
||||||
const newData = res.data
|
const newData = res.data
|
||||||
const oldData = bannerList.value
|
const oldData = bannerList.value
|
||||||
if (JSON.stringify(newData) !== JSON.stringify(oldData)) {
|
if (JSON.stringify(newData) !== JSON.stringify(oldData)) {
|
||||||
bannerList.value = newData
|
bannerList.value = newData
|
||||||
}
|
}
|
||||||
|
// 写入缓存
|
||||||
|
uni.setStorageSync(BANNER_CACHE_KEY, JSON.stringify({
|
||||||
|
data: newData,
|
||||||
|
time: Date.now()
|
||||||
|
}))
|
||||||
} else {
|
} else {
|
||||||
bannerList.value = []
|
bannerList.value = []
|
||||||
}
|
}
|
||||||
@@ -386,21 +410,26 @@ const slelctHomeData = data => {
|
|||||||
getInspectionData()
|
getInspectionData()
|
||||||
}
|
}
|
||||||
|
|
||||||
const permissionlist = ref([])
|
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
|
if (!hasInit.value) {
|
||||||
|
// 首次加载:onLoad 已触发过核心数据请求,这里只补 onLoad 没调的和需要每次都刷新的
|
||||||
|
hasInit.value = true
|
||||||
|
getbannarData() // onLoad 没调 banner
|
||||||
|
getMyOrderNum() // onLoad 没调工单数
|
||||||
|
permStore.initPerm() // 刷新权限缓存
|
||||||
|
// currentVillageData 和 getInspectionData 已在 onLoad 中调用,不再重复
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 从其他页面返回 / 从后台恢复:只刷新可能变化的数据
|
||||||
getbannarData()
|
getbannarData()
|
||||||
getInspectionData()
|
|
||||||
currentVillageData()
|
|
||||||
getMyOrderNum()
|
getMyOrderNum()
|
||||||
permStore.initPerm()
|
// 小区和巡检数据不频繁变化,从后台恢复时用缓存/旧数据,减少请求
|
||||||
})
|
})
|
||||||
|
|
||||||
onLoad(() => {
|
onLoad(() => {
|
||||||
uni.$on('confirm', slelctHomeData)
|
uni.$on('confirm', slelctHomeData)
|
||||||
// 优先调用接口获取当前小区,失败时再读缓存
|
|
||||||
currentVillageData()
|
currentVillageData()
|
||||||
getInspectionData()
|
getInspectionData()
|
||||||
// getbannarData()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnload(() => {
|
onUnload(() => {
|
||||||
|
|||||||
@@ -76,11 +76,7 @@ const onItemClick = item => {
|
|||||||
}
|
}
|
||||||
const url = routes[item.title]
|
const url = routes[item.title]
|
||||||
if (!url) return
|
if (!url) return
|
||||||
if (item.title === '设置') {
|
uni.navigateTo({ url })
|
||||||
uni.redirectTo({ url })
|
|
||||||
} else {
|
|
||||||
uni.navigateTo({ url })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -869,7 +869,9 @@ export default {
|
|||||||
const ctx = cfu.option[cid].context;
|
const ctx = cfu.option[cid].context;
|
||||||
if(typeof ctx === "object" && !!!cfu.option[cid].update){
|
if(typeof ctx === "object" && !!!cfu.option[cid].update){
|
||||||
ctx.clearRect(0, 0, this.cWidth*this.pixel, this.cHeight*this.pixel);
|
ctx.clearRect(0, 0, this.cWidth*this.pixel, this.cHeight*this.pixel);
|
||||||
ctx.draw();
|
if (typeof ctx.draw === 'function') {
|
||||||
|
ctx.draw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4643,9 +4643,13 @@ function drawXAxis(categories, opts, config, context) {
|
|||||||
context.beginPath();
|
context.beginPath();
|
||||||
context.setStrokeStyle(opts.xAxis.axisLineColor);
|
context.setStrokeStyle(opts.xAxis.axisLineColor);
|
||||||
context.setLineWidth(1 * opts.pix);
|
context.setLineWidth(1 * opts.pix);
|
||||||
|
if (opts.xAxis.dashLength) {
|
||||||
|
context.setLineDash([opts.xAxis.dashLength * opts.pix, opts.xAxis.dashLength * opts.pix]);
|
||||||
|
}
|
||||||
context.moveTo(startX, opts.height - opts.area[2]);
|
context.moveTo(startX, opts.height - opts.area[2]);
|
||||||
context.lineTo(endX, opts.height - opts.area[2]);
|
context.lineTo(endX, opts.height - opts.area[2]);
|
||||||
context.stroke();
|
context.stroke();
|
||||||
|
context.setLineDash([]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5834,7 +5838,9 @@ function drawMapDataPoints(series, opts, config, context) {
|
|||||||
mercator: mapOption.mercator
|
mercator: mapOption.mercator
|
||||||
}
|
}
|
||||||
drawToolTipBridge(opts, config, context, 1);
|
drawToolTipBridge(opts, config, context, 1);
|
||||||
context.draw();
|
if (typeof context.draw === 'function') {
|
||||||
|
context.draw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalInt(min, max, iter) {
|
function normalInt(min, max, iter) {
|
||||||
@@ -6305,7 +6311,9 @@ function drawCanvas(opts, context) {
|
|||||||
context.save();
|
context.save();
|
||||||
context.translate(0, 0.5);
|
context.translate(0, 0.5);
|
||||||
context.restore();
|
context.restore();
|
||||||
context.draw();
|
if (typeof context.draw === 'function') {
|
||||||
|
context.draw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var Timing = {
|
var Timing = {
|
||||||
|
|||||||
Reference in New Issue
Block a user