feat(GroupComparison): 添加动态组别列表功能并优化显示
- 新增groupList属性支持动态加载组别数据 - 实现根据高级经理选择过滤组别功能 - 移除静态综合分显示并优化滚动条样式 - 添加数据处理逻辑支持嵌套API响应结构
This commit is contained in:
@@ -28,10 +28,6 @@
|
|||||||
<div class="group-name">{{ group.name }}</div>
|
<div class="group-name">{{ group.name }}</div>
|
||||||
<div class="group-leader">{{ group.leader }}</div>
|
<div class="group-leader">{{ group.leader }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="performance-score">
|
|
||||||
<div class="score">{{ calculateScore(group) }}</div>
|
|
||||||
<div class="score-label">综合分</div>
|
|
||||||
</div>
|
|
||||||
<div class="key-metrics">
|
<div class="key-metrics">
|
||||||
<div class="mini-metric">
|
<div class="mini-metric">
|
||||||
<span class="mini-label">业绩</span>
|
<span class="mini-label">业绩</span>
|
||||||
@@ -55,9 +51,13 @@ import { ref, computed } from 'vue'
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
groups: {
|
groups: {
|
||||||
type: Array,
|
type: Array,
|
||||||
required: true
|
default: () => []
|
||||||
},
|
},
|
||||||
seniorManagerData: {
|
seniorManagerData: {
|
||||||
|
type: Object,
|
||||||
|
default: () => null
|
||||||
|
},
|
||||||
|
groupList: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
}
|
}
|
||||||
@@ -77,11 +77,7 @@ const seniorManagers = computed(() => {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
{ id: 'manager1', name: '张经理' },
|
{ id: 'manager1', name: '张经理' }
|
||||||
{ id: 'manager2', name: '李经理' },
|
|
||||||
{ id: 'manager3', name: '王经理' },
|
|
||||||
{ id: 'manager4', name: '刘经理' },
|
|
||||||
{ id: 'manager5', name: '陈经理' }
|
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -90,9 +86,118 @@ const handleManagerChange = () => {
|
|||||||
emit('manager-change', selectedManager.value)
|
emit('manager-change', selectedManager.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理 groupList 数据
|
||||||
|
const processedGroups = computed(() => {
|
||||||
|
console.log('GroupList data:', props.groupList)
|
||||||
|
|
||||||
|
if (!props.groupList || Object.keys(props.groupList).length === 0) {
|
||||||
|
return props.groups || []
|
||||||
|
}
|
||||||
|
|
||||||
|
const groups = []
|
||||||
|
|
||||||
|
// 处理 composition_transformation 数据
|
||||||
|
if (props.groupList.composition_transformation) {
|
||||||
|
console.log('Processing composition_transformation:', props.groupList.composition_transformation)
|
||||||
|
Object.entries(props.groupList.composition_transformation).forEach(([managerName, teamData]) => {
|
||||||
|
console.log('Manager:', managerName, 'TeamData:', teamData, 'Type:', typeof teamData)
|
||||||
|
|
||||||
|
// 处理嵌套对象结构
|
||||||
|
if (typeof teamData === 'object' && teamData !== null) {
|
||||||
|
Object.entries(teamData).forEach(([teamName, rate]) => {
|
||||||
|
// 解析团队名称,如"星耀三部-周毅"拆分为部门和经理
|
||||||
|
const parts = teamName.split('-')
|
||||||
|
let groupName, leaderName
|
||||||
|
|
||||||
|
if (parts.length >= 2) {
|
||||||
|
// 处理包含双横线的情况,如"巅峰三部--刘东洋"
|
||||||
|
if (teamName.includes('--')) {
|
||||||
|
const doubleDashParts = teamName.split('--')
|
||||||
|
groupName = doubleDashParts[0]
|
||||||
|
leaderName = doubleDashParts[1]
|
||||||
|
} else {
|
||||||
|
// 处理单横线的情况,如"星耀三部-周毅"
|
||||||
|
groupName = parts[0]
|
||||||
|
leaderName = parts.slice(1).join('-')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
groupName = teamName
|
||||||
|
leaderName = managerName
|
||||||
|
}
|
||||||
|
|
||||||
|
groups.push({
|
||||||
|
id: `${managerName}-${teamName}`,
|
||||||
|
name: groupName,
|
||||||
|
leader: leaderName,
|
||||||
|
conversionRate: parseFloat(rate) || 0,
|
||||||
|
todayPerformance: 0, // 默认值
|
||||||
|
newClients: 0, // 默认值
|
||||||
|
deals: 0 // 默认值
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else if (typeof teamData === 'string') {
|
||||||
|
// 处理直接字符串值的情况(选择具体经理时可能出现)
|
||||||
|
// 解析团队名称,如"星耀三部-周毅"拆分为部门和经理
|
||||||
|
const parts = managerName.split('-')
|
||||||
|
let groupName, leaderName
|
||||||
|
|
||||||
|
if (parts.length >= 2) {
|
||||||
|
// 处理包含双横线的情况,如"巅峰三部--刘东洋"
|
||||||
|
if (managerName.includes('--')) {
|
||||||
|
const doubleDashParts = managerName.split('--')
|
||||||
|
groupName = doubleDashParts[0]
|
||||||
|
leaderName = doubleDashParts[1]
|
||||||
|
} else {
|
||||||
|
// 处理单横线的情况,如"星耀三部-周毅"
|
||||||
|
groupName = parts[0]
|
||||||
|
leaderName = parts.slice(1).join('-')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
groupName = managerName
|
||||||
|
leaderName = managerName
|
||||||
|
}
|
||||||
|
|
||||||
|
groups.push({
|
||||||
|
id: `${managerName}`,
|
||||||
|
name: groupName,
|
||||||
|
leader: leaderName,
|
||||||
|
conversionRate: parseFloat(teamData) || 0,
|
||||||
|
todayPerformance: 0,
|
||||||
|
newClients: 0,
|
||||||
|
deals: 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理 formal_plural 数据
|
||||||
|
if (props.groupList.formal_plural) {
|
||||||
|
console.log('Processing formal_plural:', props.groupList.formal_plural)
|
||||||
|
Object.entries(props.groupList.formal_plural).forEach(([managerName, teamData]) => {
|
||||||
|
if (typeof teamData === 'object' && teamData !== null) {
|
||||||
|
Object.entries(teamData).forEach(([teamName, count]) => {
|
||||||
|
const existingGroup = groups.find(g => g.id === `${managerName}-${teamName}` || g.id === managerName)
|
||||||
|
if (existingGroup) {
|
||||||
|
existingGroup.newClients = count || 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if (typeof teamData === 'number') {
|
||||||
|
// 处理直接数值的情况
|
||||||
|
const existingGroup = groups.find(g => g.id === managerName)
|
||||||
|
if (existingGroup) {
|
||||||
|
existingGroup.newClients = teamData || 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Processed groups:', groups)
|
||||||
|
return groups
|
||||||
|
})
|
||||||
|
|
||||||
// 按综合表现排序的组别
|
// 按综合表现排序的组别
|
||||||
const sortedGroups = computed(() => {
|
const sortedGroups = computed(() => {
|
||||||
return [...props.groups].sort((a, b) => calculateScore(b) - calculateScore(a))
|
return [...processedGroups.value].sort((a, b) => calculateScore(b) - calculateScore(a))
|
||||||
})
|
})
|
||||||
|
|
||||||
// 计算综合分数
|
// 计算综合分数
|
||||||
@@ -237,10 +342,33 @@ const getAlertIcon = (level) => {
|
|||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
|
max-height: 400px;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding-right: 8px;
|
||||||
|
|
||||||
|
/* 自定义滚动条样式 */
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
background: #f1f5f9;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background: #cbd5e1;
|
||||||
|
border-radius: 3px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #94a3b8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.compact {
|
&.compact {
|
||||||
grid-template-columns: repeat(1, 1fr);
|
grid-template-columns: repeat(1, 1fr);
|
||||||
gap: 0.75rem;
|
gap: 0.75rem;
|
||||||
|
max-height: 500px;
|
||||||
|
|
||||||
.ranking-card {
|
.ranking-card {
|
||||||
padding: 0.75rem;
|
padding: 0.75rem;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
|
|
||||||
<!-- Right Section - Group Comparison -->
|
<!-- Right Section - Group Comparison -->
|
||||||
<div class="right-section">
|
<div class="right-section">
|
||||||
<GroupComparison :groups="groups" :senior-manager-data="seniorManagerList" @select-group="selectGroup" />
|
<GroupComparison :groups="groups" :senior-manager-data="seniorManagerList" :group-list="groupList" @select-group="selectGroup" @manager-change="handleManagerChange" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -327,23 +327,41 @@
|
|||||||
const res = await getCenterAdvancedManagerList(hasParams ? params : undefined)
|
const res = await getCenterAdvancedManagerList(hasParams ? params : undefined)
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
seniorManagerList.value = res.data
|
seniorManagerList.value = res.data
|
||||||
/**
|
|
||||||
* "data": {
|
|
||||||
"user_name": "刘瑞",
|
|
||||||
"user_level": 4,
|
|
||||||
"center_advanced_managers": [
|
|
||||||
"陈盼良"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取中心整体概览失败:', error)
|
console.error('获取中心整体概览失败:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 综合排名---组别列表
|
||||||
|
const groupList = ref([])
|
||||||
|
async function CenterGroupList(selectedManagerId = 'all') {
|
||||||
|
const params = getRequestParams()
|
||||||
|
const hasParams = params.user_name
|
||||||
|
|
||||||
|
// 根据选择的经理构建请求参数
|
||||||
|
let requestParams = hasParams ? { ...params } : {}
|
||||||
|
|
||||||
|
if (selectedManagerId === 'all') {
|
||||||
|
requestParams.get_all = "true"
|
||||||
|
} else {
|
||||||
|
// 根据manager id找到对应的名字
|
||||||
|
const selectedManager = seniorManagerList.value?.center_advanced_managers?.find((name, index) => `manager_${index}` === selectedManagerId)
|
||||||
|
console.log('Found Manager:', selectedManager)
|
||||||
|
if (selectedManager) {
|
||||||
|
requestParams.team_leader_name = selectedManager
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const res = await getTeamRanking(requestParams)
|
||||||
|
console.log('API Response:', res)
|
||||||
|
if (res.code === 200) {
|
||||||
|
groupList.value = res.data
|
||||||
|
console.log('Updated groupList:', groupList.value)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取团队排名失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 当前选中的组别,默认为第一个
|
// 当前选中的组别,默认为第一个
|
||||||
const selectedGroup = ref(groups[0])
|
const selectedGroup = ref(groups[0])
|
||||||
@@ -353,6 +371,11 @@
|
|||||||
selectedGroup.value = group
|
selectedGroup.value = group
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理高级经理选择变化
|
||||||
|
const handleManagerChange = (selectedManagerId) => {
|
||||||
|
CenterGroupList(selectedManagerId)
|
||||||
|
}
|
||||||
|
|
||||||
// 格式化货币
|
// 格式化货币
|
||||||
const formatCurrency = (value) => {
|
const formatCurrency = (value) => {
|
||||||
if (value >= 10000) {
|
if (value >= 10000) {
|
||||||
@@ -387,7 +410,7 @@
|
|||||||
await CenterCustomerType()
|
await CenterCustomerType()
|
||||||
await CenterUrgentNeedToAddress()
|
await CenterUrgentNeedToAddress()
|
||||||
await CenterSeniorManagerList()
|
await CenterSeniorManagerList()
|
||||||
|
await CenterGroupList('all') // 初始化加载全部高级经理数据
|
||||||
})
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user