feat(销售漏斗): 添加团队销售漏斗功能并集成到组件中
- 在api模块添加getTeamSalesFunnel接口 - GroupRanking组件新增teamSalesFunnel属性监听 - seniorManager页面集成销售漏斗数据获取和传递 - 实现销售漏斗数据自动更新图表功能
This commit is contained in:
@@ -13,13 +13,17 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue'
|
||||
import { ref, reactive, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
|
||||
import Chart from 'chart.js/auto'
|
||||
|
||||
const props = defineProps({
|
||||
selectedGroup: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
teamSalesFunnel: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -35,6 +39,19 @@ const funnelData = reactive({
|
||||
data: [120, 90, 45, 18, 10],
|
||||
})
|
||||
|
||||
// 监听teamSalesFunnel变化并更新图表数据
|
||||
watch(() => props.teamSalesFunnel, (newVal) => {
|
||||
if (newVal && Object.keys(newVal).length > 0) {
|
||||
// 按照固定顺序提取数据
|
||||
const order = ['线索', '加微', '到课', '定金', '成交']
|
||||
funnelData.data = order.map(key => newVal[key] || 0)
|
||||
// 确保在DOM更新后再更新图表
|
||||
nextTick(() => {
|
||||
renderPersonalFunnelChart()
|
||||
})
|
||||
}
|
||||
}, { deep: true })
|
||||
|
||||
// Chart.js: 创建或更新图表
|
||||
const createOrUpdateChart = (chartId, canvasRef, config) => {
|
||||
if (chartInstances[chartId]) {
|
||||
@@ -72,6 +89,11 @@ const renderPersonalFunnelChart = () => {
|
||||
|
||||
// 生命周期钩子
|
||||
onMounted(() => {
|
||||
// 处理初始传入的teamSalesFunnel数据
|
||||
if (props.teamSalesFunnel && Object.keys(props.teamSalesFunnel).length > 0) {
|
||||
const order = ['线索', '加微', '到课', '定金', '成交']
|
||||
funnelData.data = order.map(key => props.teamSalesFunnel[key] || 0)
|
||||
}
|
||||
renderPersonalFunnelChart()
|
||||
})
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
<div v-if="cardVisibility.groupRanking" class="left-section">
|
||||
<GroupRanking
|
||||
:groups="groups"
|
||||
:teamSalesFunnel="teamSalesFunnel"
|
||||
:selected-group="selectedGroup"
|
||||
@select-group="selectGroup"
|
||||
/>
|
||||
@@ -201,7 +202,7 @@ import UserDropdown from '@/components/UserDropdown.vue'
|
||||
import Loading from '@/components/Loading.vue'
|
||||
import { getOverallTeamPerformance,getTotalGroupCount,getConversionRate,getTotalCallCount,
|
||||
getNewCustomer,getDepositConversionRate,getActiveCustomerCommunicationRate,getAverageAnswerTime,
|
||||
getTimeoutRate,getTableFillingRate,getUrgentNeedToAddress,getTeamRanking,getTeamRankingInfo,getAbnormalResponseRate } from '@/api/senorManger.js'
|
||||
getTimeoutRate,getTableFillingRate,getUrgentNeedToAddress,getTeamRanking,getTeamRankingInfo,getAbnormalResponseRate,getTeamSalesFunnel } from '@/api/senorManger.js'
|
||||
|
||||
import { useUserStore } from '@/stores/user.js'
|
||||
import FeedbackForm from "@/components/FeedbackForm.vue";
|
||||
@@ -534,6 +535,41 @@ const statisticalIndicators = ref({
|
||||
formCompletionRate: 0,
|
||||
})
|
||||
|
||||
// 销售漏斗
|
||||
const teamSalesFunnel = ref({})
|
||||
async function GetTeamSalesFunnel() {
|
||||
const params = getRequestParams()
|
||||
const hasParams = params.user_name
|
||||
const requestParams = hasParams ? {
|
||||
...params,
|
||||
check_type: CheckType.value
|
||||
} : {check_type: CheckType.value}
|
||||
const res = await getTeamSalesFunnel(requestParams)
|
||||
if (res.code === 200) {
|
||||
teamSalesFunnel.value = res.data
|
||||
/**
|
||||
* data
|
||||
:
|
||||
{线索: 738, 加微: 404, 到课: 942, 定金: 43, 成交: 57}
|
||||
到课
|
||||
:
|
||||
942
|
||||
加微
|
||||
:
|
||||
404
|
||||
定金
|
||||
:
|
||||
43
|
||||
成交
|
||||
:
|
||||
57
|
||||
线索
|
||||
:
|
||||
738
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
// 团队异常
|
||||
const teamAlerts = ref({})
|
||||
// 异常预警
|
||||
@@ -742,6 +778,7 @@ onMounted(async ()=>{
|
||||
await fetchOverallTeamPerformance()
|
||||
await fetchActiveGroups()
|
||||
await fetchConversionRate()
|
||||
await GetTeamSalesFunnel()
|
||||
await fetchTotalCallCount()
|
||||
await fetchNewCustomers()
|
||||
await fetchDepositConversions()
|
||||
|
||||
Reference in New Issue
Block a user