【招生用户端】 新增# 工作台:对接成交用户统计接口
parent
c57cc282fb
commit
5110a2c267
|
@ -12,15 +12,15 @@ export function convertProcessApi(params?: any) {
|
|||
export function clueStatusApi(params?: any) {
|
||||
return request.get({ url: '/control/clueStatistics', params })
|
||||
}
|
||||
// Top5
|
||||
export function rankListApi(params?: any) {
|
||||
return request.get({ url: '/control/top', params })
|
||||
}
|
||||
// 成交客户统计
|
||||
export function completedCustomerListApi(params?: any) {
|
||||
return request.get({ url: '/control/transactionCustomerStatistics', params })
|
||||
}
|
||||
// 获取所有组织以及人员信息
|
||||
export function allUserListApi(params?: any) {
|
||||
return request.get({ url: '/organization/getAllChildOrgInfo', params })
|
||||
}
|
||||
// 获取所有团队
|
||||
export function allTeamListApi(params?: any) {
|
||||
return request.get({ url: '/organization/getAllGroup', params })
|
||||
}
|
||||
// 获取所有组织
|
||||
export function allOrgListApi(params?: any) {
|
||||
return request.get({ url: '/organization/getAllOrg', params })
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import { apiFeedbackAgreement, apiMasterWorkerApplyAgreement, apiMasterWorkerPhy
|
|||
import { applyForEdit } from '@/api/finance/withdraw'
|
||||
import { useCreateModal } from './useCreateModal'
|
||||
import { toast, formatFileSize } from '@/utils/util'
|
||||
import { postLists } from '@/api/account_center/postion'
|
||||
|
||||
export interface CategoryProp {
|
||||
id: number
|
||||
|
@ -311,3 +312,21 @@ export function useUploadMoreAction() {
|
|||
previewPdf
|
||||
}
|
||||
}
|
||||
|
||||
export function usePositionData() {
|
||||
const positionOptions = ref<any[]>([])
|
||||
const postId = ref()
|
||||
const fetchPostionData = async (callback?: (params: []) => void) => {
|
||||
try {
|
||||
const result = await postLists()
|
||||
positionOptions.value = result.lists ?? []
|
||||
if (result.lists.length > 0) postId.value = result.lists[0].id
|
||||
callback && callback(result.lists)
|
||||
} catch (error) {}
|
||||
}
|
||||
return {
|
||||
positionOptions,
|
||||
postId,
|
||||
fetchPostionData
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
<template>
|
||||
<div class="flex-1 w-full chart-card">
|
||||
<card title="成交客户统计">
|
||||
<v-charts style="height: 350px" :autoresize="true" :option="option" />
|
||||
<v-charts style="height: 350px" ref="chartRef" v-loading="loading" :autoresize="true" :option="option" />
|
||||
</card>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { completedCustomerListApi } from '@/api/workbench'
|
||||
import card from './card.vue'
|
||||
import vCharts from 'vue-echarts'
|
||||
import type { IForm } from '../index.vue'
|
||||
|
||||
const data = [
|
||||
{ name: '湛江团队', clueNumber: 52, client: 52, rate: 100 },
|
||||
{ name: '广州团队', clueNumber: 8, client: 6, rate: 15 }
|
||||
]
|
||||
function createBarSeries(data, name, field) {
|
||||
return {
|
||||
name,
|
||||
|
@ -20,9 +18,11 @@ function createBarSeries(data, name, field) {
|
|||
data: data.map(item => item[field])
|
||||
}
|
||||
}
|
||||
const chartRef = ref()
|
||||
const data = ref<any[]>([])
|
||||
const xAxisData = ref([])
|
||||
|
||||
const xAxisData = () => data.map(item => item.name)
|
||||
const series = [createBarSeries(data, '客户数', 'clueNumber'), createBarSeries(data, '成交客户数', 'client')]
|
||||
const series = [createBarSeries(data.value, '客户数', 'clientCount'), createBarSeries(data.value, '成交客户数', 'transactionClient')]
|
||||
|
||||
const option = ref({
|
||||
color: ['#0E66FB', '#96B2D9'],
|
||||
|
@ -40,7 +40,7 @@ const option = ref({
|
|||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: xAxisData()
|
||||
data: xAxisData.value
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
|
@ -53,7 +53,54 @@ const option = ref({
|
|||
],
|
||||
series
|
||||
})
|
||||
const loading = ref(false)
|
||||
|
||||
const fetchData = async (payload: IForm) => {
|
||||
loading.value = true
|
||||
try {
|
||||
const result = await completedCustomerListApi(payload)
|
||||
data.value = result.map((item: any) => {
|
||||
const { clientCount, transactionClient } = item.leadToCustomerStatisticsVo
|
||||
return {
|
||||
name: item.organizationName,
|
||||
clientCount,
|
||||
transactionClient
|
||||
}
|
||||
})
|
||||
xAxisData.value = result.map((item: any) => item.organizationName)
|
||||
const allZero = data.value.every(item => item.clientCount == 0 && item.transactionClient == 0)
|
||||
if (allZero) {
|
||||
chartRef.value.setOption({
|
||||
title: {
|
||||
text: '暂无数据',
|
||||
x: 'center',
|
||||
y: 'center'
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
data: [],
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
],
|
||||
legend: {
|
||||
show: false
|
||||
}
|
||||
})
|
||||
}
|
||||
} catch (error) {}
|
||||
loading.value = false
|
||||
}
|
||||
defineExpose({
|
||||
fetchData
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@media (max-width: 1000px) {
|
||||
.chart-card {
|
||||
|
|
|
@ -3,45 +3,70 @@
|
|||
<card title="TOP5">
|
||||
<template #right>
|
||||
<div class="positions">
|
||||
<span class="default" :class="{ active: item.id == postId }" v-for="item in positions" :key="item.id" @click="postId = item.id">
|
||||
<span
|
||||
class="default"
|
||||
:class="{ active: item.id == postId }"
|
||||
v-for="item in positionOptions"
|
||||
:key="item.id"
|
||||
@click="postId = item.id"
|
||||
>
|
||||
{{ item.name }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-table :data="tableData">
|
||||
<el-table-column prop="index" label="排名" width="70" />
|
||||
<el-table-column prop="name" label="负责人" width="180" />
|
||||
<el-table-column prop="totalNumber" label="总数" />
|
||||
</el-table>
|
||||
<template v-if="tableData.length > 0">
|
||||
<el-table :data="tableData" v-loading="loading">
|
||||
<el-table-column prop="rank" label="排名" width="70" />
|
||||
<el-table-column prop="username" label="负责人" width="180" />
|
||||
<el-table-column prop="clueCount" label="总数" />
|
||||
</el-table>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-empty description="暂无数据" />
|
||||
</template>
|
||||
</card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { rankListApi } from '@/api/workbench'
|
||||
import card from './card.vue'
|
||||
const positions = ref([
|
||||
{ name: '电销', id: 5 },
|
||||
{ name: '招生', id: 6 }
|
||||
])
|
||||
const postId = ref(5)
|
||||
import type { IForm } from '../index.vue'
|
||||
import { usePositionData } from '@/hooks/useCommon'
|
||||
|
||||
const tableData = ref([
|
||||
{
|
||||
index: 1,
|
||||
name: 'John Brown',
|
||||
totalNumber: 32
|
||||
},
|
||||
{
|
||||
index: 2,
|
||||
name: 'John Brown',
|
||||
totalNumber: 32
|
||||
},
|
||||
{
|
||||
index: 3,
|
||||
name: 'John Brown',
|
||||
totalNumber: 32
|
||||
const { positionOptions, postId, fetchPostionData } = usePositionData()
|
||||
|
||||
const emit = defineEmits(['refresh'])
|
||||
|
||||
const tableData = ref([])
|
||||
const loading = ref(false)
|
||||
const fetchData = async (payload: IForm) => {
|
||||
if (!positionOptions.value.length) await fetchPostionData()
|
||||
if (tableData.value.length > 0) tableData.value = []
|
||||
loading.value = true
|
||||
try {
|
||||
const newPayload = {
|
||||
...payload,
|
||||
post: postId.value
|
||||
}
|
||||
const result = await rankListApi(newPayload)
|
||||
console.log(result)
|
||||
|
||||
tableData.value = result ?? []
|
||||
} catch (error) {}
|
||||
loading.value = false
|
||||
}
|
||||
watch(
|
||||
() => postId.value,
|
||||
(newVal, oldVal) => {
|
||||
if (newVal !== oldVal) {
|
||||
emit('refresh')
|
||||
}
|
||||
}
|
||||
])
|
||||
)
|
||||
defineExpose({
|
||||
fetchData
|
||||
})
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.rank {
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
<data-overview ref="dataOverviewRef" />
|
||||
<div class="flex gap-[16px] flex-wrap">
|
||||
<conversion-process-chart ref="coversionProcessChartRef" />
|
||||
<converted-chart />
|
||||
<converted-chart ref="convertedChartRef" />
|
||||
</div>
|
||||
<div class="flex gap-[16px] flex-wrap">
|
||||
<rank />
|
||||
<rank ref="rankRef" @refresh="refreshData" />
|
||||
<clue-status-pie ref="clueStatusPieRef" />
|
||||
<!-- <converted-line-chart /> -->
|
||||
</div>
|
||||
|
@ -37,6 +37,8 @@ const form = ref<IForm>({
|
|||
createTimeEnd: getCurDate('end'),
|
||||
userId: ''
|
||||
})
|
||||
const convertedChartRef = ref<InstanceType<typeof convertedChart>>()
|
||||
const rankRef = ref<InstanceType<typeof rank>>()
|
||||
const clueStatusPieRef = ref<InstanceType<typeof clueStatusPie>>()
|
||||
const coversionProcessChartRef = ref<InstanceType<typeof conversionProcessChart>>()
|
||||
const dataOverviewRef = ref<InstanceType<typeof dataOverview>>()
|
||||
|
@ -57,6 +59,11 @@ const fetchAllData = (defaultValue?: number) => {
|
|||
dataOverviewRef.value?.fetchData(form.value)
|
||||
coversionProcessChartRef.value?.fetchData(form.value)
|
||||
clueStatusPieRef.value?.fetchData(form.value)
|
||||
rankRef.value?.fetchData(form.value)
|
||||
convertedChartRef.value?.fetchData(form.value)
|
||||
}
|
||||
const refreshData = () => {
|
||||
rankRef.value?.fetchData(form.value)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
Loading…
Reference in New Issue