feat: 调整首页图表
This commit is contained in:
@@ -25,6 +25,7 @@ export namespace CustomerApi {
|
||||
contractCount: number;
|
||||
signingRate: number;
|
||||
completionRate: number;
|
||||
permanentCount: number;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ function renderChart() {
|
||||
series: [
|
||||
{
|
||||
// 总授权
|
||||
name: '授权License数',
|
||||
name: 'License总数',
|
||||
type: 'bar',
|
||||
data: [props.dashboardValue.licenseCount],
|
||||
barWidth: 20,
|
||||
@@ -41,16 +41,16 @@ function renderChart() {
|
||||
},
|
||||
{
|
||||
// 已签合同
|
||||
name: '已签合同数',
|
||||
name: '永久license数',
|
||||
type: 'bar',
|
||||
data: [props.dashboardValue.contractCount],
|
||||
data: [props.dashboardValue.permanentCount],
|
||||
barWidth: 20,
|
||||
itemStyle: { color: '#91c7ae' },
|
||||
z: 2,
|
||||
label: {
|
||||
show: true,
|
||||
position: 'right',
|
||||
formatter: `{c}/${props.dashboardValue.licenseCount} (${props.dashboardValue.completionRate}%)`,
|
||||
formatter: `{c}/${props.dashboardValue.licenseCount}`,
|
||||
rich: { per: { color: '#333', fontWeight: 'bold' } },
|
||||
},
|
||||
},
|
||||
@@ -74,5 +74,5 @@ watch(
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<EchartsUI ref="chartRef" />
|
||||
<EchartsUI ref="chartRef" style="height: 150px" />
|
||||
</template>
|
||||
@@ -19,22 +19,26 @@ function renderChart() {
|
||||
{
|
||||
type: 'pie',
|
||||
roseType: 'radius',
|
||||
radius: [20, 100],
|
||||
label: { show: true, fontSize: 14 },
|
||||
data: [
|
||||
{
|
||||
value: props.dashboardValue.userCount,
|
||||
name: '员工',
|
||||
itemStyle: { color: '#4F81BD' },
|
||||
radius: [15, 60],
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: 14,
|
||||
formatter: '{b}:{c}',
|
||||
},
|
||||
data: [
|
||||
// {
|
||||
// value: props.dashboardValue.userCount,
|
||||
// name: '员工',
|
||||
// itemStyle: { color: '#4F81BD' },
|
||||
// },
|
||||
{
|
||||
value: props.dashboardValue.customerCount,
|
||||
name: '客户',
|
||||
name: '客户数',
|
||||
itemStyle: { color: '#9BBB59' },
|
||||
},
|
||||
{
|
||||
value: props.dashboardValue.projectCount,
|
||||
name: '项目',
|
||||
name: '项目数',
|
||||
itemStyle: { color: '#C0504D' },
|
||||
},
|
||||
],
|
||||
@@ -60,5 +64,5 @@ watch(
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<EchartsUI ref="chartRef" />
|
||||
<EchartsUI ref="chartRef" style="height: 150px" />
|
||||
</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 { AnalysisChartCard, WorkbenchTrends } from '@vben/common-ui';
|
||||
import {
|
||||
AnalysisChartCard,
|
||||
AnalysisOverviewCard,
|
||||
WorkbenchTrends,
|
||||
} from '@vben/common-ui';
|
||||
|
||||
import dayjs from 'dayjs';
|
||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||
@@ -16,11 +20,11 @@ import { getLicenseExpiry } from '#/api/license/license';
|
||||
// import { DictTag } from '#/components/dict-tag';
|
||||
import { DICT_TYPE, getDictObj } from '#/utils';
|
||||
|
||||
import AnalyticsVisitsData from './analytics-visits-data.vue';
|
||||
import AnalyticsVisitsSales from './analytics-visits-sales.vue';
|
||||
import AnalyticsVisitsSource from './analytics-visits-source.vue';
|
||||
import AnalyticsVisitsData from './analytics-visits-lic.vue';
|
||||
import AnalyticsVisitsSource from './analytics-visits-pie.vue';
|
||||
import AnalyticsVisitsSales from './analytics-visits-sign.vue';
|
||||
|
||||
const overviewItems = shallowRef<AnalysisOverviewItem[]>([]);
|
||||
const overviewItems = shallowRef<AnalysisOverviewItem>();
|
||||
const trendItems = shallowRef<WorkbenchTrendItem[]>([]);
|
||||
const projectProgressItems = shallowRef<WorkbenchTrendItem[]>([]);
|
||||
dayjs.extend(relativeTime);
|
||||
@@ -32,50 +36,13 @@ onMounted(async () => {
|
||||
|
||||
dashboardValue.value = data;
|
||||
|
||||
overviewItems.value = [
|
||||
{
|
||||
icon: 'icon-[streamline-plump-color--user-pin-flat] size-8 flex-shrink-0',
|
||||
title: '员工总数',
|
||||
overviewItems.value = {
|
||||
icon: 'icon-[streamline-plump-color--user-pin-flat] size-9 flex-shrink-0',
|
||||
title: '员工数',
|
||||
totalTitle: '总用户量',
|
||||
totalValue: 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();
|
||||
trendItems.value = licenses.map((item) => {
|
||||
@@ -140,14 +107,24 @@ onMounted(async () => {
|
||||
<!-- <AnalysisOverview :items="overviewItems" /> -->
|
||||
|
||||
<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" />
|
||||
</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" />
|
||||
</AnalysisChartCard>
|
||||
<AnalysisChartCard class="mt-5 md:mt-0 md:w-1/3" title="签单率">
|
||||
<AnalyticsVisitsSales :signing-rate="dashboardValue.signingRate" />
|
||||
<AnalysisChartCard class="mt-5 md:mt-0 md:w-1/4" title="签单率">
|
||||
<AnalyticsVisitsSales :dashboard-value="dashboardValue" />
|
||||
</AnalysisChartCard>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user