Files
smt/pages/stats/index.vue
T
nepiedg c883ae7b17 init
2026-01-25 11:45:16 +08:00

356 lines
6.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="page container">
<view class="tabs">
<view
v-for="tab in tabs"
:key="tab.value"
class="tab"
:class="{ 'tab-active': currentTab === tab.value }"
@tap="currentTab = tab.value"
>
{{ tab.label }}
</view>
</view>
<view class="insight-card card">
<view class="insight-icon"></view>
<view class="insight-content">
<text class="insight-title">每周洞察</text>
<text class="insight-desc">你在周末的吸烟量明显减少非常棒试着在这周一保持这个良好的势头</text>
</view>
</view>
<view class="section">
<view class="section-header">
<text class="section-title">吸烟趋势</text>
<text class="section-change text-primary"> 减少 20%</text>
</view>
<view class="chart-card card">
<view class="chart-header">
<text class="chart-label">日均吸烟量</text>
<view class="chart-value-row">
<text class="chart-value">4</text>
<text class="chart-unit">/</text>
</view>
</view>
<view class="chart-placeholder">
<view class="chart-bars">
<view v-for="(item, index) in weeklyData" :key="index" class="chart-bar-wrapper">
<view class="chart-bar" :style="{ height: item.height }"></view>
<text class="chart-bar-label">{{ item.label }}</text>
</view>
</view>
</view>
</view>
</view>
<view class="section">
<text class="section-title">健康与储蓄</text>
<view class="health-row">
<view class="health-card card">
<view class="health-ring">
<text class="health-value">¥145</text>
</view>
<text class="health-label">节省金额</text>
<text class="health-sub">目标 ¥200</text>
</view>
<view class="health-card card">
<view class="health-ring health-ring-purple">
<text class="health-value">40%</text>
</view>
<text class="health-label">肺部功能恢复</text>
<text class="health-sub">当前进度</text>
</view>
</view>
<view class="stats-grid">
<view class="mini-stat card">
<text class="mini-stat-icon">🔥</text>
<text class="mini-stat-label">连续记录</text>
<view class="mini-stat-value-row">
<text class="mini-stat-value">12</text>
<text class="mini-stat-unit"></text>
</view>
<text class="mini-stat-sub">未吸烟</text>
</view>
<view class="mini-stat card">
<text class="mini-stat-icon">🚫</text>
<text class="mini-stat-label">已拒绝</text>
<view class="mini-stat-value-row">
<text class="mini-stat-value">24</text>
<text class="mini-stat-unit"></text>
</view>
<text class="mini-stat-sub">对抗烟瘾</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
const tabs = [
{ label: '周', value: 'week' },
{ label: '月', value: 'month' },
{ label: '年', value: 'year' }
]
const currentTab = ref('week')
const weeklyData = [
{ label: '一', height: '60%', count: 3 },
{ label: '二', height: '40%', count: 2 },
{ label: '三', height: '80%', count: 4 },
{ label: '四', height: '100%', count: 5 },
{ label: '五', height: '60%', count: 3 },
{ label: '六', height: '20%', count: 1 },
{ label: '日', height: '40%', count: 2 }
]
</script>
<style scoped>
.page {
padding-bottom: 120rpx;
}
.tabs {
display: flex;
background-color: var(--color-bg-card);
border-radius: 16rpx;
padding: 8rpx;
margin-bottom: 32rpx;
}
.tab {
flex: 1;
text-align: center;
padding: 20rpx;
border-radius: 12rpx;
font-size: 28rpx;
color: var(--color-text-secondary);
}
.tab-active {
background-color: var(--color-primary);
color: var(--color-bg);
font-weight: 600;
}
.insight-card {
display: flex;
gap: 24rpx;
background-color: rgba(74, 222, 128, 0.1);
border: 2rpx solid rgba(74, 222, 128, 0.3);
}
.insight-icon {
font-size: 48rpx;
background-color: var(--color-primary);
width: 72rpx;
height: 72rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.insight-content {
flex: 1;
}
.insight-title {
font-weight: 600;
display: block;
margin-bottom: 8rpx;
}
.insight-desc {
font-size: 24rpx;
color: var(--color-text-secondary);
}
.section {
margin-bottom: 32rpx;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16rpx;
}
.section-title {
font-size: 32rpx;
font-weight: 600;
}
.section-change {
font-size: 24rpx;
}
.chart-card {
padding: 32rpx;
}
.chart-header {
margin-bottom: 32rpx;
}
.chart-label {
font-size: 24rpx;
color: var(--color-text-secondary);
display: block;
}
.chart-value-row {
display: flex;
align-items: baseline;
gap: 8rpx;
}
.chart-value {
font-size: 56rpx;
font-weight: 700;
}
.chart-unit {
font-size: 24rpx;
color: var(--color-text-secondary);
}
.chart-bars {
display: flex;
justify-content: space-between;
align-items: flex-end;
height: 240rpx;
padding-top: 24rpx;
}
.chart-bar-wrapper {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
}
.chart-bar {
width: 40rpx;
background: linear-gradient(to top, var(--color-primary), rgba(74, 222, 128, 0.5));
border-radius: 8rpx 8rpx 0 0;
min-height: 8rpx;
}
.chart-bar-label {
font-size: 22rpx;
color: var(--color-text-secondary);
margin-top: 12rpx;
}
.health-row {
display: flex;
gap: 24rpx;
margin-bottom: 24rpx;
}
.health-card {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
padding: 32rpx;
}
.health-ring {
width: 160rpx;
height: 160rpx;
border-radius: 50%;
border: 12rpx solid rgba(74, 222, 128, 0.3);
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 16rpx;
position: relative;
}
.health-ring::before {
content: '';
position: absolute;
top: -12rpx;
left: -12rpx;
right: -12rpx;
bottom: -12rpx;
border-radius: 50%;
border: 12rpx solid transparent;
border-top-color: var(--color-primary);
transform: rotate(-45deg);
}
.health-ring-purple::before {
border-top-color: #A78BFA;
}
.health-value {
font-size: 32rpx;
font-weight: 700;
}
.health-label {
font-size: 26rpx;
margin-bottom: 4rpx;
}
.health-sub {
font-size: 22rpx;
color: var(--color-text-secondary);
}
.stats-grid {
display: flex;
gap: 24rpx;
}
.mini-stat {
flex: 1;
padding: 24rpx;
}
.mini-stat-icon {
font-size: 36rpx;
margin-bottom: 12rpx;
}
.mini-stat-label {
font-size: 24rpx;
color: var(--color-text-secondary);
display: block;
margin-bottom: 8rpx;
}
.mini-stat-value-row {
display: flex;
align-items: baseline;
gap: 8rpx;
}
.mini-stat-value {
font-size: 48rpx;
font-weight: 700;
}
.mini-stat-unit {
font-size: 24rpx;
color: var(--color-text-secondary);
}
.mini-stat-sub {
font-size: 22rpx;
color: var(--color-text-muted);
}
</style>