feat(会员详情): 添加指标说明工具提示功能
为会员详情页面的各项指标添加信息图标和工具提示功能,当用户悬停在ⓘ图标上时显示该指标的计算方式和说明。包含总通话次数、通话时长、新增客户、成交单数和转化率五个指标的详细说明。 新增Tooltip组件用于显示提示信息,并实现鼠标跟随定位功能。调整了样式以适配新的信息图标布局。
This commit is contained in:
@@ -11,23 +11,38 @@
|
|||||||
<div class="details-content">
|
<div class="details-content">
|
||||||
<div class="details-grid" v-show="!isDetailsCollapsed" :class="{ 'collapsing': isDetailsCollapsed }">
|
<div class="details-grid" v-show="!isDetailsCollapsed" :class="{ 'collapsing': isDetailsCollapsed }">
|
||||||
<div class="detail-card">
|
<div class="detail-card">
|
||||||
<div class="detail-label">总通话次数</div>
|
<div class="detail-label">
|
||||||
|
总通话次数
|
||||||
|
<span class="info-icon" @mouseenter="showTooltip($event, 'totalCalls')" @mouseleave="hideTooltip">ⓘ</span>
|
||||||
|
</div>
|
||||||
<div class="detail-value">{{ selectedMember.calls || 0 }} 次</div>
|
<div class="detail-value">{{ selectedMember.calls || 0 }} 次</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-card">
|
<div class="detail-card">
|
||||||
<div class="detail-label">通话时长</div>
|
<div class="detail-label">
|
||||||
|
通话时长
|
||||||
|
<span class="info-icon" @mouseenter="showTooltip($event, 'callTime')" @mouseleave="hideTooltip">ⓘ</span>
|
||||||
|
</div>
|
||||||
<div class="detail-value">{{ selectedMember.callTime || 0 }} 小时</div>
|
<div class="detail-value">{{ selectedMember.callTime || 0 }} 小时</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-card">
|
<div class="detail-card">
|
||||||
<div class="detail-label">新增客户</div>
|
<div class="detail-label">
|
||||||
|
新增客户
|
||||||
|
<span class="info-icon" @mouseenter="showTooltip($event, 'newClients')" @mouseleave="hideTooltip">ⓘ</span>
|
||||||
|
</div>
|
||||||
<div class="detail-value">{{ selectedMember.newClients || 0 }} 人</div>
|
<div class="detail-value">{{ selectedMember.newClients || 0 }} 人</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-card">
|
<div class="detail-card">
|
||||||
<div class="detail-label">成交单数</div>
|
<div class="detail-label">
|
||||||
|
成交单数
|
||||||
|
<span class="info-icon" @mouseenter="showTooltip($event, 'deals')" @mouseleave="hideTooltip">ⓘ</span>
|
||||||
|
</div>
|
||||||
<div class="detail-value">{{ selectedMember.deals || 0 }} 单</div>
|
<div class="detail-value">{{ selectedMember.deals || 0 }} 单</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-card">
|
<div class="detail-card">
|
||||||
<div class="detail-label">转化率</div>
|
<div class="detail-label">
|
||||||
|
转化率
|
||||||
|
<span class="info-icon" @mouseenter="showTooltip($event, 'conversionRate')" @mouseleave="hideTooltip">ⓘ</span>
|
||||||
|
</div>
|
||||||
<div class="detail-value">{{ selectedMember.conversion_rate || selectedMember.conversion || '0%' }}</div>
|
<div class="detail-value">{{ selectedMember.conversion_rate || selectedMember.conversion || '0%' }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -104,11 +119,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Tooltip 组件 -->
|
||||||
|
<Tooltip
|
||||||
|
:visible="tooltip.visible"
|
||||||
|
:x="tooltip.x"
|
||||||
|
:y="tooltip.y"
|
||||||
|
:title="tooltip.title"
|
||||||
|
:description="tooltip.description"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, defineProps, watch, nextTick } from 'vue'
|
import { ref, defineProps, watch, nextTick, reactive } from 'vue'
|
||||||
|
import Tooltip from '@/components/Tooltip.vue'
|
||||||
|
|
||||||
// 定义props
|
// 定义props
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -127,6 +152,39 @@ const isGuidanceCollapsed = ref(false)
|
|||||||
// 录音列表折叠状态(默认展开)
|
// 录音列表折叠状态(默认展开)
|
||||||
const isRecordingsCollapsed = ref(false)
|
const isRecordingsCollapsed = ref(false)
|
||||||
|
|
||||||
|
// 工具提示状态
|
||||||
|
const tooltip = reactive({
|
||||||
|
visible: false,
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
title: '',
|
||||||
|
description: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// 指标描述
|
||||||
|
const metricDescriptions = {
|
||||||
|
totalCalls: {
|
||||||
|
title: '总通话次数计算方式',
|
||||||
|
description: '统计该成员在选定时间范围内的所有外呼和接听通话的总次数,包括有效通话和无效通话。'
|
||||||
|
},
|
||||||
|
callTime: {
|
||||||
|
title: '通话时长计算方式',
|
||||||
|
description: '累计该成员所有有效通话的时长,以小时为单位显示,精确到小数点后一位。'
|
||||||
|
},
|
||||||
|
newClients: {
|
||||||
|
title: '新增客户计算方式',
|
||||||
|
description: '统计该成员在选定时间范围内新建档的客户数量,不包括重复录入的客户。'
|
||||||
|
},
|
||||||
|
deals: {
|
||||||
|
title: '成交单数计算方式',
|
||||||
|
description: '统计该成员在选定时间范围内成功签约的订单数量,包括全款和定金订单。'
|
||||||
|
},
|
||||||
|
conversionRate: {
|
||||||
|
title: '转化率计算方式',
|
||||||
|
description: '成交单数 ÷ 新增客户数 × 100%,反映该成员将潜在客户转化为成交客户的能力。'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 切换详细数据折叠状态
|
// 切换详细数据折叠状态
|
||||||
const toggleDetailsCollapse = () => {
|
const toggleDetailsCollapse = () => {
|
||||||
isDetailsCollapsed.value = !isDetailsCollapsed.value
|
isDetailsCollapsed.value = !isDetailsCollapsed.value
|
||||||
@@ -142,6 +200,23 @@ const toggleRecordingsCollapse = () => {
|
|||||||
isRecordingsCollapsed.value = !isRecordingsCollapsed.value
|
isRecordingsCollapsed.value = !isRecordingsCollapsed.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 显示工具提示
|
||||||
|
const showTooltip = (event, metricType) => {
|
||||||
|
const metric = metricDescriptions[metricType]
|
||||||
|
if (metric) {
|
||||||
|
tooltip.title = metric.title
|
||||||
|
tooltip.description = metric.description
|
||||||
|
tooltip.x = event.clientX
|
||||||
|
tooltip.y = event.clientY
|
||||||
|
tooltip.visible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 隐藏工具提示
|
||||||
|
const hideTooltip = () => {
|
||||||
|
tooltip.visible = false
|
||||||
|
}
|
||||||
|
|
||||||
// 格式化金额
|
// 格式化金额
|
||||||
const formatAmount = (amount) => {
|
const formatAmount = (amount) => {
|
||||||
if (typeof amount === 'number') {
|
if (typeof amount === 'number') {
|
||||||
@@ -349,6 +424,25 @@ watch(() => props.selectedMember, () => {
|
|||||||
color: #64748b;
|
color: #64748b;
|
||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.25rem;
|
||||||
|
|
||||||
|
.info-icon {
|
||||||
|
color: #94a3b8;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0.7;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
margin-left: 0.25rem;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
color: #3b82f6;
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.detail-value {
|
.detail-value {
|
||||||
|
|||||||
Reference in New Issue
Block a user