【招生用户端】 新增# 工作台:对接数据简报、线索转化情况统计接口
parent
a8cc9b437b
commit
c57cc282fb
|
@ -0,0 +1,26 @@
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 数据简报
|
||||||
|
export function dataOverviewApi(params?: any) {
|
||||||
|
return request.get({ url: '/control/dataPresentation', params })
|
||||||
|
}
|
||||||
|
// 线索转客户统计
|
||||||
|
export function convertProcessApi(params?: any) {
|
||||||
|
return request.get({ url: '/control/leadToCustomerStatistics', params })
|
||||||
|
}
|
||||||
|
// 线索转化情况统计
|
||||||
|
export function clueStatusApi(params?: any) {
|
||||||
|
return request.get({ url: '/control/clueStatistics', 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 })
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import { isObject } from '@vue/shared'
|
import { isObject } from '@vue/shared'
|
||||||
import { ElMessage, type messageType } from 'element-plus'
|
import { ElMessage, dayjs, type messageType } from 'element-plus'
|
||||||
import { cloneDeep } from 'lodash'
|
import { cloneDeep } from 'lodash'
|
||||||
import { isArray } from './is'
|
import { isArray } from './is'
|
||||||
import type { FieldNamesProps } from '@/components/ProTable/interface'
|
import type { FieldNamesProps } from '@/components/ProTable/interface'
|
||||||
|
@ -326,3 +326,74 @@ export function findItemNested(enumData: any, callValue: any, value: string, chi
|
||||||
if (current[children]) return findItemNested(current[children], callValue, value, children)
|
if (current[children]) return findItemNested(current[children], callValue, value, children)
|
||||||
}, null)
|
}, null)
|
||||||
}
|
}
|
||||||
|
export const shortcuts = [
|
||||||
|
{
|
||||||
|
text: '今天',
|
||||||
|
value: () => {
|
||||||
|
const start = new Date()
|
||||||
|
const end = new Date()
|
||||||
|
start.setHours(0, 0, 0, 0)
|
||||||
|
end.setHours(23, 59, 59, 999)
|
||||||
|
return [start, end]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '一周后',
|
||||||
|
value: () => {
|
||||||
|
const start = new Date()
|
||||||
|
const end = new Date()
|
||||||
|
end.setDate(end.getDate() + 7)
|
||||||
|
start.setHours(0, 0, 0, 0)
|
||||||
|
end.setHours(23, 59, 59, 999)
|
||||||
|
return [start, end]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '一个月后',
|
||||||
|
value: () => {
|
||||||
|
const start = new Date()
|
||||||
|
const end = new Date()
|
||||||
|
end.setMonth(end.getMonth() + 1)
|
||||||
|
start.setHours(0, 0, 0, 0)
|
||||||
|
end.setHours(23, 59, 59, 999)
|
||||||
|
return [start, end]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '三个月后',
|
||||||
|
value: () => {
|
||||||
|
const start = new Date()
|
||||||
|
const end = new Date()
|
||||||
|
end.setMonth(end.getMonth() + 3)
|
||||||
|
start.setHours(0, 0, 0, 0)
|
||||||
|
end.setHours(23, 59, 59, 999)
|
||||||
|
return [start, end]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '半年后',
|
||||||
|
value: () => {
|
||||||
|
const start = new Date()
|
||||||
|
const end = new Date()
|
||||||
|
end.setMonth(end.getMonth() + 6)
|
||||||
|
start.setHours(0, 0, 0, 0)
|
||||||
|
end.setHours(23, 59, 59, 999)
|
||||||
|
return [start, end]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '一年后',
|
||||||
|
value: () => {
|
||||||
|
const start = new Date()
|
||||||
|
const end = new Date()
|
||||||
|
end.setFullYear(end.getFullYear() + 1)
|
||||||
|
start.setHours(0, 0, 0, 0)
|
||||||
|
end.setHours(23, 59, 59, 999)
|
||||||
|
return [start, end]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
// 今天
|
||||||
|
export const getCurDate = (type: string, format = 'YYYY-MM-DD HH:mm:ss') => {
|
||||||
|
return type == 'start' ? dayjs().startOf('day').format(format) : dayjs().endOf('day').format(format)
|
||||||
|
}
|
||||||
|
|
|
@ -1,24 +1,19 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="flex-1 w-full">
|
<div class="flex-1 w-full">
|
||||||
<card title="线索转化情况统计">
|
<card title="线索转化情况统计">
|
||||||
<v-charts style="height: 350px" :option="option" :autoresize="true" />
|
<v-charts ref="chartRef" v-loading="loading" style="height: 350px" :option="option" :autoresize="true" />
|
||||||
</card>
|
</card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { clueStatusApi } from '@/api/workbench'
|
||||||
import card from './card.vue'
|
import card from './card.vue'
|
||||||
import vCharts from 'vue-echarts'
|
import vCharts from 'vue-echarts'
|
||||||
|
import type { IForm } from '../index.vue'
|
||||||
|
|
||||||
const data = [
|
const chartRef = ref()
|
||||||
{ value: 1048, name: '有意向' },
|
const data = ref<any[]>([])
|
||||||
{ value: 735, name: '待领取' },
|
|
||||||
{ value: 580, name: '转化中' },
|
|
||||||
{ value: 484, name: '已添加' },
|
|
||||||
{ value: 300, name: '异常待处理' },
|
|
||||||
{ value: 300, name: '已成交' },
|
|
||||||
{ value: 300, name: '已战败' }
|
|
||||||
]
|
|
||||||
const option = ref({
|
const option = ref({
|
||||||
color: ['#73DDFF', '#73ACFF', '#FDD56A', '#FDB36A', '#FD866A', '#9E87FF', '#58D5FF'],
|
color: ['#73DDFF', '#73ACFF', '#FDD56A', '#FDB36A', '#FD866A', '#9E87FF', '#58D5FF'],
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
@ -47,5 +42,45 @@ const option = ref({
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
const loading = ref(false)
|
||||||
|
const dataMap: Record<string, string> = {
|
||||||
|
unclaimedCount: '待领取',
|
||||||
|
conversionCount: '转化中',
|
||||||
|
addedCount: '已添加',
|
||||||
|
abnormalCount: '异常待处理',
|
||||||
|
tradedCount: '已成交',
|
||||||
|
failCount: '已战败'
|
||||||
|
}
|
||||||
|
const fetchData = async (payload: IForm) => {
|
||||||
|
try {
|
||||||
|
loading.value = true
|
||||||
|
const result = await clueStatusApi(payload)
|
||||||
|
data.value = Object.keys(dataMap).map(item => {
|
||||||
|
return {
|
||||||
|
name: dataMap[item],
|
||||||
|
value: result[item] || 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 检查数组中的每一项是否都为 0
|
||||||
|
const allZero = data.value.every(item => item.value === 0)
|
||||||
|
if (allZero) {
|
||||||
|
chartRef.value.setOption({
|
||||||
|
title: {
|
||||||
|
text: '暂无数据',
|
||||||
|
x: 'center',
|
||||||
|
y: 'center'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
series: []
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} catch (error) {}
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
defineExpose({
|
||||||
|
fetchData
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|
|
@ -1,18 +1,16 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="flex-1 w-full chart-card">
|
<div class="flex-1 w-full chart-card">
|
||||||
<card title="线索转客户统计">
|
<card title="线索转客户统计">
|
||||||
<v-charts style="height: 350px" :autoresize="true" :option="option" />
|
<v-charts ref="chartRef" v-loading="loading" style="height: 350px" :autoresize="true" :option="option" />
|
||||||
</card>
|
</card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { convertProcessApi } from '@/api/workbench'
|
||||||
import card from './card.vue'
|
import card from './card.vue'
|
||||||
import vCharts from 'vue-echarts'
|
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) {
|
function createBarSeries(data, name, field) {
|
||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
|
@ -27,18 +25,21 @@ function createLineSeries(data, name) {
|
||||||
type: 'line',
|
type: 'line',
|
||||||
tooltip: {
|
tooltip: {
|
||||||
valueFormatter: function (value) {
|
valueFormatter: function (value) {
|
||||||
return (value as number) + '%'
|
return value as number
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data: data.map(item => item.client),
|
data: data.map(item => item.client),
|
||||||
yAxisIndex: 1
|
yAxisIndex: 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const xAxisData = () => data.map(item => item.name)
|
const loading = ref(false)
|
||||||
|
const data = ref([])
|
||||||
|
const xAxisData = ref([])
|
||||||
|
|
||||||
const series = [
|
const series = [
|
||||||
createBarSeries(data, '线索数', 'clueNumber'),
|
createBarSeries(data.value, '线索数', 'clueNumber'),
|
||||||
createBarSeries(data, '线索转客户数', 'client'),
|
createBarSeries(data.value, '线索转客户数', 'client'),
|
||||||
createLineSeries(data, '线索转客户率')
|
createLineSeries(data.value, '线索转客户率')
|
||||||
]
|
]
|
||||||
|
|
||||||
const option = ref({
|
const option = ref({
|
||||||
|
@ -57,7 +58,7 @@ const option = ref({
|
||||||
xAxis: [
|
xAxis: [
|
||||||
{
|
{
|
||||||
type: 'category',
|
type: 'category',
|
||||||
data: xAxisData()
|
data: xAxisData.value
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
yAxis: [
|
yAxis: [
|
||||||
|
@ -70,12 +71,60 @@ const option = ref({
|
||||||
{
|
{
|
||||||
type: 'value',
|
type: 'value',
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
formatter: '{value} %'
|
formatter: '{value}'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
series
|
series
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const chartRef = ref()
|
||||||
|
const fetchData = async (payload: IForm) => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const result = await convertProcessApi(payload)
|
||||||
|
if (result.length > 0) {
|
||||||
|
data.value = result.map((item: any) => {
|
||||||
|
const { clueCount, transactionClient, percentConversion } = item.leadToCustomerStatisticsVo
|
||||||
|
return {
|
||||||
|
name: item.organizationName,
|
||||||
|
clueNumber: clueCount,
|
||||||
|
client: transactionClient,
|
||||||
|
rate: percentConversion
|
||||||
|
}
|
||||||
|
})
|
||||||
|
xAxisData.value = result.map((item: any) => item.organizationName)
|
||||||
|
if (series[2].data.length === 0) {
|
||||||
|
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>
|
</script>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@media (max-width: 1000px) {
|
@media (max-width: 1000px) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<card title="数据简报">
|
<card title="数据简报">
|
||||||
<div class="data-overview">
|
<div class="data-overview" v-loading="loading">
|
||||||
<div
|
<div
|
||||||
class="flex-1 bg-[#F7F8FA] flex flex-col gap-[12px] p-[20px] rounded-[8px]"
|
class="flex-1 bg-[#F7F8FA] flex flex-col gap-[12px] p-[20px] rounded-[8px]"
|
||||||
v-for="(item, index) in dataOverview"
|
v-for="(item, index) in dataOverview"
|
||||||
|
@ -15,19 +15,41 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import card from './card.vue'
|
import card from './card.vue'
|
||||||
const dataOverview = ref([
|
import type { IForm } from '../index.vue'
|
||||||
{ label: '新增跟进记录(个)', value: 60 },
|
import { dataOverviewApi } from '@/api/workbench'
|
||||||
{ label: '新增客户(个)', value: 60 },
|
|
||||||
{ label: '成交客户(个)', value: 60 },
|
const loading = ref(false)
|
||||||
{ label: '转化中客户(个)', value: 60 },
|
const dataOverview = ref<any[]>([])
|
||||||
{ label: '异常待处理(个)', value: 60 },
|
const dataMap: Record<string, string> = {
|
||||||
{ label: '战败客户(个)', value: 60 }
|
followUpRecord: '新增跟进记录(个)',
|
||||||
])
|
newCustomer: '新增客户(个)',
|
||||||
|
transactionClient: '成交客户(个)',
|
||||||
|
convertingClient: '转化中客户(个)',
|
||||||
|
exceptionPending: '异常待处理(个)',
|
||||||
|
defeatedClient: '战败客户(个)'
|
||||||
|
}
|
||||||
|
const fetchData = async (payload: IForm) => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const result = await dataOverviewApi(payload)
|
||||||
|
dataOverview.value = Object.keys(dataMap).map(key => {
|
||||||
|
return {
|
||||||
|
label: dataMap[key],
|
||||||
|
value: result[key] || 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (error) {}
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
defineExpose({
|
||||||
|
fetchData
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.data-overview {
|
.data-overview {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
min-height: 100px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
<template>
|
||||||
|
<el-card class="!border-none" shadow="never">
|
||||||
|
<div class="flex gap-[30px]">
|
||||||
|
<div class="flex gap-[30px]">
|
||||||
|
<el-tree-select
|
||||||
|
v-model="queryParams.organizationId"
|
||||||
|
:props="defaultProps"
|
||||||
|
default-expand-all
|
||||||
|
:data="organizationList"
|
||||||
|
:render-after-expand="false"
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<daterange-picker
|
||||||
|
type="datetimerange"
|
||||||
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
isDisabledDate
|
||||||
|
isDisabledHours
|
||||||
|
:shortcuts="shortcuts"
|
||||||
|
v-model:startTime="queryParams.createTimeStart"
|
||||||
|
v-model:endTime="queryParams.createTimeEnd"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<el-cascader v-model="selectedUserId" :props="CascaderProps" :options="userList" @change="handleCascaderChange" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-button type="primary" @click="resetPage">查询</el-button>
|
||||||
|
<el-button @click="resetParams">重置</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { organzationLists } from '@/api/account_center/organization'
|
||||||
|
import { shortcuts } from '@/utils/util'
|
||||||
|
import type { PropType } from 'vue'
|
||||||
|
import type { IForm } from '../index.vue'
|
||||||
|
import { allUserListApi } from '@/api/workbench'
|
||||||
|
|
||||||
|
const defaultProps = {
|
||||||
|
label: 'name',
|
||||||
|
value: 'id'
|
||||||
|
}
|
||||||
|
const CascaderProps = {
|
||||||
|
label: 'name',
|
||||||
|
value: 'id'
|
||||||
|
}
|
||||||
|
const props = defineProps({
|
||||||
|
queryParams: {
|
||||||
|
type: Object as PropType<IForm>,
|
||||||
|
default: () => ({
|
||||||
|
organizationId: '',
|
||||||
|
createTimeStart: '',
|
||||||
|
createTimeEnd: '',
|
||||||
|
userId: []
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const emit = defineEmits(['update:queryParams', 'resetParams', 'resetPage', 'fectAllData'])
|
||||||
|
const localValue = computed({
|
||||||
|
get() {
|
||||||
|
return props.queryParams
|
||||||
|
},
|
||||||
|
set(newValue) {
|
||||||
|
emit('update:queryParams', newValue)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const selectedUserId = ref([])
|
||||||
|
|
||||||
|
const resetParams = () => {
|
||||||
|
selectedUserId.value = []
|
||||||
|
emit('resetParams')
|
||||||
|
}
|
||||||
|
const resetPage = () => {
|
||||||
|
emit('resetPage')
|
||||||
|
}
|
||||||
|
const organizationList = ref([])
|
||||||
|
const userList = ref<any[]>([])
|
||||||
|
const fetchOrganizationList = async () => {
|
||||||
|
try {
|
||||||
|
const result = await organzationLists()
|
||||||
|
organizationList.value = result ?? []
|
||||||
|
if (result.length > 0) {
|
||||||
|
localValue.value = {
|
||||||
|
...localValue.value,
|
||||||
|
organizationId: result[0].id
|
||||||
|
}
|
||||||
|
emit('fectAllData', result[0].id)
|
||||||
|
}
|
||||||
|
} catch (error) {}
|
||||||
|
}
|
||||||
|
const fetchAllUserList = async () => {
|
||||||
|
try {
|
||||||
|
const result = await allUserListApi()
|
||||||
|
const renamedData = renameFields(result)
|
||||||
|
userList.value = renamedData
|
||||||
|
} catch (error) {}
|
||||||
|
}
|
||||||
|
const renameFields = (data: any[]): any[] => {
|
||||||
|
return data.map(item => {
|
||||||
|
const newItem = { ...item }
|
||||||
|
if (newItem.organizationVoList) {
|
||||||
|
newItem.children = renameFields(newItem.organizationVoList)
|
||||||
|
delete newItem.organizationVoList
|
||||||
|
}
|
||||||
|
if (newItem.userVos) {
|
||||||
|
newItem.userVos.forEach(item => {
|
||||||
|
item.name = item.username
|
||||||
|
})
|
||||||
|
newItem.children = newItem.children ? [...newItem.children, ...newItem.userVos] : newItem.userVos
|
||||||
|
delete newItem.userVos
|
||||||
|
}
|
||||||
|
if (!newItem.children.length) {
|
||||||
|
newItem.disabled = true
|
||||||
|
}
|
||||||
|
return newItem
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const handleCascaderChange = value => {
|
||||||
|
const lastVal = value[value.length - 1]
|
||||||
|
localValue.value = {
|
||||||
|
...localValue.value,
|
||||||
|
userId: lastVal.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fetchOrganizationList()
|
||||||
|
fetchAllUserList()
|
||||||
|
</script>
|
||||||
|
<style scoped></style>
|
|
@ -1,13 +1,14 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="workbench flex flex-col gap-[16px]">
|
<div class="workbench flex flex-col gap-[16px]">
|
||||||
<data-overview />
|
<search-form v-model:queryParams="form" @reset-page="resetPage" @reset-params="resetParams" @fect-all-data="fetchAllData" />
|
||||||
|
<data-overview ref="dataOverviewRef" />
|
||||||
<div class="flex gap-[16px] flex-wrap">
|
<div class="flex gap-[16px] flex-wrap">
|
||||||
<conversion-process-chart />
|
<conversion-process-chart ref="coversionProcessChartRef" />
|
||||||
<converted-chart />
|
<converted-chart />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-[16px] flex-wrap">
|
<div class="flex gap-[16px] flex-wrap">
|
||||||
<rank />
|
<rank />
|
||||||
<clue-status-pie />
|
<clue-status-pie ref="clueStatusPieRef" />
|
||||||
<!-- <converted-line-chart /> -->
|
<!-- <converted-line-chart /> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -20,6 +21,43 @@ import convertedChart from './components/converted-chart.vue'
|
||||||
import rank from './components/rank.vue'
|
import rank from './components/rank.vue'
|
||||||
import clueStatusPie from './components/clue-status-pie.vue'
|
import clueStatusPie from './components/clue-status-pie.vue'
|
||||||
// import convertedLineChart from './components/converted-line-chart.vue'
|
// import convertedLineChart from './components/converted-line-chart.vue'
|
||||||
|
import searchForm from './components/search-form.vue'
|
||||||
|
import { getCurDate } from '@/utils/util'
|
||||||
|
|
||||||
|
export interface IForm {
|
||||||
|
organizationId: number | null
|
||||||
|
createTimeStart: string
|
||||||
|
createTimeEnd: string
|
||||||
|
userId: string
|
||||||
|
}
|
||||||
|
const initialVal = ref()
|
||||||
|
const form = ref<IForm>({
|
||||||
|
organizationId: null,
|
||||||
|
createTimeStart: getCurDate('start'),
|
||||||
|
createTimeEnd: getCurDate('end'),
|
||||||
|
userId: ''
|
||||||
|
})
|
||||||
|
const clueStatusPieRef = ref<InstanceType<typeof clueStatusPie>>()
|
||||||
|
const coversionProcessChartRef = ref<InstanceType<typeof conversionProcessChart>>()
|
||||||
|
const dataOverviewRef = ref<InstanceType<typeof dataOverview>>()
|
||||||
|
const resetPage = () => {
|
||||||
|
fetchAllData(initialVal.value)
|
||||||
|
}
|
||||||
|
const resetParams = () => {
|
||||||
|
form.value = {
|
||||||
|
organizationId: initialVal.value,
|
||||||
|
createTimeStart: getCurDate('start').toString(),
|
||||||
|
createTimeEnd: getCurDate('end').toString(),
|
||||||
|
userId: ''
|
||||||
|
}
|
||||||
|
fetchAllData(initialVal.value)
|
||||||
|
}
|
||||||
|
const fetchAllData = (defaultValue?: number) => {
|
||||||
|
initialVal.value = defaultValue ?? null
|
||||||
|
dataOverviewRef.value?.fetchData(form.value)
|
||||||
|
coversionProcessChartRef.value?.fetchData(form.value)
|
||||||
|
clueStatusPieRef.value?.fetchData(form.value)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
Loading…
Reference in New Issue