1 changed files with 593 additions and 1 deletions
@ -1,14 +1,606 @@ |
|||||
<template> |
<template> |
||||
<div class="user-login-stats-container"> |
<div class="user-login-stats-container"> |
||||
<h1>用户类登录统计</h1> |
|
||||
|
<div class="tab-header"> |
||||
|
<div |
||||
|
class="tab-item" |
||||
|
:class="{ active: activeTab === 'loginData' }" |
||||
|
@click="activeTab = 'loginData'" |
||||
|
> |
||||
|
登录数据 |
||||
|
</div> |
||||
|
<div |
||||
|
class="tab-item" |
||||
|
:class="{ active: activeTab === 'regionalData' }" |
||||
|
@click="activeTab = 'regionalData'" |
||||
|
> |
||||
|
各地区登录数据 |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 登录数据 Tab --> |
||||
|
<div v-show="activeTab === 'loginData'" class="tab-content"> |
||||
|
<!-- 搜索栏 --> |
||||
|
<div class="search-bar"> |
||||
|
<div class="search-label">地区</div> |
||||
|
<el-select v-model="selectedRegion" placeholder="请选择所属地区" style="width: 200px; margin-right: 20px;"> |
||||
|
<el-option label="全部" value="all" /> |
||||
|
<el-option label="中国" value="cn" /> |
||||
|
<el-option label="美国" value="us" /> |
||||
|
</el-select> |
||||
|
|
||||
|
<div class="search-label">时间段查询</div> |
||||
|
<el-date-picker |
||||
|
v-model="dateRange" |
||||
|
type="daterange" |
||||
|
range-separator="至" |
||||
|
start-placeholder="开始时间" |
||||
|
end-placeholder="结束时间" |
||||
|
size="default" |
||||
|
/> |
||||
|
<el-button type="primary" class="search-btn">搜索</el-button> |
||||
|
<el-button type="primary" class="reset-btn">重置</el-button> |
||||
|
<el-button type="danger" class="export-btn">数据导出</el-button> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 统计卡片 --> |
||||
|
<div class="stats-row"> |
||||
|
<!-- 今日登录用户数 --> |
||||
|
<div class="stat-card purple-gradient big-card"> |
||||
|
<div class="card-title"> |
||||
|
<el-icon><UserFilled /></el-icon> 今日登录用户数 |
||||
|
</div> |
||||
|
<div class="big-card-content"> |
||||
|
<div class="card-value">154,838</div> |
||||
|
<div class="card-tag up"> |
||||
|
较昨日增加↑ 5.22% |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="right-stats-col"> |
||||
|
<!-- 今日登录会员用户数 --> |
||||
|
<div class="stat-card orange-gradient small-card"> |
||||
|
<div class="top-row"> |
||||
|
<div class="card-title"> |
||||
|
<el-icon><Trophy /></el-icon> 今日登录会员用户数 |
||||
|
</div> |
||||
|
<div class="card-value-small">112,265</div> |
||||
|
</div> |
||||
|
<div class="card-tag-wrapper"> |
||||
|
<div class="card-tag up">较昨日增加↑ 15.22%</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 今日登录非网用户数 --> |
||||
|
<div class="stat-card blue-gradient small-card"> |
||||
|
<div class="top-row"> |
||||
|
<div class="card-title"> |
||||
|
<el-icon><User /></el-icon> 今日登录非网用户数 |
||||
|
</div> |
||||
|
<div class="card-value-small">42,567</div> |
||||
|
</div> |
||||
|
<div class="card-tag-wrapper"> |
||||
|
<div class="card-tag down">较昨日减少↓ 1.22%</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 近7天登录趋势 --> |
||||
|
<div class="chart-section"> |
||||
|
<div class="section-title"><el-icon><TrendCharts /></el-icon> 近7天登录趋势</div> |
||||
|
<div ref="chartTrendRef" class="chart-box-large"></div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 表格1: 今日登录数据 --> |
||||
|
<div class="detail-section"> |
||||
|
<div class="section-title"><el-icon><DataLine /></el-icon> 今日登录数据</div> |
||||
|
<el-table :data="loginTableData1" style="width: 100%" :header-cell-style="headerCellStyle"> |
||||
|
<el-table-column prop="channel" label="来源渠道" /> |
||||
|
<el-table-column prop="total" label="今日登录总数" /> |
||||
|
<el-table-column prop="dailyNew" label="较昨日新增" /> |
||||
|
<el-table-column prop="percent" label="占比" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 表格2: 会员登录数据 --> |
||||
|
<div class="detail-section"> |
||||
|
<div class="section-title"><el-icon><Trophy /></el-icon> 会员登录数据</div> |
||||
|
<el-table :data="loginTableData2" style="width: 100%" :header-cell-style="headerCellStyle"> |
||||
|
<el-table-column prop="channel" label="来源渠道" /> |
||||
|
<el-table-column prop="total" label="今日登录会员数" /> |
||||
|
<el-table-column prop="dailyNew" label="较昨日新增" /> |
||||
|
<el-table-column prop="rate" label="会员登录率" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 表格3: 非网登录数据 --> |
||||
|
<div class="detail-section"> |
||||
|
<div class="section-title"><el-icon><User /></el-icon> 非网登录数据</div> |
||||
|
<el-table :data="loginTableData3" style="width: 100%" :header-cell-style="headerCellStyle"> |
||||
|
<el-table-column prop="channel" label="来源渠道" /> |
||||
|
<el-table-column prop="total" label="今日登录会员数" /> |
||||
|
<el-table-column prop="dailyNew" label="较昨日新增" /> |
||||
|
<el-table-column prop="rate" label="非网登录率" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 各地区登录数据 Tab --> |
||||
|
<div v-show="activeTab === 'regionalData'" class="tab-content"> |
||||
|
<!-- 搜索栏 --> |
||||
|
<div class="search-bar"> |
||||
|
<div class="search-label">地区查询</div> |
||||
|
<el-input v-model="searchRegion" placeholder="请输入地区" style="width: 200px; margin-right: 20px;" /> |
||||
|
|
||||
|
<div class="search-label">时间段查询</div> |
||||
|
<el-date-picker |
||||
|
v-model="dateRangeRegion" |
||||
|
type="daterange" |
||||
|
range-separator="至" |
||||
|
start-placeholder="开始时间" |
||||
|
end-placeholder="结束时间" |
||||
|
size="default" |
||||
|
/> |
||||
|
<el-button type="primary" class="search-btn">搜索</el-button> |
||||
|
<el-button type="primary" class="reset-btn">重置</el-button> |
||||
|
<el-button type="danger" class="export-btn">数据导出</el-button> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 表格1: 各地区活跃数据 --> |
||||
|
<div class="detail-section"> |
||||
|
<div class="section-title"><el-icon><Location /></el-icon> 各地区活跃数据</div> |
||||
|
<el-table :data="regionalTableData1" style="width: 100%" :header-cell-style="headerCellStyle"> |
||||
|
<el-table-column prop="region" label="地区" /> |
||||
|
<el-table-column prop="dailyActive" label="日活跃用户" /> |
||||
|
<el-table-column prop="weeklyActive" label="周活跃用户" /> |
||||
|
<el-table-column prop="monthlyActive" label="月活跃用户" /> |
||||
|
<el-table-column prop="periodActive" label="区间活跃用户" /> |
||||
|
<el-table-column prop="percent" label="活跃度占比" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 表格2: 各地区会员活跃数据 --> |
||||
|
<div class="detail-section"> |
||||
|
<div class="section-title"><el-icon><Trophy /></el-icon> 各地区会员活跃数据</div> |
||||
|
<el-table :data="regionalTableData2" style="width: 100%" :header-cell-style="headerCellStyle"> |
||||
|
<el-table-column prop="region" label="地区" /> |
||||
|
<el-table-column prop="dailyActive" label="日活跃用户" /> |
||||
|
<el-table-column prop="weeklyActive" label="周活跃用户" /> |
||||
|
<el-table-column prop="monthlyActive" label="月活跃用户" /> |
||||
|
<el-table-column prop="periodActive" label="区间活跃用户" /> |
||||
|
<el-table-column prop="percent" label="活跃度占比" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 表格3: 各地区非网活跃数据 --> |
||||
|
<div class="detail-section"> |
||||
|
<div class="section-title"><el-icon><User /></el-icon> 各地区非网活跃数据</div> |
||||
|
<el-table :data="regionalTableData3" style="width: 100%" :header-cell-style="headerCellStyle"> |
||||
|
<el-table-column prop="region" label="地区" /> |
||||
|
<el-table-column prop="dailyActive" label="日活跃用户" /> |
||||
|
<el-table-column prop="weeklyActive" label="周活跃用户" /> |
||||
|
<el-table-column prop="monthlyActive" label="月活跃用户" /> |
||||
|
<el-table-column prop="periodActive" label="区间活跃用户" /> |
||||
|
<el-table-column prop="percent" label="活跃度占比" /> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 图表: 各地区日活跃用户 --> |
||||
|
<div class="chart-section"> |
||||
|
<div class="section-title"><el-icon><BarChart /></el-icon> 各地区日活跃用户 |
||||
|
<el-button size="small" style="margin-left: auto;">切换</el-button> |
||||
|
</div> |
||||
|
<div ref="chartRegionBarRef" class="chart-box-large"></div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 图表: 地区分布 --> |
||||
|
<div class="chart-section"> |
||||
|
<div class="section-title"><el-icon><PieChart /></el-icon> 各地区用户分布</div> |
||||
|
<div ref="chartRegionPieRef" class="chart-box-large" style="height: 400px;"></div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="charts-row"> |
||||
|
<div class="chart-section half-width"> |
||||
|
<div class="section-title">各地区会员用户分布</div> |
||||
|
<div ref="chartRegionMemberPieRef" class="chart-box-medium"></div> |
||||
|
</div> |
||||
|
<div class="chart-section half-width"> |
||||
|
<div class="section-title">各地区非网用户分布</div> |
||||
|
<div ref="chartRegionNonMemberPieRef" class="chart-box-medium"></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
</div> |
</div> |
||||
</template> |
</template> |
||||
|
|
||||
<script setup> |
<script setup> |
||||
|
import { ref, onMounted, nextTick, watch } from 'vue'; |
||||
|
import { useRoute, useRouter } from 'vue-router'; |
||||
|
import * as echarts from 'echarts'; |
||||
|
|
||||
|
const route = useRoute(); |
||||
|
const router = useRouter(); |
||||
|
|
||||
|
const activeTab = ref(route.query.tab || 'loginData'); |
||||
|
const dateRange = ref(''); |
||||
|
const selectedRegion = ref(''); |
||||
|
const searchRegion = ref(''); |
||||
|
const dateRangeRegion = ref(''); |
||||
|
|
||||
|
const chartTrendRef = ref(null); |
||||
|
const chartRegionBarRef = ref(null); |
||||
|
const chartRegionPieRef = ref(null); |
||||
|
const chartRegionMemberPieRef = ref(null); |
||||
|
const chartRegionNonMemberPieRef = ref(null); |
||||
|
|
||||
|
// Tab 1 数据 |
||||
|
const loginTableData1 = [ |
||||
|
{ channel: 'App Store', total: '154,832', dailyNew: '', percent: '38%' }, |
||||
|
{ channel: 'Play Store', total: '42,567', dailyNew: '', percent: '30%' }, |
||||
|
{ channel: 'H5', total: '112,265', dailyNew: '', percent: '17%' }, |
||||
|
{ channel: 'APK', total: '68,420', dailyNew: '', percent: '10%' }, |
||||
|
{ channel: '总计', total: '68,420', dailyNew: '', percent: '100%' }, |
||||
|
]; |
||||
|
|
||||
|
const loginTableData2 = [ |
||||
|
{ channel: 'App Store', total: '1,245', dailyNew: '', rate: '38%' }, |
||||
|
{ channel: 'Play Store', total: '987', dailyNew: '', rate: '30%' }, |
||||
|
{ channel: 'H5', total: '543', dailyNew: '', rate: '17%' }, |
||||
|
{ channel: 'APK', total: '321', dailyNew: '', rate: '10%' }, |
||||
|
{ channel: '总计', total: '3,096', dailyNew: '', rate: '100%' }, |
||||
|
]; |
||||
|
|
||||
|
const loginTableData3 = [ |
||||
|
{ channel: 'App Store', total: '1,245', dailyNew: '', rate: '38%' }, |
||||
|
{ channel: 'Play Store', total: '987', dailyNew: '', rate: '30%' }, |
||||
|
{ channel: 'H5', total: '543', dailyNew: '', rate: '17%' }, |
||||
|
{ channel: 'APK', total: '321', dailyNew: '', rate: '10%' }, |
||||
|
{ channel: '总计', total: '3,096', dailyNew: '', rate: '100%' }, |
||||
|
]; |
||||
|
|
||||
|
// Tab 2 数据 |
||||
|
const regionalTableData1 = [ |
||||
|
{ region: '香港', dailyActive: '1,245', weeklyActive: '1,245', monthlyActive: '1,245', periodActive: '', percent: '38%' }, |
||||
|
{ region: '新加坡', dailyActive: '987', weeklyActive: '987', monthlyActive: '807', periodActive: '', percent: '30%' }, |
||||
|
{ region: '泰国', dailyActive: '543', weeklyActive: '543', monthlyActive: '543', periodActive: '', percent: '17%' }, |
||||
|
{ region: '越南', dailyActive: '321', weeklyActive: '321', monthlyActive: '321', periodActive: '', percent: '10%' }, |
||||
|
{ region: '马来西亚', dailyActive: '321', weeklyActive: '321', monthlyActive: '321', periodActive: '', percent: '10%' }, |
||||
|
{ region: '加拿大', dailyActive: '321', weeklyActive: '321', monthlyActive: '321', periodActive: '', percent: '10%' }, |
||||
|
{ region: '其他', dailyActive: '321', weeklyActive: '321', monthlyActive: '321', periodActive: '', percent: '10%' }, |
||||
|
{ region: '总计', dailyActive: '3,096', weeklyActive: '3,096', monthlyActive: '3,096', periodActive: '', percent: '100%' }, |
||||
|
]; |
||||
|
|
||||
|
const regionalTableData2 = JSON.parse(JSON.stringify(regionalTableData1)); // 复用假数据 |
||||
|
const regionalTableData3 = JSON.parse(JSON.stringify(regionalTableData1)); // 复用假数据 |
||||
|
|
||||
|
const headerCellStyle = { |
||||
|
background: '#fff0f0', |
||||
|
color: '#333', |
||||
|
fontWeight: 'bold' |
||||
|
}; |
||||
|
|
||||
|
const initCharts = () => { |
||||
|
nextTick(() => { |
||||
|
if (activeTab.value === 'loginData') { |
||||
|
if (chartTrendRef.value) { |
||||
|
const chart = echarts.init(chartTrendRef.value); |
||||
|
chart.setOption({ |
||||
|
tooltip: { trigger: 'axis' }, |
||||
|
legend: { data: ['新用户', '老用户'], top: 'top' }, |
||||
|
grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true }, |
||||
|
xAxis: { |
||||
|
type: 'category', |
||||
|
boundaryGap: false, |
||||
|
data: ['六天前', '五天前', '四天前', '三天前', '两天前', '昨天', '今天'] |
||||
|
}, |
||||
|
yAxis: { type: 'value' }, |
||||
|
series: [ |
||||
|
{ |
||||
|
name: '新用户', |
||||
|
type: 'line', |
||||
|
data: [1350, 1250, 1100, 1050, 1050, 1300, 1000], |
||||
|
smooth: true, |
||||
|
itemStyle: { color: '#40a9ff' } |
||||
|
}, |
||||
|
{ |
||||
|
name: '老用户', |
||||
|
type: 'line', |
||||
|
data: [300, 600, 320, 320, 400, 550, 650], |
||||
|
smooth: true, |
||||
|
itemStyle: { color: '#52c41a' } |
||||
|
} |
||||
|
] |
||||
|
}); |
||||
|
} |
||||
|
} else if (activeTab.value === 'regionalData') { |
||||
|
// 柱状图 |
||||
|
if (chartRegionBarRef.value) { |
||||
|
const chart = echarts.init(chartRegionBarRef.value); |
||||
|
chart.setOption({ |
||||
|
tooltip: { trigger: 'axis' }, |
||||
|
legend: { data: ['日活跃用户', '周活跃用户', '月活跃用户'], top: 'top' }, |
||||
|
xAxis: { |
||||
|
type: 'category', |
||||
|
data: ['香港', '新加坡', '泰国', '越南', '马来西亚', '加拿大', '美国'] |
||||
|
}, |
||||
|
yAxis: { type: 'value' }, |
||||
|
series: [ |
||||
|
{ name: '日活跃用户', type: 'bar', data: [400, 400, 400, 500, 400, 400, 400], itemStyle: { color: '#40a9ff' } }, |
||||
|
{ name: '周活跃用户', type: 'bar', data: [500, 500, 500, 600, 500, 500, 500], itemStyle: { color: '#52c41a' } }, |
||||
|
{ name: '月活跃用户', type: 'bar', data: [600, 600, 600, 700, 600, 600, 600], itemStyle: { color: '#b37feb' } } |
||||
|
] |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
// 饼图 - 地区分布 |
||||
|
if (chartRegionPieRef.value) { |
||||
|
const chart = echarts.init(chartRegionPieRef.value); |
||||
|
chart.setOption({ |
||||
|
tooltip: { trigger: 'item' }, |
||||
|
legend: { orient: 'vertical', right: '10%', top: 'center' }, |
||||
|
series: [ |
||||
|
{ |
||||
|
type: 'pie', |
||||
|
radius: '80%', |
||||
|
center: ['40%', '50%'], |
||||
|
data: [ |
||||
|
{ value: 1048, name: '香港地区' }, |
||||
|
{ value: 735, name: '新加坡地区' }, |
||||
|
{ value: 580, name: '泰国地区' }, |
||||
|
{ value: 484, name: '越南地区' }, |
||||
|
{ value: 300, name: '马来西亚地区' }, |
||||
|
{ value: 300, name: '其他地区' } |
||||
|
], |
||||
|
itemStyle: { |
||||
|
borderRadius: 0, |
||||
|
borderColor: '#fff', |
||||
|
borderWidth: 2 |
||||
|
}, |
||||
|
label: { show: false } |
||||
|
} |
||||
|
] |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
// 饼图 - 会员分布 |
||||
|
if (chartRegionMemberPieRef.value) { |
||||
|
const chart = echarts.init(chartRegionMemberPieRef.value); |
||||
|
chart.setOption({ |
||||
|
tooltip: { trigger: 'item' }, |
||||
|
legend: { orient: 'vertical', right: '0%', top: 'center', itemWidth: 10, itemHeight: 10, textStyle: { fontSize: 10 } }, |
||||
|
series: [ |
||||
|
{ |
||||
|
type: 'pie', |
||||
|
radius: '70%', |
||||
|
center: ['30%', '50%'], |
||||
|
data: [ |
||||
|
{ value: 1048, name: '香港地区' }, |
||||
|
{ value: 735, name: '新加坡地区' }, |
||||
|
{ value: 580, name: '泰国地区' }, |
||||
|
{ value: 484, name: '越南地区' }, |
||||
|
{ value: 300, name: '马来西亚地区' }, |
||||
|
{ value: 300, name: '其他地区' } |
||||
|
], |
||||
|
label: { show: false } |
||||
|
} |
||||
|
] |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
// 饼图 - 非网分布 |
||||
|
if (chartRegionNonMemberPieRef.value) { |
||||
|
const chart = echarts.init(chartRegionNonMemberPieRef.value); |
||||
|
chart.setOption({ |
||||
|
tooltip: { trigger: 'item' }, |
||||
|
legend: { orient: 'vertical', right: '0%', top: 'center', itemWidth: 10, itemHeight: 10, textStyle: { fontSize: 10 } }, |
||||
|
series: [ |
||||
|
{ |
||||
|
type: 'pie', |
||||
|
radius: '70%', |
||||
|
center: ['30%', '50%'], |
||||
|
data: [ |
||||
|
{ value: 1048, name: '香港地区' }, |
||||
|
{ value: 735, name: '新加坡地区' }, |
||||
|
{ value: 580, name: '泰国地区' }, |
||||
|
{ value: 484, name: '越南地区' }, |
||||
|
{ value: 300, name: '马来西亚地区' }, |
||||
|
{ value: 300, name: '其他地区' } |
||||
|
], |
||||
|
label: { show: false } |
||||
|
} |
||||
|
] |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
watch(activeTab, (newVal) => { |
||||
|
router.replace({ query: { ...route.query, tab: newVal } }); |
||||
|
initCharts(); |
||||
|
}); |
||||
|
|
||||
|
onMounted(() => { |
||||
|
initCharts(); |
||||
|
}); |
||||
</script> |
</script> |
||||
|
|
||||
<style scoped> |
<style scoped> |
||||
.user-login-stats-container { |
.user-login-stats-container { |
||||
padding: 20px; |
padding: 20px; |
||||
|
background-color: #fee6e6; |
||||
|
min-height: calc(100vh - 40px); |
||||
|
} |
||||
|
|
||||
|
/* Tabs */ |
||||
|
.tab-header { |
||||
|
display: flex; |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
.tab-item { |
||||
|
padding: 6px 16px; |
||||
|
margin-right: 10px; |
||||
|
background-color: #fff; |
||||
|
border: 1px solid #ffcccc; |
||||
|
border-radius: 4px; |
||||
|
cursor: pointer; |
||||
|
color: #ff4d4f; |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
.tab-item.active { |
||||
|
background-color: #ff4d4f; |
||||
|
color: #fff; |
||||
|
} |
||||
|
|
||||
|
/* Search Bar */ |
||||
|
.search-bar { |
||||
|
background: #fff; |
||||
|
padding: 15px; |
||||
|
border-radius: 8px; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 10px; |
||||
|
margin-bottom: 20px; |
||||
|
border: 1px solid #f0f0f0; |
||||
|
} |
||||
|
.search-label { |
||||
|
font-weight: bold; |
||||
|
margin-right: 5px; |
||||
|
} |
||||
|
.search-btn, .reset-btn { |
||||
|
width: 80px; |
||||
|
} |
||||
|
.search-btn { |
||||
|
background-color: #409eff; |
||||
|
} |
||||
|
.reset-btn { |
||||
|
background-color: #a0cfff; |
||||
|
border-color: #a0cfff; |
||||
|
} |
||||
|
.export-btn { |
||||
|
margin-left: auto; |
||||
|
background-color: #ff7875; |
||||
|
border-color: #ff7875; |
||||
|
} |
||||
|
|
||||
|
/* Cards */ |
||||
|
.stats-row { |
||||
|
display: flex; |
||||
|
gap: 20px; |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
.big-card { |
||||
|
flex: 1; |
||||
|
height: 360px; |
||||
|
border-radius: 12px; |
||||
|
padding: 24px; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: flex-start; |
||||
|
color: #fff; |
||||
|
position: relative; |
||||
|
} |
||||
|
.right-stats-col { |
||||
|
flex: 2; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
gap: 20px; |
||||
|
} |
||||
|
.small-card { |
||||
|
flex: 1; |
||||
|
border-radius: 12px; |
||||
|
padding: 20px; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: flex-start; |
||||
|
color: #fff; |
||||
|
position: relative; |
||||
|
} |
||||
|
.purple-gradient { background: linear-gradient(135deg, #a18cd1 0%, #fbc2eb 100%); } |
||||
|
.orange-gradient { background: linear-gradient(90deg, #ff8c6d 0%, #ffcba4 100%); } |
||||
|
.blue-gradient { background: linear-gradient(135deg, #9BB7FC 0%, #66a6ff 100%); } |
||||
|
|
||||
|
.card-title { |
||||
|
font-size: 24px; |
||||
|
font-weight: bold; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 8px; |
||||
|
margin-bottom: 20px; |
||||
|
width: 100%; |
||||
|
} |
||||
|
.big-card-content { |
||||
|
flex: 1; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
gap: 10px; |
||||
|
} |
||||
|
.card-value { |
||||
|
font-size: 64px; |
||||
|
font-weight: bold; |
||||
|
margin: 0; |
||||
|
text-align: center; |
||||
|
} |
||||
|
.card-value-small { |
||||
|
font-size: 48px; |
||||
|
font-weight: bold; |
||||
|
margin-left: auto; |
||||
|
} |
||||
|
.top-row { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
.card-tag-wrapper { |
||||
|
display: flex; |
||||
|
justify-content: flex-end; |
||||
|
margin-top: 10px; |
||||
|
} |
||||
|
.card-tag { |
||||
|
background-color: #fff; |
||||
|
padding: 8px 16px; |
||||
|
border-radius: 4px; |
||||
|
font-weight: bold; |
||||
|
display: inline-block; |
||||
|
} |
||||
|
.big-card .card-tag { font-size: 18px; } |
||||
|
.card-tag.up { color: #52c41a; } |
||||
|
.card-tag.down { color: #ff4d4f; } |
||||
|
|
||||
|
/* Sections */ |
||||
|
.chart-section, .detail-section { |
||||
|
background: #fff; |
||||
|
border-radius: 8px; |
||||
|
padding: 15px; |
||||
|
margin-bottom: 20px; |
||||
|
border: 1px solid #f0f0f0; |
||||
|
} |
||||
|
.section-title { |
||||
|
color: #409eff; |
||||
|
font-size: 16px; |
||||
|
font-weight: bold; |
||||
|
margin-bottom: 15px; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 5px; |
||||
|
} |
||||
|
.chart-box-large { |
||||
|
width: 100%; |
||||
|
height: 400px; |
||||
|
} |
||||
|
.charts-row { |
||||
|
display: flex; |
||||
|
gap: 20px; |
||||
|
} |
||||
|
.half-width { |
||||
|
flex: 1; |
||||
|
} |
||||
|
.chart-box-medium { |
||||
|
width: 100%; |
||||
|
height: 300px; |
||||
} |
} |
||||
</style> |
</style> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue