feat: refresh mini program home and stats experience

This commit is contained in:
nepiedg
2026-04-01 23:53:28 +08:00
parent e92f1bdfae
commit 7282bbc373
8 changed files with 1220 additions and 512 deletions
+53 -12
View File
@@ -23,7 +23,7 @@
<text class="insight-glyph">{{ insightEmoji }}</text>
</view>
<view class="insight-content">
<text class="insight-title">每周洞察</text>
<text class="insight-title">阶段洞察</text>
<text class="insight-desc">{{ insightText }}</text>
</view>
</view>
@@ -33,23 +33,20 @@
<view class="card-header">
<view>
<text class="card-title">吸烟趋势</text>
<text class="card-sub">{{ trendRangeText }}</text>
</view>
<view class="status-chip" :class="statusChipClass">
<text class="status-arrow" :class="statusIconClass">{{ statusArrow }}</text>
<text class="status-text">{{ statusText }}</text>
<text class="card-sub">{{ weeklyTrendRangeText }}</text>
</view>
<view class="card-link" @tap="goCalendarDetail">日历详情</view>
</view>
<!-- 日均数据 -->
<view class="avg-row">
<text class="avg-value">{{ averageCount }}</text>
<text class="avg-value">{{ weeklyAverageCount }}</text>
<text class="avg-unit">/</text>
</view>
<!-- 日历格式趋势 -->
<view v-if="trendItems.length > 0" class="cal-grid">
<view v-for="(item, index) in trendItems" :key="index" class="cal-cell" :class="{ 'cal-cell-today': item.isHighlight }">
<view v-if="weeklyTrendItems.length > 0" class="cal-grid">
<view v-for="(item, index) in weeklyTrendItems" :key="index" class="cal-cell" :class="{ 'cal-cell-today': item.isHighlight }">
<text class="cal-weekday">{{ item.weekday }}</text>
<text class="cal-date">{{ item.date }}</text>
<view class="cal-dot" :class="calDotClass(item.count)">
@@ -164,7 +161,7 @@
<script setup>
import { ref, computed, onMounted, watch } from 'vue'
import { onShareAppMessage } from '@dcloudio/uni-app'
import { onShareAppMessage, onShow } from '@dcloudio/uni-app'
import { useLogin } from '@/hooks/useLogin'
import * as api from '@/api'
@@ -179,6 +176,7 @@ const tabs = [
const currentTab = ref('week')
const statsData = ref(null)
const weeklyStatsData = ref(null)
const WEEKDAY_NAMES = ['日', '一', '二', '三', '四', '五', '六']
@@ -217,6 +215,13 @@ const trendRangeText = computed(() => {
return formatRangeText(start, end)
})
const weeklyTrendRangeText = computed(() => {
const start = weeklyStatsData.value?.start
const end = weeklyStatsData.value?.end
if (!start || !end) return '固定展示最近 7 天'
return `${formatRangeText(start, end)} · 固定展示最近 7 天`
})
const statusText = computed(() => {
if (changePercent.value === null) return '暂无对比'
const sign = changePercent.value > 0 ? '+' : ''
@@ -244,8 +249,14 @@ const averageCount = computed(() => {
return Number(avg) || 0
})
const trendItems = computed(() => {
const trend = statsData.value?.trend
const weeklyAverageCount = computed(() => {
const avg = weeklyStatsData.value?.daily_average
if (avg === undefined || avg === null) return 0
return Number(avg) || 0
})
const weeklyTrendItems = computed(() => {
const trend = weeklyStatsData.value?.trend
if (!trend || !Array.isArray(trend) || trend.length === 0) return []
return trend.map((item, index) => {
const count = Number(item.count) || 0
@@ -425,11 +436,31 @@ async function fetchStats() {
}
}
async function fetchWeeklyStats() {
try {
await waitForLogin()
const res = await api.getStats({ range: 'week' })
weeklyStatsData.value = res.data
} catch (e) {
console.error('fetchWeeklyStats error:', e)
}
}
function goCalendarDetail() {
uni.navigateTo({ url: '/pages/stats-calendar/index' })
}
watch(currentTab, () => { fetchStats() })
onMounted(() => {
setupNavBar()
fetchStats()
fetchWeeklyStats()
})
onShow(() => {
fetchStats()
fetchWeeklyStats()
})
onShareAppMessage(() => {
@@ -558,6 +589,16 @@ onShareAppMessage(() => {
margin-bottom: 16rpx;
}
.card-link {
flex-shrink: 0;
padding: 8rpx 16rpx;
border-radius: 999rpx;
background: rgba(52, 200, 160, 0.08);
font-size: 22rpx;
font-weight: 600;
color: #1a8c62;
}
.card-title-row {
display: flex;
align-items: center;