优化记录页趋势分析展示
This commit is contained in:
@@ -29,8 +29,12 @@ Page({
|
||||
monthRecords: [],
|
||||
historyList: [],
|
||||
listMode: 'month',
|
||||
contentMode: 'records',
|
||||
trendMode: 'week',
|
||||
trendData: [],
|
||||
trendSummary: {},
|
||||
bestTrendData: [],
|
||||
bestTrendSummary: {},
|
||||
showDayDetail: false,
|
||||
dayDetail: {},
|
||||
icons: iconsMod.build()
|
||||
@@ -61,7 +65,7 @@ Page({
|
||||
},
|
||||
|
||||
refresh() {
|
||||
storage.validateStreak()
|
||||
const streak = storage.validateStreak()
|
||||
const stats = storage.getTotalStats()
|
||||
const monthKey = `${this.data.currentYear}-${String(this.data.currentMonth).padStart(2, '0')}`
|
||||
const records = (storage.getRecordsByMonth(monthKey) || []).map(r => ({ ...r, durationText: util.formatTime(r.duration) }))
|
||||
@@ -103,6 +107,9 @@ Page({
|
||||
: `还差 ${badgeDefs[nextIdx].days - totalDays} 天解锁「${badgeDefs[nextIdx].name}」`
|
||||
|
||||
const theme = themeMod.getCurrentTheme()
|
||||
const trendMode = this.data.trendMode || 'week'
|
||||
const trendData = this._computeTrend(trendMode)
|
||||
const bestTrendData = this._computeBestTrend(trendMode)
|
||||
this.setData({
|
||||
theme,
|
||||
icons: iconsMod.build(theme),
|
||||
@@ -119,7 +126,10 @@ Page({
|
||||
historyList,
|
||||
listMode: this.data.listMode || 'month',
|
||||
displayList: (this.data.listMode || 'month') === 'month' ? records : historyList,
|
||||
trendData: this._computeTrend(this.data.trendMode || 'week'),
|
||||
trendData,
|
||||
trendSummary: { ...util.getTrendSummary(trendData, trendMode), streakCount: Number(streak.count) || 0 },
|
||||
bestTrendData,
|
||||
bestTrendSummary: util.getTrendSummary(bestTrendData, trendMode),
|
||||
loading: false
|
||||
})
|
||||
},
|
||||
@@ -155,10 +165,24 @@ Page({
|
||||
this.refresh()
|
||||
},
|
||||
|
||||
onToggleContentMode(e) {
|
||||
const mode = e.currentTarget.dataset.mode
|
||||
if (!['records', 'trend'].includes(mode) || mode === this.data.contentMode) return
|
||||
this.setData({ contentMode: mode })
|
||||
},
|
||||
|
||||
onToggleTrendMode(e) {
|
||||
const mode = e.currentTarget.dataset.mode
|
||||
if (!mode || mode === this.data.trendMode) return
|
||||
this.setData({ trendMode: mode, trendData: this._computeTrend(mode) })
|
||||
const trendData = this._computeTrend(mode)
|
||||
const bestTrendData = this._computeBestTrend(mode)
|
||||
this.setData({
|
||||
trendMode: mode,
|
||||
trendData,
|
||||
trendSummary: { ...util.getTrendSummary(trendData, mode), streakCount: Number(storage.getStreak().count) || 0 },
|
||||
bestTrendData,
|
||||
bestTrendSummary: util.getTrendSummary(bestTrendData, mode)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -171,6 +195,10 @@ Page({
|
||||
return util.getTrendData(storage.getRecords(), mode)
|
||||
},
|
||||
|
||||
_computeBestTrend(mode) {
|
||||
return util.getBestTrendData(storage.getRecords(), mode)
|
||||
},
|
||||
|
||||
onDayTap(e) {
|
||||
const { year, month, day } = e.detail
|
||||
const dateStr = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`
|
||||
|
||||
@@ -80,7 +80,14 @@
|
||||
</view>
|
||||
</ui-card>
|
||||
|
||||
<!-- 内容分区:日历与记录共享月份状态,趋势按需展示,减少默认页长度。 -->
|
||||
<view class="records-content-tabs" hidden="{{totalSessions === 0}}">
|
||||
<view class="records-content-tab {{contentMode === 'records' ? 'active' : ''}}" data-mode="records" bindtap="onToggleContentMode">记录日历</view>
|
||||
<view class="records-content-tab {{contentMode === 'trend' ? 'active' : ''}}" data-mode="trend" bindtap="onToggleContentMode">趋势</view>
|
||||
</view>
|
||||
|
||||
<!-- 训练趋势 -->
|
||||
<block wx:if="{{contentMode === 'trend'}}">
|
||||
<ui-card variant="in" hidden="{{totalSessions === 0}}">
|
||||
<view class="trend-section">
|
||||
<view class="trend-header">
|
||||
@@ -93,11 +100,40 @@
|
||||
<view class="rec-seg-item {{trendMode === 'month' ? 'active' : ''}}" data-mode="month" bindtap="onToggleTrendMode">近6月</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="trend-summary">
|
||||
<view class="trend-summary-item">
|
||||
<text class="trend-summary-value">{{trendSummary.totalText}}</text>
|
||||
<text class="trend-summary-label">累计时长</text>
|
||||
</view>
|
||||
<view class="trend-summary-item">
|
||||
<text class="trend-summary-value">{{trendSummary.activeCount}}</text>
|
||||
<text class="trend-summary-label">{{trendSummary.activeLabel}}</text>
|
||||
</view>
|
||||
<view class="trend-summary-item">
|
||||
<text class="trend-summary-value">{{trendSummary.streakCount}}</text>
|
||||
<text class="trend-summary-label">连续打卡</text>
|
||||
</view>
|
||||
</view>
|
||||
<trend-chart chart-data="{{trendData}}"></trend-chart>
|
||||
<view class="trend-highlight">
|
||||
<image class="trend-highlight-icon" src="{{icons.sparkleFill}}" mode="aspectFit"></image>
|
||||
<text class="trend-highlight-title">{{trendSummary.peakTitle}}</text>
|
||||
<text class="trend-highlight-text">{{trendSummary.peakText}}</text>
|
||||
</view>
|
||||
<view class="best-trend-header">
|
||||
<view class="trend-title-wrap">
|
||||
<image class="history-title-icon" src="{{icons.crownFill}}" mode="aspectFit"></image>
|
||||
<text class="best-trend-title">个人最佳趋势</text>
|
||||
</view>
|
||||
<text class="best-trend-best">{{bestTrendSummary.peakText}}</text>
|
||||
</view>
|
||||
<trend-chart chart-data="{{bestTrendData}}" variant="peak"></trend-chart>
|
||||
</view>
|
||||
</ui-card>
|
||||
</block>
|
||||
|
||||
<!-- 日历热力图 -->
|
||||
<block wx:if="{{contentMode === 'records'}}">
|
||||
<ui-card variant="in" hidden="{{totalSessions === 0}}">
|
||||
<view class="calendar-section">
|
||||
<view class="month-picker">
|
||||
@@ -167,6 +203,7 @@
|
||||
</view>
|
||||
</view>
|
||||
</ui-card>
|
||||
</block>
|
||||
</view>
|
||||
<!-- /hidden wrapper -->
|
||||
|
||||
|
||||
@@ -199,6 +199,32 @@
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* ---- records / trend top-level switch ---- */
|
||||
.records-content-tabs {
|
||||
display: flex;
|
||||
margin: 8rpx 0 20rpx;
|
||||
padding: 6rpx;
|
||||
background: var(--bg-soft);
|
||||
border-radius: 999rpx;
|
||||
}
|
||||
|
||||
.records-content-tab {
|
||||
flex: 1;
|
||||
padding: 14rpx 0;
|
||||
border-radius: 999rpx;
|
||||
color: var(--text-secondary);
|
||||
font-size: 26rpx;
|
||||
text-align: center;
|
||||
transition: background 0.25s ease, color 0.25s ease;
|
||||
}
|
||||
|
||||
.records-content-tab.active {
|
||||
background: var(--card-bg);
|
||||
color: var(--primary);
|
||||
font-weight: 700;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.10);
|
||||
}
|
||||
|
||||
/* ---- calendar ---- */
|
||||
.calendar-section {
|
||||
padding: 0;
|
||||
@@ -267,6 +293,79 @@
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.trend-summary {
|
||||
display: flex;
|
||||
margin: 16rpx 0 4rpx;
|
||||
padding: 16rpx 0;
|
||||
background: rgba(var(--primary-rgb), 0.06);
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.trend-summary-item {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.trend-summary-value {
|
||||
color: var(--primary);
|
||||
font-size: 28rpx;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.trend-summary-label {
|
||||
margin-top: 4rpx;
|
||||
color: var(--text-secondary);
|
||||
font-size: 20rpx;
|
||||
}
|
||||
|
||||
.trend-highlight {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
margin-top: 18rpx;
|
||||
padding: 14rpx 16rpx;
|
||||
background: var(--bg-soft);
|
||||
border-radius: 14rpx;
|
||||
}
|
||||
|
||||
.trend-highlight-icon {
|
||||
width: 28rpx;
|
||||
height: 28rpx;
|
||||
}
|
||||
|
||||
.trend-highlight-title {
|
||||
color: var(--text-secondary);
|
||||
font-size: 22rpx;
|
||||
}
|
||||
|
||||
.trend-highlight-text {
|
||||
color: var(--text);
|
||||
font-size: 22rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.best-trend-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 28rpx;
|
||||
}
|
||||
|
||||
.best-trend-title {
|
||||
color: var(--text);
|
||||
font-size: 26rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.best-trend-best {
|
||||
color: var(--primary);
|
||||
font-size: 20rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ---- history ---- */
|
||||
.history-section {
|
||||
padding: 0;
|
||||
|
||||
Reference in New Issue
Block a user