feat: 调整首页图表
This commit is contained in:
@@ -25,6 +25,7 @@ export namespace CustomerApi {
|
|||||||
contractCount: number;
|
contractCount: number;
|
||||||
signingRate: number;
|
signingRate: number;
|
||||||
completionRate: number;
|
completionRate: number;
|
||||||
|
permanentCount: number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ function renderChart() {
|
|||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
// 总授权
|
// 总授权
|
||||||
name: '授权License数',
|
name: 'License总数',
|
||||||
type: 'bar',
|
type: 'bar',
|
||||||
data: [props.dashboardValue.licenseCount],
|
data: [props.dashboardValue.licenseCount],
|
||||||
barWidth: 20,
|
barWidth: 20,
|
||||||
@@ -41,16 +41,16 @@ function renderChart() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
// 已签合同
|
// 已签合同
|
||||||
name: '已签合同数',
|
name: '永久license数',
|
||||||
type: 'bar',
|
type: 'bar',
|
||||||
data: [props.dashboardValue.contractCount],
|
data: [props.dashboardValue.permanentCount],
|
||||||
barWidth: 20,
|
barWidth: 20,
|
||||||
itemStyle: { color: '#91c7ae' },
|
itemStyle: { color: '#91c7ae' },
|
||||||
z: 2,
|
z: 2,
|
||||||
label: {
|
label: {
|
||||||
show: true,
|
show: true,
|
||||||
position: 'right',
|
position: 'right',
|
||||||
formatter: `{c}/${props.dashboardValue.licenseCount} (${props.dashboardValue.completionRate}%)`,
|
formatter: `{c}/${props.dashboardValue.licenseCount}`,
|
||||||
rich: { per: { color: '#333', fontWeight: 'bold' } },
|
rich: { per: { color: '#333', fontWeight: 'bold' } },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -74,5 +74,5 @@ watch(
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<EchartsUI ref="chartRef" />
|
<EchartsUI ref="chartRef" style="height: 150px" />
|
||||||
</template>
|
</template>
|
||||||
@@ -19,22 +19,26 @@ function renderChart() {
|
|||||||
{
|
{
|
||||||
type: 'pie',
|
type: 'pie',
|
||||||
roseType: 'radius',
|
roseType: 'radius',
|
||||||
radius: [20, 100],
|
radius: [15, 60],
|
||||||
label: { show: true, fontSize: 14 },
|
label: {
|
||||||
data: [
|
show: true,
|
||||||
{
|
fontSize: 14,
|
||||||
value: props.dashboardValue.userCount,
|
formatter: '{b}:{c}',
|
||||||
name: '员工',
|
|
||||||
itemStyle: { color: '#4F81BD' },
|
|
||||||
},
|
},
|
||||||
|
data: [
|
||||||
|
// {
|
||||||
|
// value: props.dashboardValue.userCount,
|
||||||
|
// name: '员工',
|
||||||
|
// itemStyle: { color: '#4F81BD' },
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
value: props.dashboardValue.customerCount,
|
value: props.dashboardValue.customerCount,
|
||||||
name: '客户',
|
name: '客户数',
|
||||||
itemStyle: { color: '#9BBB59' },
|
itemStyle: { color: '#9BBB59' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: props.dashboardValue.projectCount,
|
value: props.dashboardValue.projectCount,
|
||||||
name: '项目',
|
name: '项目数',
|
||||||
itemStyle: { color: '#C0504D' },
|
itemStyle: { color: '#C0504D' },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -60,5 +64,5 @@ watch(
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<EchartsUI ref="chartRef" />
|
<EchartsUI ref="chartRef" style="height: 150px" />
|
||||||
</template>
|
</template>
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
<script lang="ts" setup>
|
|
||||||
import type { EchartsUIType } from '@vben/plugins/echarts';
|
|
||||||
|
|
||||||
import { onMounted, ref, watch } from 'vue';
|
|
||||||
|
|
||||||
import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{ signingRate?: number }>(), {
|
|
||||||
signingRate: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
const chartRef = ref<EchartsUIType>();
|
|
||||||
const { renderEcharts } = useEcharts(chartRef);
|
|
||||||
|
|
||||||
function renderChart() {
|
|
||||||
renderEcharts({
|
|
||||||
// title: { text: '签单率', left: 'center' },
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
type: 'gauge',
|
|
||||||
startAngle: 225,
|
|
||||||
endAngle: -45,
|
|
||||||
progress: { show: true, width: 18 },
|
|
||||||
axisLine: { lineStyle: { width: 18 } },
|
|
||||||
pointer: { width: 6 },
|
|
||||||
detail: { fontSize: 24, formatter: '{value}%' },
|
|
||||||
data: [{ value: props.signingRate }],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'item',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
renderChart();
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.signingRate,
|
|
||||||
(newVal) => {
|
|
||||||
if (newVal) {
|
|
||||||
renderChart();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ deep: true },
|
|
||||||
);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<EchartsUI ref="chartRef" />
|
|
||||||
</template>
|
|
||||||
71
apps/web-antd/src/views/dashboard/analytics-visits-sign.vue
Normal file
71
apps/web-antd/src/views/dashboard/analytics-visits-sign.vue
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import type { EchartsUIType } from '@vben/plugins/echarts';
|
||||||
|
|
||||||
|
import type { CustomerApi } from '#/api/license/customer';
|
||||||
|
|
||||||
|
import { onMounted, ref, watch } from 'vue';
|
||||||
|
|
||||||
|
import { EchartsUI, useEcharts } from '@vben/plugins/echarts';
|
||||||
|
|
||||||
|
const props = defineProps<{ dashboardValue: CustomerApi.Dashboard }>();
|
||||||
|
const chartRef = ref<EchartsUIType>();
|
||||||
|
const { renderEcharts } = useEcharts(chartRef);
|
||||||
|
|
||||||
|
function renderChart() {
|
||||||
|
renderEcharts({
|
||||||
|
// title: { text: '签单率', left: 'center' },
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '签单率(已签合同数/项目数)',
|
||||||
|
type: 'gauge',
|
||||||
|
startAngle: 225,
|
||||||
|
endAngle: -45,
|
||||||
|
radius: '100%',
|
||||||
|
progress: { show: true },
|
||||||
|
// axisLine: { lineStyle: { width: 11 } },
|
||||||
|
axisLabel: {
|
||||||
|
fontSize: 10,
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
length: 2,
|
||||||
|
distance: 3,
|
||||||
|
// show: false,
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
length: 5,
|
||||||
|
distance: 3,
|
||||||
|
lineStyle: {
|
||||||
|
width: 2,
|
||||||
|
// color: '#999',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// pointer: { width: 6 },
|
||||||
|
detail: { fontSize: 18, formatter: '{value}%' },
|
||||||
|
data: [{ value: props.dashboardValue.signingRate ?? 0 }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
tooltip: {
|
||||||
|
// trigger: 'item',
|
||||||
|
formatter: `{a} <br/>${props.dashboardValue.contractCount}/${props.dashboardValue.projectCount}={c}%`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
renderChart();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.dashboardValue,
|
||||||
|
(newVal) => {
|
||||||
|
if (newVal) {
|
||||||
|
renderChart();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true },
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<EchartsUI ref="chartRef" style="height: 150px" />
|
||||||
|
</template>
|
||||||
@@ -5,7 +5,11 @@ import type { CustomerApi } from '#/api/license/customer';
|
|||||||
|
|
||||||
import { onMounted, ref, shallowRef } from 'vue';
|
import { onMounted, ref, shallowRef } from 'vue';
|
||||||
|
|
||||||
import { AnalysisChartCard, WorkbenchTrends } from '@vben/common-ui';
|
import {
|
||||||
|
AnalysisChartCard,
|
||||||
|
AnalysisOverviewCard,
|
||||||
|
WorkbenchTrends,
|
||||||
|
} from '@vben/common-ui';
|
||||||
|
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||||
@@ -16,11 +20,11 @@ import { getLicenseExpiry } from '#/api/license/license';
|
|||||||
// import { DictTag } from '#/components/dict-tag';
|
// import { DictTag } from '#/components/dict-tag';
|
||||||
import { DICT_TYPE, getDictObj } from '#/utils';
|
import { DICT_TYPE, getDictObj } from '#/utils';
|
||||||
|
|
||||||
import AnalyticsVisitsData from './analytics-visits-data.vue';
|
import AnalyticsVisitsData from './analytics-visits-lic.vue';
|
||||||
import AnalyticsVisitsSales from './analytics-visits-sales.vue';
|
import AnalyticsVisitsSource from './analytics-visits-pie.vue';
|
||||||
import AnalyticsVisitsSource from './analytics-visits-source.vue';
|
import AnalyticsVisitsSales from './analytics-visits-sign.vue';
|
||||||
|
|
||||||
const overviewItems = shallowRef<AnalysisOverviewItem[]>([]);
|
const overviewItems = shallowRef<AnalysisOverviewItem>();
|
||||||
const trendItems = shallowRef<WorkbenchTrendItem[]>([]);
|
const trendItems = shallowRef<WorkbenchTrendItem[]>([]);
|
||||||
const projectProgressItems = shallowRef<WorkbenchTrendItem[]>([]);
|
const projectProgressItems = shallowRef<WorkbenchTrendItem[]>([]);
|
||||||
dayjs.extend(relativeTime);
|
dayjs.extend(relativeTime);
|
||||||
@@ -32,50 +36,13 @@ onMounted(async () => {
|
|||||||
|
|
||||||
dashboardValue.value = data;
|
dashboardValue.value = data;
|
||||||
|
|
||||||
overviewItems.value = [
|
overviewItems.value = {
|
||||||
{
|
icon: 'icon-[streamline-plump-color--user-pin-flat] size-9 flex-shrink-0',
|
||||||
icon: 'icon-[streamline-plump-color--user-pin-flat] size-8 flex-shrink-0',
|
title: '员工数',
|
||||||
title: '员工总数',
|
|
||||||
totalTitle: '总用户量',
|
totalTitle: '总用户量',
|
||||||
totalValue: data.userCount || 0,
|
totalValue: data.userCount || 0,
|
||||||
value: data.userCount || 0,
|
value: data.userCount || 0,
|
||||||
},
|
};
|
||||||
{
|
|
||||||
icon: 'icon-[streamline-color--key-flat] size-8 flex-shrink-0',
|
|
||||||
title: '授权License数',
|
|
||||||
totalTitle: '总License量',
|
|
||||||
totalValue: data?.licenseCount || 0,
|
|
||||||
value: data?.licenseCount || 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'icon-[streamline-sharp-color--laptop-project-screen-flat] size-8 flex-shrink-0',
|
|
||||||
title: '项目总数',
|
|
||||||
totalTitle: '总项目量',
|
|
||||||
totalValue: data?.projectCount || 0,
|
|
||||||
value: data?.projectCount || 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'icon-[material-icon-theme--folder-contract-open] size-8 flex-shrink-0',
|
|
||||||
title: '已签合同数',
|
|
||||||
totalTitle: '总合同量',
|
|
||||||
totalValue: data?.contractCount || 0,
|
|
||||||
value: data?.contractCount || 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'icon-[streamline-color--information-desk-customer] size-8 flex-shrink-0',
|
|
||||||
title: '客户总数',
|
|
||||||
totalTitle: '总客户量',
|
|
||||||
totalValue: data?.customerCount || 0,
|
|
||||||
value: data?.customerCount || 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'icon-[streamline-plump-color--fill-and-sign-flat] size-8 flex-shrink-0',
|
|
||||||
title: '签单率',
|
|
||||||
totalTitle: '总签单率',
|
|
||||||
totalValue: data?.signingRate || 0,
|
|
||||||
value: data?.signingRate || 0,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const licenses = await getLicenseExpiry();
|
const licenses = await getLicenseExpiry();
|
||||||
trendItems.value = licenses.map((item) => {
|
trendItems.value = licenses.map((item) => {
|
||||||
@@ -140,14 +107,24 @@ onMounted(async () => {
|
|||||||
<!-- <AnalysisOverview :items="overviewItems" /> -->
|
<!-- <AnalysisOverview :items="overviewItems" /> -->
|
||||||
|
|
||||||
<div class="w-full md:flex">
|
<div class="w-full md:flex">
|
||||||
<AnalysisChartCard class="mt-5 md:mr-4 md:mt-0 md:w-1/3" title="概览">
|
<AnalysisOverviewCard
|
||||||
|
:item="overviewItems"
|
||||||
|
class="mt-5 md:mr-4 md:mt-0 md:w-1/4"
|
||||||
|
/>
|
||||||
|
<AnalysisChartCard
|
||||||
|
class="mt-5 md:mr-4 md:mt-0 md:w-1/4"
|
||||||
|
title="项目与客户数"
|
||||||
|
>
|
||||||
<AnalyticsVisitsSource :dashboard-value="dashboardValue" />
|
<AnalyticsVisitsSource :dashboard-value="dashboardValue" />
|
||||||
</AnalysisChartCard>
|
</AnalysisChartCard>
|
||||||
<AnalysisChartCard class="mt-5 md:mr-4 md:mt-0 md:w-1/3" title="完成度">
|
<AnalysisChartCard
|
||||||
|
class="mt-5 md:mr-4 md:mt-0 md:w-1/4"
|
||||||
|
title="交付完成率"
|
||||||
|
>
|
||||||
<AnalyticsVisitsData :dashboard-value="dashboardValue" />
|
<AnalyticsVisitsData :dashboard-value="dashboardValue" />
|
||||||
</AnalysisChartCard>
|
</AnalysisChartCard>
|
||||||
<AnalysisChartCard class="mt-5 md:mt-0 md:w-1/3" title="签单率">
|
<AnalysisChartCard class="mt-5 md:mt-0 md:w-1/4" title="签单率">
|
||||||
<AnalyticsVisitsSales :signing-rate="dashboardValue.signingRate" />
|
<AnalyticsVisitsSales :dashboard-value="dashboardValue" />
|
||||||
</AnalysisChartCard>
|
</AnalysisChartCard>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user