324 lines
7.9 KiB
Plaintext
324 lines
7.9 KiB
Plaintext
<template>
|
|
<view class="statistic-page">
|
|
<!-- 筛选栏 -->
|
|
<view class="filter-card">
|
|
<view class="filter-item">
|
|
<text class="filter-label">用户渠道:</text>
|
|
<view class="select-box">
|
|
<text class="select-text">全部</text>
|
|
<text class="select-arrow">▼</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="filter-item">
|
|
<text class="filter-label">选择时间:</text>
|
|
<view class="date-picker-box">
|
|
<text class="date-icon">📅</text>
|
|
<text class="date-text">2026/01/04 - 2026/02/02</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="filter-btns">
|
|
<button class="btn primary" @click="onSearch">查询</button>
|
|
<button class="btn" @click="onExport">导出</button>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 用户概况卡片区 (使用统一响应式网格) -->
|
|
<view class="section-card">
|
|
<view class="section-header">
|
|
<text class="section-title">用户概况</text>
|
|
<text class="info-icon">ⓘ</text>
|
|
</view>
|
|
|
|
<view class="kpi-grid">
|
|
<view class="kpi-card" v-for="item in kpiData" :key="item.title">
|
|
<view class="kpi-icon-box" :style="{ backgroundColor: item.bg }">
|
|
<text class="kpi-icon">{{ item.icon }}</text>
|
|
</view>
|
|
<view class="kpi-content">
|
|
<text class="kpi-label">{{ item.title }}</text>
|
|
<text class="kpi-value">{{ item.value }}</text>
|
|
<view class="kpi-meta">
|
|
<text class="meta-label">环比增长:</text>
|
|
<text class="meta-value" :class="item.trend">{{ item.percent }} {{ item.trend === 'up' ? '▲' : '▼' }}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 图表区 -->
|
|
<view class="chart-container">
|
|
<view class="chart-header">
|
|
<view class="header-left"></view>
|
|
<view class="header-right">
|
|
<text class="download-icon">📥</text>
|
|
</view>
|
|
</view>
|
|
<AnalyticsMultiLineChart
|
|
:xLabels="chartData.x"
|
|
:series="chartData.series"
|
|
:height="450"
|
|
/>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 地域分布与性别比例 -->
|
|
<view class="analysis-row">
|
|
<view class="map-col">
|
|
<AnalyticsUserMapTable />
|
|
</view>
|
|
<view class="gender-col">
|
|
<AnalyticsUserGenderSection />
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup lang="uts">
|
|
import { ref } from 'vue'
|
|
import AnalyticsMultiLineChart from '@/components/analytics/AnalyticsMultiLineChart.uvue'
|
|
import AnalyticsUserMapTable from '@/components/analytics/AnalyticsUserMapTable.uvue'
|
|
import AnalyticsUserGenderSection from '@/components/analytics/AnalyticsUserGenderSection.uvue'
|
|
|
|
const kpiData = [
|
|
{ title: '累计用户', value: '80834', percent: '0.84%', trend: 'up', icon: '👤', bg: '#f3e8ff' },
|
|
{ title: '访客数', value: '1138', percent: '1.04%', trend: 'down', icon: '👤', bg: '#e0f2fe' },
|
|
{ title: '浏览量', value: '9519', percent: '2.34%', trend: 'down', icon: '👁️', bg: '#dcfce7' },
|
|
{ title: '新增用户数', value: '680', percent: '4.36%', trend: 'down', icon: '👤', bg: '#ffedd5' },
|
|
{ title: '成交用户数', value: '132', percent: '11.86%', trend: 'up', icon: '👤', bg: '#f3e8ff' },
|
|
{ title: '付费会员数', value: '79', percent: '7.05%', trend: 'down', icon: '💎', bg: '#f3e8ff' }
|
|
]
|
|
|
|
const chartData = {
|
|
x: ['01-04', '01-05', '01-06', '01-07', '01-08', '01-09', '01-10', '01-11', '01-12', '01-13', '01-14', '01-15', '01-16', '01-17', '01-18', '01-19', '01-20', '01-21', '01-22', '01-23', '01-24', '01-25', '01-26', '01-27', '01-28', '01-29', '01-30', '01-31', '02-01', '02-02'],
|
|
series: [
|
|
{ name: '新增用户数', color: '#1890ff', data: [40, 30, 25, 30, 22, 10, 20, 32, 28, 15, 8, 12, 18, 22, 15, 12, 25, 30, 28, 25, 35, 20, 18, 22, 20, 15, 10, 8, 15, 38] },
|
|
{ name: '访客数', color: '#52c41a', data: [70, 75, 65, 55, 65, 50, 45, 35, 50, 68, 72, 65, 50, 48, 55, 65, 75, 62, 58, 85, 70, 55, 48, 58, 65, 72, 68, 60, 45, 50] },
|
|
{ name: '浏览量', color: '#fa8c16', data: [520, 500, 420, 280, 580, 180, 220, 100, 180, 450, 500, 400, 320, 340, 150, 280, 450, 320, 440, 460, 320, 260, 320, 280, 380, 400, 320, 330, 250, 300] },
|
|
{ name: '成交用户数', color: '#722ed1', data: [15, 12, 10, 8, 18, 5, 8, 4, 6, 12, 15, 10, 8, 9, 4, 10, 12, 8, 10, 12, 8, 6, 10, 8, 12, 14, 10, 8, 5, 8] },
|
|
{ name: '新增付费用户数', color: '#f5222d', data: [5, 4, 3, 2, 6, 1, 2, 1, 2, 4, 5, 3, 2, 3, 1, 3, 4, 2, 3, 4, 2, 2, 3, 2, 4, 5, 3, 2, 1, 3] }
|
|
]
|
|
}
|
|
|
|
function onSearch() {
|
|
uni.showToast({ title: '搜索中...' })
|
|
}
|
|
|
|
function onExport() {
|
|
uni.showToast({ title: '导出中...' })
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.statistic-page {
|
|
padding: 16px;
|
|
background-color: #f0f2f5;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
.filter-card {
|
|
background-color: #fff;
|
|
border-radius: 4px;
|
|
padding: 16px 24px;
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
gap: 32px;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.filter-item {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.filter-label {
|
|
font-size: 14px;
|
|
color: #333;
|
|
}
|
|
|
|
.select-box {
|
|
width: 180px;
|
|
height: 32px;
|
|
border: 1px solid #d9d9d9;
|
|
border-radius: 2px;
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 0 12px;
|
|
}
|
|
|
|
.select-text { font-size: 14px; color: #333; }
|
|
.select-arrow { font-size: 10px; color: #bfbfbf; }
|
|
|
|
.date-picker-box {
|
|
min-width: 240px;
|
|
height: 32px;
|
|
border: 1px solid #d9d9d9;
|
|
border-radius: 2px;
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
padding: 0 12px;
|
|
gap: 8px;
|
|
}
|
|
|
|
.date-icon { font-size: 14px; }
|
|
.date-text { font-size: 14px; color: #333; }
|
|
|
|
.filter-btns {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.btn {
|
|
height: 32px;
|
|
padding: 0 16px;
|
|
font-size: 14px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-radius: 2px;
|
|
background-color: #fff;
|
|
border: 1px solid #d9d9d9;
|
|
margin: 0;
|
|
}
|
|
|
|
.btn.primary {
|
|
background-color: #1890ff;
|
|
border-color: #1890ff;
|
|
color: #fff;
|
|
}
|
|
|
|
.section-card {
|
|
background-color: #fff;
|
|
border-radius: 4px;
|
|
padding: 20px;
|
|
}
|
|
|
|
.section-header {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
gap: 8px;
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.section-title {
|
|
font-size: 16px;
|
|
font-weight: 500;
|
|
color: #262626;
|
|
}
|
|
|
|
.info-icon {
|
|
font-size: 14px;
|
|
color: #bfbfbf;
|
|
}
|
|
|
|
/* kpi-row 已废弃,采用全局 kpi-grid */
|
|
.kpi-card {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
gap: 16px;
|
|
padding: 8px;
|
|
min-width: 0; /* 允许收缩 */
|
|
}
|
|
|
|
.kpi-icon-box {
|
|
width: 44px;
|
|
height: 44px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.kpi-icon { font-size: 20px; }
|
|
|
|
.kpi-content {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
}
|
|
|
|
.kpi-label { font-size: 14px; color: #8c8c8c; }
|
|
.kpi-value { font-size: 24px; font-weight: 500; color: #262626; }
|
|
|
|
.kpi-meta {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.meta-label { color: #8c8c8c; }
|
|
.meta-value.up { color: #ff4d4f; }
|
|
.meta-value.down { color: #52c41a; }
|
|
|
|
.chart-container {
|
|
border-top: 1px solid #f0f0f0;
|
|
padding-top: 24px;
|
|
}
|
|
|
|
.chart-header {
|
|
display: flex;
|
|
flex-direction: row;
|
|
justify-content: space-between;
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.download-icon {
|
|
font-size: 18px;
|
|
color: #8c8c8c;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.analysis-row {
|
|
display: flex;
|
|
flex-direction: row;
|
|
gap: 16px;
|
|
margin-top: 16px;
|
|
width: 100%;
|
|
}
|
|
|
|
@media (max-width: 1200px) {
|
|
.filter-card {
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
gap: 16px;
|
|
}
|
|
|
|
.filter-item {
|
|
width: 100%;
|
|
}
|
|
|
|
.select-box, .date-picker-box {
|
|
flex: 1;
|
|
}
|
|
|
|
.analysis-row {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.map-col, .gender-col {
|
|
width: 100%;
|
|
flex: none;
|
|
}
|
|
}
|
|
|
|
.map-col {
|
|
flex: 7;
|
|
}
|
|
|
|
.gender-col {
|
|
flex: 3;
|
|
}
|
|
</style>
|