<script lang="ts" setup>
|
import type { EchartsUIType } from '@vben/plugins/echarts';
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
import type { CrmSalesTargetApi } from '#/api/crm/salesTarget';
|
|
import { onMounted, ref } from 'vue';
|
|
import { ContentWrap, Page } from '@vben/common-ui';
|
import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
|
import { Tabs } from 'ant-design-vue';
|
|
import { useVbenForm } from '#/adapter/form';
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { getSalesTargetAnalysis } from '#/api/crm/salesTarget';
|
import { $t } from '#/locales';
|
|
import {
|
ANALYSIS_TABS,
|
getChartOptions,
|
type AnalysisTabKey,
|
} from './chart-options';
|
import { useGridColumns, useGridFormSchema } from './data';
|
|
const activeTab = ref<string>('contract');
|
const chartRef = ref<EchartsUIType>();
|
const { renderEcharts } = useEcharts(chartRef);
|
|
/** 按当前表单值 + 当前指标 Tab 加载图表与表格 */
|
async function handleLoad() {
|
const formValues = await formApi.getValues();
|
const res = await getSalesTargetAnalysis(formValues);
|
await renderEcharts(getChartOptions(activeTab.value as AnalysisTabKey, res));
|
await gridApi.grid.reloadData(res);
|
}
|
|
const [QueryForm, formApi] = useVbenForm({
|
commonConfig: {
|
componentProps: {
|
class: 'w-full',
|
},
|
},
|
schema: useGridFormSchema(),
|
showCollapseButton: true,
|
submitButtonOptions: {
|
content: $t('common.query'),
|
},
|
wrapperClass: 'grid-cols-1 md:grid-cols-4',
|
handleSubmit: handleLoad,
|
});
|
|
const [Grid, gridApi] = useVbenVxeGrid({
|
gridOptions: {
|
columns: useGridColumns(),
|
height: 'auto',
|
keepSource: true,
|
pagerConfig: {
|
enabled: false,
|
},
|
proxyConfig: {
|
autoLoad: false, // 图表与表格统一走 handleLoad 手动加载,避免空参数请求
|
},
|
rowConfig: {
|
keyField: 'id',
|
isHover: true,
|
},
|
toolbarConfig: {
|
enabled: false,
|
},
|
} as VxeTableGridOptions<CrmSalesTargetApi.SalesTarget>,
|
});
|
|
/** 指标 Tab 切换 */
|
function handleTabChange(key: string | number) {
|
activeTab.value = String(key);
|
handleLoad();
|
}
|
|
onMounted(async () => {
|
// 重置表单为默认周期(当前年份),默认加载一次达成分析
|
await formApi.resetForm();
|
await handleLoad();
|
});
|
</script>
|
|
<template>
|
<Page auto-content-height>
|
<ContentWrap>
|
<QueryForm />
|
<Tabs
|
v-model:active-key="activeTab"
|
class="w-full"
|
@change="handleTabChange"
|
>
|
<Tabs.TabPane
|
v-for="item in ANALYSIS_TABS"
|
:key="item.key"
|
:tab="item.label"
|
:force-render="true"
|
/>
|
</Tabs>
|
<EchartsUI class="mb-4 w-full" height="380px" ref="chartRef" />
|
<Grid>
|
<template #target="{ row }">
|
<span>
|
{{
|
row.targetUserName ||
|
row.targetDeptName ||
|
row.targetItemName ||
|
'--'
|
}}
|
</span>
|
</template>
|
<template #contractRate="{ row }">
|
<span :class="row.contractRate == null ? '' : 'font-medium'">
|
{{ row.contractRate == null ? '--' : `${row.contractRate}%` }}
|
</span>
|
</template>
|
<template #receivableRate="{ row }">
|
<span :class="row.receivableRate == null ? '' : 'font-medium'">
|
{{ row.receivableRate == null ? '--' : `${row.receivableRate}%` }}
|
</span>
|
</template>
|
<template #businessRate="{ row }">
|
<span :class="row.businessRate == null ? '' : 'font-medium'">
|
{{ row.businessRate == null ? '--' : `${row.businessRate}%` }}
|
</span>
|
</template>
|
<template #customerRate="{ row }">
|
<span :class="row.customerRate == null ? '' : 'font-medium'">
|
{{ row.customerRate == null ? '--' : `${row.customerRate}%` }}
|
</span>
|
</template>
|
<template #contractCountRate="{ row }">
|
<span :class="row.contractCountRate == null ? '' : 'font-medium'">
|
{{
|
row.contractCountRate == null
|
? '--'
|
: `${row.contractCountRate}%`
|
}}
|
</span>
|
</template>
|
</Grid>
|
</ContentWrap>
|
</Page>
|
</template>
|