refactor(manager): 优化团队成员详情和预警处理逻辑

- 移除硬编码的团队成员数据,改为从API获取
- 添加可选链操作符处理可能为空的成员数据
- 重构异常预警处理逻辑,动态生成预警消息
- 调整UI组件间距和样式
- 清理无用注释和代码
This commit is contained in:
2025-08-26 14:55:05 +08:00
parent 6779db176c
commit 14ee188856
4 changed files with 57 additions and 108 deletions

View File

@@ -1,7 +1,7 @@
<template>
<div class="member-details">
<div class="details-header" @click="toggleDetailsCollapse">
<h2>{{ selectedMember.user_name || selectedMember.name }} 的详细数据</h2>
<h2>{{ selectedMember?.user_name || selectedMember?.name||'张三' }} 的详细数据</h2>
<div class="collapse-toggle" :class="{ 'collapsed': isDetailsCollapsed }">
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
<path d="M8 4l4 4H4l4-4z"/>
@@ -15,35 +15,35 @@
总通话次数
<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 class="detail-card">
<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 class="detail-card">
<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 class="detail-card">
<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 class="detail-card">
<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>
@@ -115,7 +115,7 @@
<div class="no-recordings" v-else>
<div class="no-data-icon">📞</div>
<h4>暂无录音</h4>
<p>{{ selectedMember.user_name || selectedMember.name }} 还没有通话录音记录</p>
<p>{{ selectedMember?.user_name || selectedMember?.name || '张三' }} 还没有通话录音记录</p>
</div>
</div>
</div>
@@ -259,7 +259,7 @@ const getRecordingsForMember = (member) => {
]
// 根据成员ID返回对应的录音这里简化处理
return recordings.slice(0, Math.min(3, member.calls || 0))
return recordings.slice(0, Math.min(3, member?.calls || 0))
}
// 下载录音文件

View File

@@ -62,7 +62,6 @@ const aggregatedAlerts = computed(() => {
.alert-list {
display: flex;
flex-direction: column;
gap: 0.75rem;
max-height: 270px;
overflow-y: auto;
@@ -85,12 +84,11 @@ const aggregatedAlerts = computed(() => {
}
}
}
.alert-item {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.75rem;
gap: 0.2rem;
padding: 0.25rem;
border-radius: 8px;
font-size: 0.9rem;

View File

@@ -95,54 +95,6 @@ const teamMembers = [
newClients: 12,
deals: 5,
avgDealValue: 24000,
},
{
id: 2,
name: "张明",
rank: 2,
performance: 85000,
conversion: 5.0,
calls: 142,
callTime: 6.2,
newClients: 8,
deals: 3,
avgDealValue: 28333,
},
{
id: 3,
name: "王强",
rank: 3,
performance: 65000,
conversion: 4.0,
calls: 128,
callTime: 5.8,
newClients: 6,
deals: 2,
avgDealValue: 32500,
},
{
id: 4,
name: "赵静",
rank: 4,
performance: 0,
conversion: 0.0,
calls: 89,
callTime: 3.2,
newClients: 2,
deals: 0,
avgDealValue: 0,
},
{
id: 5,
name: "刘洋",
rank: 5,
performance: 0,
conversion: 0.0,
calls: 76,
callTime: 2.8,
newClients: 1,
deals: 0,
avgDealValue: 0,
}
];
@@ -199,10 +151,46 @@ const groupAbnormalResponse = ref({})
async function TeamGetGroupAbnormalResponse() {
const params = getRequestParams()
const hasParams = params.user_name
const res = await getGroupAbnormalResponse(hasParams ? params : undefined)
console.log(res)
if (res.code === 200) {
groupAbnormalResponse.value = res.data
try {
const response = await getGroupAbnormalResponse(hasParams ? params : undefined)
const rawData = response.data
// 转换数据格式,生成预警消息
const processedAlerts = []
let alertId = 1
// 处理严重超时异常人员
const timeoutPersons = rawData.erious_timeout_rate_abnorma || []
// 处理表格填写异常人员
const fillingPersons = rawData.table_filling_abnormal || []
// 为每个异常人员生成独立的预警消息
// 处理严重超时率异常人员
timeoutPersons.forEach(person => {
processedAlerts.push({
id: `timeout-${alertId++}`,
type: 'warning',
icon: '⚠',
message: `${person}严重超时率过高`
})
})
// 处理表格填写率异常人员
fillingPersons.forEach(person => {
processedAlerts.push({
id: `filling-${alertId++}`,
type: 'warning',
icon: '⚠',
message: `${person}表格填写率过低`
})
})
// 设置处理后的数据
groupAbnormalResponse.value = { processedAlerts }
} catch (error) {
console.error('获取团队异常预警失败:', error)
}
}
// 团队总通话
@@ -281,57 +269,22 @@ async function TeamGetGroupRanking() {
console.log(res)
if (res.code === 200) {
groupRanking.value = res.data
/**
* "data": {
"user_name": "马然",
"user_level": 2,
"team_data": {
"group_list": [
{
"user_name": "马然",
"week_amount": 0,
"conversion_rate": "0%",
"plus_v_rate": "0%",
"group_rate": "0%"
},
{
"user_name": "程慧仟",
"week_amount": 7100.0,
"conversion_rate": "0.00%",
"plus_v_rate": "0.00%",
"group_rate": "0.00%"
},
{
"user_name": "常琳",
"week_amount": 14500.0,
"conversion_rate": "3.51%",
"plus_v_rate": "54.39%",
"group_rate": "49.12%"
},
{
"user_name": "王娟娟",
"week_amount": 600.0,
"conversion_rate": "0.00%",
"plus_v_rate": "3.08%",
"group_rate": "0.00%"
}
]
}
}
*/
}
}
// 成员详细数据
const memberDetails = ref({})
// 当前选中的成员,默认为第一名
const selectedMember = ref(teamMembers[0]);
// 当前选中的成员,默认为
const selectedMember = ref(null);
// 选择成员函数
const selectMember = (member) => {
selectedMember.value = member;
};
// 团队异常预警
onMounted(async () => {
await TeamGetGroupAbnormalResponse()
await TeamGetWeekTotalCall()
@@ -340,7 +293,6 @@ onMounted(async () => {
await TeamGetWeekAddFeeTotal()
await TeamGetGroupFunnel()
await TeamGetGroupRanking()
})
</script>