feat(中心概览): 实现中心概览组件数据动态绑定

将静态数据替换为通过props传入的动态数据,并更新API端点名称
This commit is contained in:
2025-08-14 22:14:03 +08:00
parent 7a7b114b35
commit 814961d84a
3 changed files with 824 additions and 1156 deletions

View File

@@ -7,7 +7,7 @@ export const getOverallCenterPerformance = (params) => {
// 活跃组数 /api/v1/level_four/overview/total_group_count
export const getTotalGroupCount = (params) => {
return https.post('/api/v1/level_four/overview/total_group_count', params)
return https.post('/api/v1/level_four/overview/total_team_count', params)
}
// 中心转化率 /api/v1/level_four/overview/center_conversion_rate

View File

@@ -5,55 +5,55 @@
<div class="overview-card primary">
<div class="card-header">
<span class="card-title">中心总业绩</span>
<span class="card-trend positive">+12% vs 上期</span>
<span class="card-trend positive">{{ props.overallData.CenterPerformance?.center_monthly_vs_previous_deals }} vs 上期</span>
</div>
<div class="card-value">552,000 </div>
<div class="card-subtitle">月目标完成率: 56%</div>
<div class="card-value">{{ props.overallData.CenterPerformance.center_monthly_deal_count || '552,000' }} </div>
<div class="card-subtitle">月目标完成率: {{ props.overallData.CenterPerformance?.center_monthly_target_completion_rate || '56%' }}</div>
</div>
<div class="overview-card">
<div class="card-header">
<span class="card-title">活跃组数</span>
<span class="card-trend stable">5/5 </span>
<span class="card-trend stable">{{ props.overallData.TotalGroupCount?.center_total_team_count}}/{{ props.overallData.TotalGroupCount?.center_total_team_count }} </span>
</div>
<div class="card-value">5 </div>
<div class="card-subtitle">总人数: 40</div>
<div class="card-value">{{ props.overallData.TotalGroupCount?.center_total_team_count || '5' }} </div>
<div class="card-subtitle">总人数: {{ props.overallData.TotalGroupCount?.center_total_user_count || '40' }}</div>
</div>
<div class="overview-card">
<div class="card-header">
<span class="card-title">中心转化率</span>
<span class="card-trend positive">+0.3% vs 上期</span>
<span class="card-trend positive">{{ props.overallData.CenterConversionRate?.center_monthly_vs_previous_deals }}vs 上期</span>
</div>
<div class="card-value">5.2%</div>
<div class="card-subtitle">行业平均: 4.8%</div>
<div class="card-value">{{ props.overallData.CenterConversionRate?.center_conversion_rate || '5.2' }}</div>
<div class="card-subtitle">行业平均: {{ props.overallData.CenterConversionRate?.current_user_center_conversion_rate || '4.8' }}</div>
</div>
<div class="overview-card">
<div class="card-header">
<span class="card-title">总通话次数</span>
<span class="card-trend positive">+8% vs 上期</span>
<span class="card-trend positive">{{ props.overallData.TotalCallCount?.total_call_count_vs_yesterday}} vs 上期</span>
</div>
<div class="card-value">1,247 </div>
<div class="card-subtitle">有效通话: 892</div>
<div class="card-value">{{ props.overallData.TotalCallCount?.total_call_count || '1,247' }} </div>
<div class="card-subtitle">有效通话: {{ props.overallData.TotalCallCount?.center_effective_call_count || '892' }}</div>
</div>
<div class="overview-card">
<div class="card-header">
<span class="card-title">新增客户</span>
<span class="card-trend positive">+15% vs 上期</span>
<span class="card-trend positive">{{ props.overallData.NewCustomer?.center_new_leads_vs_previous_period }} vs 上期</span>
</div>
<div class="card-value">117 </div>
<div class="card-subtitle">意向客户: 89</div>
<div class="card-value">{{ props.overallData.NewCustomer?.center_new_leads_count || '117' }} </div>
<div class="card-subtitle">意向客户: {{ props.overallData.NewCustomer?.center_new_v_customer_count || '89' }}</div>
</div>
<div class="overview-card">
<div class="card-header">
<span class="card-title">定金转化</span>
<span class="card-trend positive">+18% vs 上期</span>
<span class="card-trend positive">{{ props.overallData.DepositConversionRate?.center_deposit_conversion_vs_previous }} vs 上期</span>
</div>
<div class="card-value">40 </div>
<div class="card-subtitle">平均定金转化率: 13,800</div>
<div class="card-value">{{ props.overallData.DepositConversionRate?.center_current_deposit_conversion_rate || '0' }} </div>
<div class="card-subtitle">平均定金转化率: {{ props.overallData.DepositConversionRate?.center_monthly_deposit_conversion_rate || '0' }}</div>
</div>
</div>
@@ -62,6 +62,19 @@
<script setup>
// 中心整体概览组件
const props = defineProps({
overallData: {
type: Object,
default: () => ({
CenterPerformance: {},
TotalGroupCount: {},
CenterConversionRate: {},
TotalCallCount: {},
NewCustomer: {},
DepositConversionRate: {}
})
}
})
</script>
<style lang="scss" scoped>

View File

@@ -14,21 +14,11 @@
<span class="stage-label">营期所属阶段</span>
<span class="stage-value">接数据</span>
</div>
<!-- 头像 -->
<div
class="header-ringht"
style="display: flex; align-items: center; gap: 10px;margin-left: auto;"
>
<img
src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png"
alt="用户头像"
class="avatar"
@error="handleAvatarError"
style="width: 35px; height: 35px"
/>
<span>你好管理员</span>
<div>
<!-- 用户下拉菜单 -->
<UserDropdown />
</div>
</div>
</div>
</header>
@@ -37,7 +27,7 @@
<!-- Top Section - Center Overview and Action Items -->
<div class="top-section">
<!-- Center Performance Overview -->
<CenterOverview />
<CenterOverview :overall-data="overallCenterPerformance" />
<!-- Action Items (Compact) -->
<div class="action-items-compact">
@@ -50,17 +40,13 @@
<!-- 优秀录音 -->
<GoodMusic />
<!-- 客户问题排行 -->
<ProblemRanking />
<ProblemRanking :ranking-data="formattedUrgentNeedData" />
</div>
<!-- Bottom Section -->
<div class="bottom-section">
<!-- Left Section - Group Performance Ranking -->
<div class="left-section">
<GroupRanking
:groups="groups"
:selected-group="selectedGroup"
@select-group="selectGroup"
/>
<GroupRanking :groups="groups" :selected-group="selectedGroup" @select-group="selectGroup" />
</div>
<!-- Right Section - Group Comparison -->
@@ -95,12 +81,8 @@
</div>
<div class="members-grid">
<div
v-for="member in selectedGroup.members"
:key="member.id"
class="member-card"
:class="getStatusClass(member.status)"
>
<div v-for="member in selectedGroup.members" :key="member.id" class="member-card"
:class="getStatusClass(member.status)">
<div class="member-header">
<div class="member-info">
<h3 class="member-name">{{ member.name }}</h3>
@@ -156,7 +138,8 @@
</template>
<script setup>
import { ref } from 'vue'
import { ref, onMounted, computed } from 'vue'
import CenterOverview from './components/CenterOverview.vue'
import GroupComparison from './components/GroupComparison.vue'
import GroupRanking from './components/GroupRanking.vue'
@@ -166,520 +149,16 @@ import CustomerType from './components/CustomerType.vue'
import GoodMusic from './components/GoodMusic.vue'
import ProblemRanking from './components/ProblemRanking.vue'
import seniorManager from './components/seniorManager.vue'
import {getOverallCenterPerformance,getTotalGroupCount,getCenterConversionRate,getTotalCallCount,getNewCustomer
import UserDropdown from '@/components/UserDropdown.vue'
import {
getOverallCenterPerformance, getTotalGroupCount, getCenterConversionRate, getTotalCallCount, getNewCustomer
, getDepositConversionRate, getCustomerTypeDistribution, getUrgentNeedToAddress, getCenterAdvancedManagerList, getTeamRanking, getTeamRankingInfo
} from '@/api/secondTop.js'
import { useRouter } from 'vue-router'
import { useUserStore } from '@/stores/user.js'
// 组别数据
const groups = [
{
id: 1,
name: '精英组',
leader: '李主管',
memberCount: 8,
todayPerformance: 156000,
monthlyTarget: 800000,
monthlyProgress: 65,
conversionRate: 6.8,
avgCallTime: 7.2,
newClients: 28,
deals: 12,
status: 'excellent',
trend: 'up',
alerts: [],
members: [
{
id: 1,
name: '张小明',
position: '高级销售',
phone: '138****1234',
todayPerformance: 25000,
monthlyPerformance: 180000,
conversionRate: 8.2,
callCount: 45,
newClients: 6,
deals: 3,
status: 'excellent',
joinDate: '2022-03-15'
},
{
id: 2,
name: '王丽华',
position: '销售专员',
phone: '139****5678',
todayPerformance: 22000,
monthlyPerformance: 165000,
conversionRate: 7.5,
callCount: 38,
newClients: 5,
deals: 2,
status: 'excellent',
joinDate: '2021-08-20'
},
{
id: 3,
name: '刘强东',
position: '销售专员',
phone: '137****9012',
todayPerformance: 18000,
monthlyPerformance: 142000,
conversionRate: 6.8,
callCount: 42,
newClients: 4,
deals: 2,
status: 'good',
joinDate: '2022-01-10'
},
{
id: 4,
name: '陈美玲',
position: '销售专员',
phone: '136****3456',
todayPerformance: 20000,
monthlyPerformance: 158000,
conversionRate: 7.1,
callCount: 40,
newClients: 5,
deals: 2,
status: 'good',
joinDate: '2021-11-05'
},
{
id: 5,
name: '赵志伟',
position: '销售专员',
phone: '135****7890',
todayPerformance: 16000,
monthlyPerformance: 125000,
conversionRate: 6.2,
callCount: 35,
newClients: 3,
deals: 1,
status: 'good',
joinDate: '2022-05-18'
},
{
id: 6,
name: '孙晓燕',
position: '销售专员',
phone: '134****2345',
todayPerformance: 19000,
monthlyPerformance: 148000,
conversionRate: 6.9,
callCount: 37,
newClients: 4,
deals: 2,
status: 'good',
joinDate: '2021-12-12'
},
{
id: 7,
name: '周建华',
position: '销售专员',
phone: '133****6789',
todayPerformance: 17000,
monthlyPerformance: 135000,
conversionRate: 6.5,
callCount: 33,
newClients: 3,
deals: 1,
status: 'good',
joinDate: '2022-02-28'
},
{
id: 8,
name: '吴雅琴',
position: '销售专员',
phone: '132****0123',
todayPerformance: 19000,
monthlyPerformance: 152000,
conversionRate: 7.0,
callCount: 39,
newClients: 4,
deals: 2,
status: 'good',
joinDate: '2021-09-15'
}
]
},
{
id: 2,
name: '冲锋组',
leader: '张主管',
memberCount: 10,
todayPerformance: 142000,
monthlyTarget: 900000,
monthlyProgress: 58,
conversionRate: 5.9,
avgCallTime: 6.8,
newClients: 32,
deals: 10,
status: 'good',
trend: 'up',
alerts: ['需要加强追单环节'],
members: [
{
id: 9,
name: '李建国',
position: '高级销售',
phone: '138****4567',
todayPerformance: 18000,
monthlyPerformance: 145000,
conversionRate: 6.8,
callCount: 42,
newClients: 4,
deals: 2,
status: 'good',
joinDate: '2021-06-10'
},
{
id: 10,
name: '马晓丽',
position: '销售专员',
phone: '139****8901',
todayPerformance: 16000,
monthlyPerformance: 128000,
conversionRate: 6.2,
callCount: 38,
newClients: 3,
deals: 1,
status: 'good',
joinDate: '2022-04-22'
},
{
id: 11,
name: '杨志强',
position: '销售专员',
phone: '137****2345',
todayPerformance: 14000,
monthlyPerformance: 112000,
conversionRate: 5.8,
callCount: 35,
newClients: 3,
deals: 1,
status: 'average',
joinDate: '2022-07-08'
},
{
id: 12,
name: '黄美娟',
position: '销售专员',
phone: '136****6789',
todayPerformance: 15000,
monthlyPerformance: 120000,
conversionRate: 6.0,
callCount: 36,
newClients: 3,
deals: 1,
status: 'good',
joinDate: '2021-10-30'
},
{
id: 13,
name: '林志华',
position: '销售专员',
phone: '135****0123',
todayPerformance: 13000,
monthlyPerformance: 105000,
conversionRate: 5.5,
callCount: 32,
newClients: 2,
deals: 1,
status: 'average',
joinDate: '2022-08-15'
},
{
id: 14,
name: '郑小芳',
position: '销售专员',
phone: '134****4567',
todayPerformance: 14000,
monthlyPerformance: 115000,
conversionRate: 5.9,
callCount: 34,
newClients: 3,
deals: 1,
status: 'good',
joinDate: '2021-12-05'
},
{
id: 15,
name: '何建明',
position: '销售专员',
phone: '133****8901',
todayPerformance: 12000,
monthlyPerformance: 98000,
conversionRate: 5.2,
callCount: 30,
newClients: 2,
deals: 0,
status: 'attention',
joinDate: '2022-09-20'
},
{
id: 16,
name: '谢雅琳',
position: '销售专员',
phone: '132****2345',
todayPerformance: 15000,
monthlyPerformance: 122000,
conversionRate: 6.1,
callCount: 37,
newClients: 4,
deals: 1,
status: 'good',
joinDate: '2021-07-18'
},
{
id: 17,
name: '罗志勇',
position: '销售专员',
phone: '131****6789',
todayPerformance: 13000,
monthlyPerformance: 108000,
conversionRate: 5.6,
callCount: 33,
newClients: 3,
deals: 1,
status: 'average',
joinDate: '2022-06-12'
},
{
id: 18,
name: '蔡美华',
position: '销售专员',
phone: '130****0123',
todayPerformance: 12000,
monthlyPerformance: 102000,
conversionRate: 5.4,
callCount: 31,
newClients: 2,
deals: 1,
status: 'average',
joinDate: '2022-03-25'
}
]
},
{
id: 3,
name: '突破组',
leader: '王主管',
memberCount: 7,
todayPerformance: 89000,
monthlyTarget: 700000,
monthlyProgress: 45,
conversionRate: 4.2,
avgCallTime: 5.5,
newClients: 18,
deals: 6,
status: 'warning',
trend: 'down',
alerts: ['转化率偏低', '通话时长不足'],
members: [
{
id: 19,
name: '徐志强',
position: '销售专员',
phone: '138****7890',
todayPerformance: 15000,
monthlyPerformance: 118000,
conversionRate: 5.2,
callCount: 28,
newClients: 3,
deals: 1,
status: 'average',
joinDate: '2022-01-20'
},
{
id: 20,
name: '袁美丽',
position: '销售专员',
phone: '139****1234',
todayPerformance: 13000,
monthlyPerformance: 95000,
conversionRate: 4.8,
callCount: 25,
newClients: 2,
deals: 1,
status: 'attention',
joinDate: '2022-05-08'
},
{
id: 21,
name: '冯建华',
position: '销售专员',
phone: '137****5678',
todayPerformance: 12000,
monthlyPerformance: 88000,
conversionRate: 4.2,
callCount: 22,
newClients: 2,
deals: 0,
status: 'attention',
joinDate: '2022-08-30'
},
{
id: 22,
name: '邓小芳',
position: '销售专员',
phone: '136****9012',
todayPerformance: 11000,
monthlyPerformance: 82000,
conversionRate: 3.9,
callCount: 20,
newClients: 2,
deals: 1,
status: 'attention',
joinDate: '2022-09-15'
},
{
id: 23,
name: '韩志明',
position: '销售专员',
phone: '135****3456',
todayPerformance: 14000,
monthlyPerformance: 105000,
conversionRate: 4.6,
callCount: 26,
newClients: 3,
deals: 1,
status: 'average',
joinDate: '2021-11-22'
},
{
id: 24,
name: '曾雅琴',
position: '销售专员',
phone: '134****7890',
todayPerformance: 12000,
monthlyPerformance: 92000,
conversionRate: 4.1,
callCount: 23,
newClients: 2,
deals: 1,
status: 'attention',
joinDate: '2022-04-10'
},
{
id: 25,
name: '彭建国',
position: '销售专员',
phone: '133****1234',
todayPerformance: 12000,
monthlyPerformance: 90000,
conversionRate: 4.0,
callCount: 21,
newClients: 2,
deals: 1,
status: 'attention',
joinDate: '2022-07-05'
}
]
},
{
id: 4,
name: '新星组',
leader: '赵主管',
memberCount: 6,
todayPerformance: 67000,
monthlyTarget: 600000,
monthlyProgress: 38,
conversionRate: 3.8,
avgCallTime: 4.9,
newClients: 15,
deals: 4,
status: 'attention',
trend: 'stable',
alerts: ['新人培训需加强', '客户跟进不及时'],
members: [
{
id: 26,
name: '廖志华',
position: '销售专员',
phone: '138****5678',
todayPerformance: 12000,
monthlyPerformance: 85000,
conversionRate: 4.2,
callCount: 18,
newClients: 3,
deals: 1,
status: 'attention',
joinDate: '2022-10-15'
},
{
id: 27,
name: '范美玲',
position: '销售专员',
phone: '139****9012',
todayPerformance: 11000,
monthlyPerformance: 78000,
conversionRate: 3.8,
callCount: 16,
newClients: 2,
deals: 0,
status: 'attention',
joinDate: '2022-11-20'
},
{
id: 28,
name: '方建明',
position: '销售专员',
phone: '137****3456',
todayPerformance: 10000,
monthlyPerformance: 72000,
conversionRate: 3.5,
callCount: 15,
newClients: 2,
deals: 1,
status: 'poor',
joinDate: '2022-12-08'
},
{
id: 29,
name: '石雅芳',
position: '销售专员',
phone: '136****7890',
todayPerformance: 11000,
monthlyPerformance: 80000,
conversionRate: 3.9,
callCount: 17,
newClients: 3,
deals: 1,
status: 'attention',
joinDate: '2022-09-28'
},
{
id: 30,
name: '姚志勇',
position: '销售专员',
phone: '135****1234',
todayPerformance: 12000,
monthlyPerformance: 88000,
conversionRate: 4.0,
callCount: 19,
newClients: 3,
deals: 1,
status: 'attention',
joinDate: '2022-08-12'
},
{
id: 31,
name: '汤美华',
position: '销售专员',
phone: '134****5678',
todayPerformance: 11000,
monthlyPerformance: 82000,
conversionRate: 3.7,
callCount: 16,
newClients: 2,
deals: 0,
status: 'attention',
joinDate: '2022-10-30'
}
]
}
]
const groups = ref([])
// 路由实例
const router = useRouter();
// 用户store实例
@@ -703,20 +182,178 @@ const getRequestParams = () => {
}
// 中心整体概览
const overallCenterPerformance = ref({
CenterPerformance: {},
TotalGroupCount: {},
CenterConversionRate: {},
TotalCallCount: {},
NewCustomer: {},
DepositConversionRate: {}
})
// 客户类型
const customerTypeDistribution = ref({})
// 迫切解决的问题
const urgentNeedToAddress = ref({})
// 格式化迫切解决问题数据为组件所需格式
const formattedUrgentNeedData = computed(() => {
if (urgentNeedToAddress.value && urgentNeedToAddress.value.center_urgent_issue_ratio) {
return Object.entries(urgentNeedToAddress.value.center_urgent_issue_ratio).map(([name, value]) => ({
name,
value
}))
}
return []
})
// 中心总业绩
async function CenterOverallCenterPerformance() {
const params = getRequestParams()
const hasParams = params.user_name
try {
const res = await getOverallCenterPerformance(params)
const res = await getOverallCenterPerformance(hasParams ? params : undefined)
if (res.code === 200) {
overallCenterPerformance.value = res.data
overallCenterPerformance.value.CenterPerformance = res.data
}
} catch (error) {
console.error('获取中心整体概览失败:', error)
}
}
// 活跃组数
async function CenterTotalGroupCount() {
const params = getRequestParams()
const hasParams = params.user_name
try {
const res = await getTotalGroupCount(hasParams ? params : undefined)
if (res.code === 200) {
overallCenterPerformance.value.TotalGroupCount = res.data
}
} catch (error) {
console.error('获取中心整体概览失败:', error)
}
}
// 中心转化率
async function CenterConversionRate() {
const params = getRequestParams()
const hasParams = params.user_name
try {
const res = await getCenterConversionRate(hasParams ? params : undefined)
if (res.code === 200) {
overallCenterPerformance.value.CenterConversionRate = res.data
}
} catch (error) {
console.error('获取中心整体概览失败:', error)
}
}
// 中心通话次数
async function CenterTotalCallCount() {
const params = getRequestParams()
const hasParams = params.user_name
try {
const res = await getTotalCallCount(hasParams ? params : undefined)
if (res.code === 200) {
overallCenterPerformance.value.TotalCallCount = res.data
}
} catch (error) {
console.error('获取中心整体概览失败:', error)
}
}
// 新增客户
async function CenterNewCustomer() {
const params = getRequestParams()
const hasParams = params.user_name
try {
const res = await getNewCustomer(hasParams ? params : undefined)
if (res.code === 200) {
overallCenterPerformance.value.NewCustomer = res.data
}
} catch (error) {
console.error('获取中心整体概览失败:', error)
}
}
// 定金转化率
async function CenterDepositConversionRate() {
const params = getRequestParams()
const hasParams = params.user_name
try {
const res = await getDepositConversionRate(hasParams ? params : undefined)
if (res.code === 200) {
overallCenterPerformance.value.DepositConversionRate = res.data
}
} catch (error) {
console.error('获取中心整体概览失败:', error)
}
}
// 客户类型
async function CenterCustomerType() {
const params = getRequestParams()
const hasParams = params.user_name
try {
const res = await getCustomerTypeDistribution(hasParams ? params : undefined)
if (res.code === 200) {
customerTypeDistribution.value = res.data
}
} catch (error) {
console.error('获取中心整体概览失败:', error)
}
}
// 客户迫切解决的问题
async function CenterUrgentNeedToAddress() {
const params = getRequestParams()
const hasParams = params.user_name
try {
const res = await getUrgentNeedToAddress(hasParams ? params : undefined)
if (res.code === 200) {
urgentNeedToAddress.value = res.data
/**
* data
:
{user_name: "刘瑞", user_level: 4,…}
center_urgent_issue_counts
:
{成绩提升: 1, 少玩手机: 1, 回归学校: 0, 心理健康: 0}
回归学校
:
0
少玩手机
:
1
心理健康
:
0
成绩提升
:
1
center_urgent_issue_ratio
:
{成绩提升: "50.00%", 少玩手机: "50.00%", 回归学校: "0.00%", 心理健康: "0.00%"}
回归学校
:
"0.00%"
少玩手机
:
"50.00%"
心理健康
:
"0.00%"
成绩提升
:
"50.00%"
user_level
:
4
user_name
:
"刘瑞"
*/
}
} catch (error) {
console.error('获取中心整体概览失败:', error)
}
}
// 当前选中的组别,默认为第一个
const selectedGroup = ref(groups[0])
@@ -750,6 +387,18 @@ const getStatusText = (status) => {
}
return statusMap[status] || '未知'
}
onMounted(async () => {
await CenterOverallCenterPerformance()
await CenterTotalGroupCount()
await CenterConversionRate()
await CenterTotalCallCount()
await CenterNewCustomer()
await CenterDepositConversionRate()
await CenterCustomerType()
await CenterUrgentNeedToAddress()
})
</script>
<style lang="scss" scoped>
@@ -773,6 +422,7 @@ const getStatusText = (status) => {
.logo-section {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
}
@@ -836,7 +486,8 @@ const getStatusText = (status) => {
margin-top: 1rem;
}
.left-section, .right-section {
.left-section,
.right-section {
display: flex;
flex-direction: column;
gap: 1rem;
@@ -940,7 +591,9 @@ const getStatusText = (status) => {
.action-footer {
.action-buttons {
.btn-edit, .btn-delete {
.btn-edit,
.btn-delete {
padding: 0.25rem 0.5rem;
font-size: 0.7rem;
}
@@ -1252,7 +905,9 @@ const getStatusText = (status) => {
gap: 1rem;
.summary-item {
.label, .value {
.label,
.value {
font-size: 0.8rem;
}
}