feat(组件): 添加指标说明工具提示功能
在个人仪表盘、团队报表和统计指标组件中添加工具提示功能,当用户悬停在指标信息图标上时显示详细说明 创建新的Tooltip组件用于显示指标说明 更新API基础路径配置
This commit is contained in:
53
my-vue-app/src/components/Tooltip.vue
Normal file
53
my-vue-app/src/components/Tooltip.vue
Normal file
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<Teleport to="body">
|
||||
<div v-if="visible" class="stat-tooltip" :style="{ left: x + 'px', top: y + 'px' }">
|
||||
<div class="tooltip-title">
|
||||
{{ title }}
|
||||
</div>
|
||||
<div class="tooltip-description">
|
||||
<p>{{ description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
visible: Boolean,
|
||||
x: Number,
|
||||
y: Number,
|
||||
title: String,
|
||||
description: String
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.stat-tooltip {
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
color: white;
|
||||
padding: 12px 16px;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
max-width: 300px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.tooltip-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 4px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.tooltip-description {
|
||||
font-size: 13px;
|
||||
color: #e0e0e0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.tooltip-description p {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -5,7 +5,7 @@ import { useUserStore } from '@/stores/user'
|
||||
|
||||
// 创建axios实例
|
||||
const service = axios.create({
|
||||
baseURL: 'http://192.168.15.60:8890' || '', // API基础路径,支持完整URL
|
||||
baseURL: 'http://192.168.15.54:8890' || '', // API基础路径,支持完整URL
|
||||
timeout: 100000, // 请求超时时间
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=UTF-8'
|
||||
|
||||
@@ -4,52 +4,62 @@
|
||||
<div class="report-grid">
|
||||
<div class="report-card">
|
||||
<div class="card-header">
|
||||
<span class="card-title">团队总通话</span>
|
||||
<span class="card-title">团队总通话 <i class="info-icon" @mouseenter="showTooltip('totalCalls', $event)" @mouseleave="hideTooltip">ⓘ</i></span>
|
||||
<span class="card-trend positive">{{ weekTotalData.week_total_call?.team_data?.current_rate_last_current || '0%' }} vs 上期</span>
|
||||
</div>
|
||||
<div class="card-value">{{ weekTotalData.week_total_call?.team_data?.total_current_week_call || 0 }} 次</div>
|
||||
</div>
|
||||
<div class="report-card">
|
||||
<div class="card-header">
|
||||
<span class="card-title">有效通话时长</span>
|
||||
<span class="card-title">有效通话时长 <i class="info-icon" @mouseenter="showTooltip('callDuration', $event)" @mouseleave="hideTooltip">ⓘ</i></span>
|
||||
<span class="card-trend negative">{{ weekTotalData.week_total_call?.team_data?.current_rate_last_current || '0%' }} vs 上期</span>
|
||||
</div>
|
||||
<div class="card-value">{{ formatDuration(weekTotalData.week_total_call?.team_data?.total_call_duration)||0 }} 小时</div>
|
||||
</div>
|
||||
<div class="report-card">
|
||||
<div class="card-header">
|
||||
<span class="card-title">新增意向客户</span>
|
||||
<span class="card-title">新增意向客户 <i class="info-icon" @mouseenter="showTooltip('newCustomers', $event)" @mouseleave="hideTooltip">ⓘ</i></span>
|
||||
<span class="card-trend positive">{{ weekTotalData.week_add_customer_total?.team_data?.week_rate_last_week || '0%' }} vs 上期</span>
|
||||
</div>
|
||||
<div class="card-value">{{ weekTotalData.week_add_customer_total?.team_data?.total_week_add_customer || 0 }} 人</div>
|
||||
</div>
|
||||
<div class="report-card">
|
||||
<div class="card-header">
|
||||
<span class="card-title">新增成交</span>
|
||||
<span class="card-title">新增成交 <i class="info-icon" @mouseenter="showTooltip('newDeals', $event)" @mouseleave="hideTooltip">ⓘ</i></span>
|
||||
<span class="card-trend positive">{{ weekTotalData.week_add_deal_total?.team_data?.week_rate_last_week || '0%' }} vs 上期</span>
|
||||
</div>
|
||||
<div class="card-value">{{ weekTotalData.week_add_deal_total?.team_data?.total_week_add_deal || 0 }} 单</div>
|
||||
</div>
|
||||
<div class="report-card">
|
||||
<div class="card-header">
|
||||
<span class="card-title">月度总业绩</span>
|
||||
<span class="card-title">月度总业绩 <i class="info-icon" @mouseenter="showTooltip('monthlyRevenue', $event)" @mouseleave="hideTooltip">ⓘ</i></span>
|
||||
<span class="card-trend positive">+8% vs 上月</span>
|
||||
</div>
|
||||
<div class="card-value">{{ formatCurrency(weekTotalData.week_add_fee_total?.total_add_fee || 0) }} 元</div>
|
||||
</div>
|
||||
<div class="report-card">
|
||||
<div class="card-header">
|
||||
<span class="card-title">定金转化率</span>
|
||||
<span class="card-title">定金转化率 <i class="info-icon" @mouseenter="showTooltip('conversionRate', $event)" @mouseleave="hideTooltip">ⓘ</i></span>
|
||||
<span class="card-trend positive">{{ weekTotalData.pay_deposit_to_money_rate?.team_data?.week_vs_last_week || '0%' }} vs 上期</span>
|
||||
</div>
|
||||
<div class="card-value">{{ weekTotalData.pay_deposit_to_money_rate?.team_data?.week_pay_deposit_to_money_rate || '0%' }} </div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tooltip 组件 -->
|
||||
<Tooltip
|
||||
:visible="tooltip.visible"
|
||||
:x="tooltip.x"
|
||||
:y="tooltip.y"
|
||||
:title="tooltip.title"
|
||||
:description="tooltip.description"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { watch } from 'vue'
|
||||
import { watch, reactive } from 'vue'
|
||||
import Tooltip from '@/components/Tooltip.vue'
|
||||
|
||||
// 定义props
|
||||
const props = defineProps({
|
||||
@@ -82,6 +92,59 @@ const formatCurrency = (amount) => {
|
||||
if (!amount) return '0'
|
||||
return amount.toLocaleString()
|
||||
}
|
||||
|
||||
// Tooltip 相关数据
|
||||
const tooltip = reactive({
|
||||
visible: false,
|
||||
x: 0,
|
||||
y: 0,
|
||||
title: '',
|
||||
description: ''
|
||||
})
|
||||
|
||||
// 指标说明配置
|
||||
const metricDescriptions = {
|
||||
totalCalls: {
|
||||
title: '团队总通话',
|
||||
description: '团队所有成员在本期内的通话总次数,包括拨出和接听的所有电话。'
|
||||
},
|
||||
callDuration: {
|
||||
title: '有效通话时长',
|
||||
description: '团队所有成员有效通话的总时长,不包括未接通和短时间通话。'
|
||||
},
|
||||
newCustomers: {
|
||||
title: '新增意向客户',
|
||||
description: '本期新增的有明确购买意向的客户数量,通过沟通确认有需求的客户。'
|
||||
},
|
||||
newDeals: {
|
||||
title: '新增成交',
|
||||
description: '本期新增的成交订单数量,已确认付款或签约的客户订单。'
|
||||
},
|
||||
monthlyRevenue: {
|
||||
title: '月度总业绩',
|
||||
description: '本月团队累计完成的销售业绩总额,包括所有已确认的订单金额。'
|
||||
},
|
||||
conversionRate: {
|
||||
title: '定金转化率',
|
||||
description: '支付定金的客户数 ÷ 意向客户总数,反映客户从意向到付费的转化效果。'
|
||||
}
|
||||
}
|
||||
|
||||
// Tooltip 相关方法
|
||||
const showTooltip = (metricType, event) => {
|
||||
const description = metricDescriptions[metricType]
|
||||
if (description) {
|
||||
tooltip.title = description.title
|
||||
tooltip.description = description.description
|
||||
tooltip.x = event.clientX + 10
|
||||
tooltip.y = event.clientY - 10
|
||||
tooltip.visible = true
|
||||
}
|
||||
}
|
||||
|
||||
const hideTooltip = () => {
|
||||
tooltip.visible = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -188,4 +251,30 @@ const formatCurrency = (amount) => {
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
// 感叹号图标样式
|
||||
.info-icon {
|
||||
font-style: normal;
|
||||
color: #409eff;
|
||||
font-size: 12px;
|
||||
margin-left: 4px;
|
||||
opacity: 0.7;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
color: #007bff;
|
||||
transform: scale(1.2);
|
||||
}
|
||||
}
|
||||
|
||||
.card-title:hover .info-icon {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.report-card {
|
||||
position: relative;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
</style>
|
||||
@@ -13,27 +13,27 @@
|
||||
<div class="kpi-grid">
|
||||
<div class="kpi-item">
|
||||
<div class="kpi-value">{{ props.kpiData.totalCalls }}</div>
|
||||
<p>今日通话</p>
|
||||
<p>今日通话 <i class="info-icon" @mouseenter="showTooltip('totalCalls', $event)" @mouseleave="hideTooltip">ⓘ</i></p>
|
||||
</div>
|
||||
<div class="kpi-item">
|
||||
<div class="kpi-value">{{ props.kpiData.successRate }}%</div>
|
||||
<p>电话接通率</p>
|
||||
<p>电话接通率 <i class="info-icon" @mouseenter="showTooltip('successRate', $event)" @mouseleave="hideTooltip">ⓘ</i></p>
|
||||
</div>
|
||||
<div class="kpi-item">
|
||||
<div class="kpi-value">{{ props.kpiData.avgDuration }}<span class="kpi-unit">min</span></div>
|
||||
<p>平均通话时长</p>
|
||||
<p>平均通话时长 <i class="info-icon" @mouseenter="showTooltip('avgDuration', $event)" @mouseleave="hideTooltip">ⓘ</i></p>
|
||||
</div>
|
||||
<div class="kpi-item">
|
||||
<div class="kpi-value">{{ props.kpiData.conversionRate }}</div>
|
||||
<p>成交转化率</p>
|
||||
<p>成交转化率 <i class="info-icon" @mouseenter="showTooltip('conversionRate', $event)" @mouseleave="hideTooltip">ⓘ</i></p>
|
||||
</div>
|
||||
<div class="kpi-item">
|
||||
<div class="kpi-value">{{ props.kpiData.assignedData }}</div>
|
||||
<p>本期分配数据</p>
|
||||
<p>本期分配数据 <i class="info-icon" @mouseenter="showTooltip('assignedData', $event)" @mouseleave="hideTooltip">ⓘ</i></p>
|
||||
</div>
|
||||
<div class="kpi-item">
|
||||
<div class="kpi-value">{{ props.kpiData.wechatAddRate }}</div>
|
||||
<p>加微率</p>
|
||||
<p>加微率 <i class="info-icon" @mouseenter="showTooltip('wechatAddRate', $event)" @mouseleave="hideTooltip">ⓘ</i></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -95,10 +95,21 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 指标说明 Tooltip -->
|
||||
<Tooltip
|
||||
:visible="tooltip.visible"
|
||||
:x="tooltip.x"
|
||||
:y="tooltip.y"
|
||||
:title="tooltip.title"
|
||||
:description="tooltip.description"
|
||||
/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Tooltip from '@/components/Tooltip.vue';
|
||||
import { ref, reactive, onMounted, onBeforeUnmount, computed, watch } from 'vue';
|
||||
import StatisticData from './StatisticData.vue';
|
||||
import * as echarts from 'echarts';
|
||||
@@ -155,6 +166,35 @@ const chartInstances = {};
|
||||
const personalFunnelChartCanvas = ref(null);
|
||||
const contactTimeChartCanvas = ref(null);
|
||||
|
||||
// Tooltip 相关数据
|
||||
const tooltip = reactive({
|
||||
visible: false,
|
||||
x: 0,
|
||||
y: 0,
|
||||
title: '',
|
||||
description: ''
|
||||
});
|
||||
|
||||
// 指标说明配置
|
||||
const kpiDescriptions = {
|
||||
successRate: {
|
||||
title: '电话接通率',
|
||||
description: '拨通电话 ÷ 拨打的电话'
|
||||
},
|
||||
avgDuration: {
|
||||
title: '平均通话时长',
|
||||
description: '所有通话总时长 ÷ 拨打电话次数。'
|
||||
},
|
||||
conversionRate: {
|
||||
title: '成交转化率',
|
||||
description: '成交人数 ÷ 本期总数据。'
|
||||
},
|
||||
wechatAddRate: {
|
||||
title: '加微率',
|
||||
description: '加微人数 ÷ 本期数据总人数'
|
||||
}
|
||||
};
|
||||
|
||||
// Chart.js 数据 - 使用props传递的数据
|
||||
const funnelData = computed(() => props.funnelData);
|
||||
const contactTimeData = computed(() => props.contactTimeData);
|
||||
@@ -250,6 +290,22 @@ const getPercentage = (value) => {
|
||||
const getRankingClass = (index) => ({ 'rank-first': index === 0, 'rank-second': index === 1, 'rank-third': index === 2, 'rank-other': index > 2 });
|
||||
const getRankBadgeClass = (index) => ({ 'badge-gold': index === 0, 'badge-silver': index === 1, 'badge-bronze': index === 2, 'badge-default': index > 2 });
|
||||
|
||||
// Tooltip 相关方法
|
||||
const showTooltip = (kpiType, event) => {
|
||||
const description = kpiDescriptions[kpiType];
|
||||
if (description) {
|
||||
tooltip.title = description.title;
|
||||
tooltip.description = description.description;
|
||||
tooltip.x = event.clientX + 10;
|
||||
tooltip.y = event.clientY - 10;
|
||||
tooltip.visible = true;
|
||||
}
|
||||
};
|
||||
|
||||
const hideTooltip = () => {
|
||||
tooltip.visible = false;
|
||||
};
|
||||
|
||||
|
||||
|
||||
watch(() => props.contactTimeData, () => {
|
||||
@@ -433,6 +489,8 @@ $white: #ffffff;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// --- 图表区域 ---
|
||||
.charts-section {
|
||||
display: grid;
|
||||
@@ -649,4 +707,32 @@ $white: #ffffff;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.info-icon {
|
||||
font-style: normal;
|
||||
color: $blue;
|
||||
font-size: 12px;
|
||||
margin-left: 4px;
|
||||
opacity: 0.7;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
color: #007bff;
|
||||
transform: scale(1.2);
|
||||
}
|
||||
}
|
||||
|
||||
.kpi-item:hover .info-icon {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.kpi-item {
|
||||
position: relative;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
</style>
|
||||
@@ -2,72 +2,96 @@
|
||||
<div class="stat-card kpi-card">
|
||||
<h3 class="card-title">统计指标</h3>
|
||||
<div class="kpi-grid stats-grid-inner">
|
||||
<div class="kpi-item stat-item">
|
||||
<div class="stat-icon customer-rate">
|
||||
<i class="el-icon-chat-dot-round"></i>
|
||||
</div>
|
||||
<!-- 所有 .kpi-item 保持不变 -->
|
||||
<div class="kpi-item stat-item" >
|
||||
<div class="stat-icon customer-rate"><i class="el-icon-chat-dot-round"></i></div>
|
||||
<div class="kpi-value">{{ customerCommunicationRate }}</div>
|
||||
<p>活跃客户沟通率</p>
|
||||
</div>
|
||||
<div class="kpi-item stat-item">
|
||||
<div class="stat-icon response-time">
|
||||
<i class="el-icon-timer"></i>
|
||||
<p>活跃客户沟通率 <i class="info-icon" @mouseenter="showTooltip('customerCommunicationRate', $event)" @mouseleave="hideTooltip">ⓘ</i></p>
|
||||
</div>
|
||||
<div class="kpi-item stat-item" >
|
||||
<div class="stat-icon response-time"><i class="el-icon-timer"></i></div>
|
||||
<div class="kpi-value">{{ averageResponseTime }}<span class="kpi-unit">分钟</span></div>
|
||||
<p>平均应答时间</p>
|
||||
</div>
|
||||
<div class="kpi-item stat-item">
|
||||
<div class="stat-icon timeout-rate">
|
||||
<i class="el-icon-warning"></i>
|
||||
<p>平均应答时间 <i class="info-icon" @mouseenter="showTooltip('averageResponseTime', $event)" @mouseleave="hideTooltip">ⓘ</i></p>
|
||||
</div>
|
||||
<div class="kpi-item stat-item" >
|
||||
<div class="stat-icon timeout-rate"><i class="el-icon-warning"></i></div>
|
||||
<div class="kpi-value">{{ timeoutResponseRate }}</div>
|
||||
<p>超时应答率</p>
|
||||
<p>超时应答率 <i class="info-icon" @mouseenter="showTooltip('timeoutResponseRate', $event)" @mouseleave="hideTooltip">ⓘ</i></p>
|
||||
</div>
|
||||
<div class="kpi-item stat-item">
|
||||
<div class="stat-icon severe-timeout-rate">
|
||||
<i class="el-icon-warning-outline"></i>
|
||||
</div>
|
||||
<div class="stat-icon severe-timeout-rate"><i class="el-icon-warning-outline"></i></div>
|
||||
<div class="kpi-value">{{ severeTimeoutRate }}</div>
|
||||
<p>严重超时应答率</p>
|
||||
<p>严重超时应答率 <i class="info-icon" @mouseenter="showTooltip('severeTimeoutRate', $event)" @mouseleave="hideTooltip">ⓘ</i></p>
|
||||
</div>
|
||||
<div class="kpi-item stat-item">
|
||||
<div class="stat-icon form-rate">
|
||||
<i class="el-icon-document"></i>
|
||||
</div>
|
||||
<div class="stat-icon form-rate"><i class="el-icon-document"></i></div>
|
||||
<div class="kpi-value">{{ formCompletionRate }}</div>
|
||||
<p>表格填写率</p>
|
||||
<p>表格填写率 <i class="info-icon" @mouseenter="showTooltip('formCompletionRate', $event)" @mouseleave="hideTooltip">ⓘ</i></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 指标说明 Tooltip -->
|
||||
<Tooltip
|
||||
:visible="tooltip.visible"
|
||||
:x="tooltip.x"
|
||||
:y="tooltip.y"
|
||||
:title="tooltip.title"
|
||||
:description="tooltip.description"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps } from 'vue';
|
||||
import { defineProps, reactive } from 'vue';
|
||||
import Tooltip from '@/components/Tooltip.vue';
|
||||
|
||||
defineProps({
|
||||
customerCommunicationRate: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
averageResponseTime: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
timeoutResponseRate: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
severeTimeoutRate: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
formCompletionRate: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
customerCommunicationRate: { type: Number, default: 0 },
|
||||
averageResponseTime: { type: Number, default: 0 },
|
||||
timeoutResponseRate: { type: Number, default: 0 },
|
||||
severeTimeoutRate: { type: Number, default: 0 },
|
||||
formCompletionRate: { type: Number, default: 0 }
|
||||
});
|
||||
|
||||
const tooltip = reactive({
|
||||
visible: false, // 确保初始值为 false
|
||||
x: 0,
|
||||
y: 0,
|
||||
title: '',
|
||||
description: ''
|
||||
});
|
||||
|
||||
const statDescriptions = {
|
||||
customerCommunicationRate: { title: '活跃客户沟通率', description: '活跃沟通客户数 ÷ 总客户数' },
|
||||
averageResponseTime: { title: '平均应答时间', description: '总应答时间 ÷ 应答次数' },
|
||||
timeoutResponseRate: { title: '超时应答率', description: '超时应答次数 ÷ 总应答次数' },
|
||||
severeTimeoutRate: { title: '严重超时应答率', description: '严重超时应答次数 ÷ 总应答次数' },
|
||||
formCompletionRate: { title: '表格填写率', description: '已填写表格数 ÷ 总表格数' }
|
||||
};
|
||||
|
||||
const showTooltip = (statKey, event) => {
|
||||
console.log('Mouse entered! Firing showTooltip for:', statKey);
|
||||
const description = statDescriptions[statKey];
|
||||
if (description) {
|
||||
tooltip.visible = true;
|
||||
tooltip.x = event.clientX + 10;
|
||||
tooltip.y = event.clientY + 15;
|
||||
tooltip.title = description.title;
|
||||
tooltip.description = description.description;
|
||||
console.log('Tooltip state updated:', JSON.parse(JSON.stringify(tooltip))); // 使用 JSON 序列化来查看快照
|
||||
}
|
||||
};
|
||||
|
||||
const hideTooltip = () => {
|
||||
console.log('Mouse left! Hiding tooltip.');
|
||||
tooltip.visible = false;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* ... 您的样式代码不变 ... */
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
// --- 颜色和变量定义 ---
|
||||
$slate-50: #f8fafc;
|
||||
@@ -157,6 +181,59 @@ $white: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
// Info 图标样式
|
||||
.info-icon {
|
||||
font-size: 12px;
|
||||
margin-left: 4px;
|
||||
opacity: 0.7;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
color: #007bff;
|
||||
transform: scale(1.2);
|
||||
}
|
||||
}
|
||||
|
||||
// Tooltip 样式
|
||||
.stat-tooltip {
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
background: rgba(0, 0, 0, 0.9);
|
||||
color: white;
|
||||
padding: 12px 16px;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
max-width: 300px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||
pointer-events: none;
|
||||
|
||||
.tooltip-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 4px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.tooltip-description {
|
||||
font-size: 13px;
|
||||
color: #e0e0e0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
|
||||
// 统计项悬停效果
|
||||
.stat-item {
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
// --- 响应式设计 ---
|
||||
@media (max-width: 768px) {
|
||||
.stats-grid-inner {
|
||||
|
||||
Reference in New Issue
Block a user