refactor ui layout for home and stats
This commit is contained in:
+1
-1
@@ -21,7 +21,7 @@
|
|||||||
{
|
{
|
||||||
"path": "pages/stats/index",
|
"path": "pages/stats/index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "数据统计分析"
|
"navigationStyle": "custom"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
+504
-427
File diff suppressed because it is too large
Load Diff
+26
-13
@@ -3,7 +3,7 @@
|
|||||||
<view class="page-glow page-glow-a"></view>
|
<view class="page-glow page-glow-a"></view>
|
||||||
<view class="page-glow page-glow-b"></view>
|
<view class="page-glow page-glow-b"></view>
|
||||||
<view class="sticky-bar">
|
<view class="sticky-bar">
|
||||||
<view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
|
<view class="status-bar" :style="{ height: navBarHeight + 'px' }"></view>
|
||||||
<view class="page-head">
|
<view class="page-head">
|
||||||
<text class="page-eyebrow">Statistics</text>
|
<text class="page-eyebrow">Statistics</text>
|
||||||
<text class="page-title">数据统计</text>
|
<text class="page-title">数据统计</text>
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
<scroll-view v-if="trendItems.length > 0" scroll-x class="trend-chart-scroll" :show-scrollbar="false">
|
<scroll-view v-if="trendItems.length > 0" scroll-x class="trend-chart-scroll" :show-scrollbar="false">
|
||||||
<view class="trend-chart" :style="{ minWidth: trendChartMinWidth }">
|
<view class="trend-chart" :style="{ minWidth: trendChartMinWidth }">
|
||||||
<view v-for="(item, index) in trendItems" :key="index" class="trend-bar-item">
|
<view v-for="(item, index) in trendItems" :key="index" class="trend-bar-item">
|
||||||
<view v-if="item.isHighlight" class="trend-bubble">{{ item.count }}</view>
|
<view v-if="item.isHighlight && item.count > 0" class="trend-bubble">{{ item.count }}</view>
|
||||||
<view class="trend-bar-wrap">
|
<view class="trend-bar-wrap">
|
||||||
<view class="trend-bar" :style="{ height: item.height }"></view>
|
<view class="trend-bar" :style="{ height: item.height }"></view>
|
||||||
</view>
|
</view>
|
||||||
@@ -193,7 +193,7 @@ import { useLogin } from '@/hooks/useLogin'
|
|||||||
import * as api from '@/api'
|
import * as api from '@/api'
|
||||||
|
|
||||||
const { waitForLogin } = useLogin()
|
const { waitForLogin } = useLogin()
|
||||||
const statusBarHeight = ref(0)
|
const navBarHeight = ref(0)
|
||||||
|
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{ label: '周', value: 'week' },
|
{ label: '周', value: 'week' },
|
||||||
@@ -264,8 +264,8 @@ const statusIconClass = computed(() => {
|
|||||||
|
|
||||||
const averageCount = computed(() => {
|
const averageCount = computed(() => {
|
||||||
const avg = statsData.value?.daily_average
|
const avg = statsData.value?.daily_average
|
||||||
if (avg === undefined || avg === null) return 1
|
if (avg === undefined || avg === null) return 0
|
||||||
return avg
|
return Number(avg) || 0
|
||||||
})
|
})
|
||||||
|
|
||||||
// 图表仅使用接口返回的 trend 渲染,无数据时为空
|
// 图表仅使用接口返回的 trend 渲染,无数据时为空
|
||||||
@@ -275,10 +275,13 @@ const trendItems = computed(() => {
|
|||||||
if (!trend || !Array.isArray(trend) || trend.length === 0) {
|
if (!trend || !Array.isArray(trend) || trend.length === 0) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
const maxCount = Math.max(...trend.map(item => Number(item.count) || 0), 1)
|
const counts = trend.map(item => Number(item.count) || 0)
|
||||||
|
const maxCount = Math.max(...counts, 0)
|
||||||
return trend.map((item, index) => {
|
return trend.map((item, index) => {
|
||||||
const count = Number(item.count) || 0
|
const count = Number(item.count) || 0
|
||||||
const height = `${Math.max((count / maxCount) * 100, 6)}%`
|
const height = maxCount > 0
|
||||||
|
? `${Math.max((count / maxCount) * 100, count > 0 ? 6 : 0)}%`
|
||||||
|
: '0%'
|
||||||
return {
|
return {
|
||||||
label: formatTrendLabel(item.label, trendUnit),
|
label: formatTrendLabel(item.label, trendUnit),
|
||||||
count,
|
count,
|
||||||
@@ -485,6 +488,17 @@ function formatRangeText(start, end) {
|
|||||||
return `${startMonth}月${startDay}日-${endMonth}月${endDay}日`
|
return `${startMonth}月${startDay}日-${endMonth}月${endDay}日`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setupNavBar() {
|
||||||
|
const systemInfo = uni.getSystemInfoSync()
|
||||||
|
const statusBarH = systemInfo.statusBarHeight || 0
|
||||||
|
try {
|
||||||
|
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
||||||
|
navBarHeight.value = menuBtn.bottom + (menuBtn.top - statusBarH)
|
||||||
|
} catch (e) {
|
||||||
|
navBarHeight.value = statusBarH + 44
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function fetchStats() {
|
async function fetchStats() {
|
||||||
try {
|
try {
|
||||||
await waitForLogin()
|
await waitForLogin()
|
||||||
@@ -500,8 +514,7 @@ watch(currentTab, () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const sys = uni.getSystemInfoSync()
|
setupNavBar()
|
||||||
statusBarHeight.value = Math.max((sys.statusBarHeight || 0) - 20, 0)
|
|
||||||
fetchStats()
|
fetchStats()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -560,11 +573,13 @@ onShareAppMessage(() => {
|
|||||||
top: 0;
|
top: 0;
|
||||||
z-index: 20;
|
z-index: 20;
|
||||||
background: linear-gradient(180deg, rgba(237, 242, 248, 0.96) 0%, rgba(245, 247, 251, 0.92) 76%, rgba(251, 253, 255, 0) 100%);
|
background: linear-gradient(180deg, rgba(237, 242, 248, 0.96) 0%, rgba(245, 247, 251, 0.92) 76%, rgba(251, 253, 255, 0) 100%);
|
||||||
|
padding-left: 8rpx;
|
||||||
|
padding-right: 8rpx;
|
||||||
padding-bottom: 8rpx;
|
padding-bottom: 8rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-head {
|
.page-head {
|
||||||
padding: 18rpx 0 18rpx;
|
padding: 24rpx 14rpx 18rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-eyebrow {
|
.page-eyebrow {
|
||||||
@@ -599,7 +614,7 @@ onShareAppMessage(() => {
|
|||||||
padding: 6rpx;
|
padding: 6rpx;
|
||||||
border-radius: 24rpx;
|
border-radius: 24rpx;
|
||||||
gap: 6rpx;
|
gap: 6rpx;
|
||||||
margin-bottom: 16rpx;
|
margin: 0 6rpx 16rpx;
|
||||||
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
border: 2rpx solid rgba(255, 255, 255, 0.66);
|
||||||
box-shadow: 0 12rpx 28rpx rgba(15, 23, 42, 0.06);
|
box-shadow: 0 12rpx 28rpx rgba(15, 23, 42, 0.06);
|
||||||
backdrop-filter: blur(24rpx);
|
backdrop-filter: blur(24rpx);
|
||||||
@@ -1371,5 +1386,3 @@ onShareAppMessage(() => {
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user