171 lines
5.3 KiB
Vue
171 lines
5.3 KiB
Vue
<script lang="ts" setup>
|
||
import type { AnalysisOverviewItem, WorkbenchTrendItem } from '@vben/common-ui';
|
||
|
||
import { onMounted, shallowRef } from 'vue';
|
||
|
||
import {
|
||
AnalysisOverview,
|
||
WorkbenchTrends,
|
||
WorkbenchTrendsComment,
|
||
} from '@vben/common-ui';
|
||
|
||
import dayjs from 'dayjs';
|
||
import relativeTime from 'dayjs/plugin/relativeTime';
|
||
|
||
import { getLatestCommentList } from '#/api/license/comment';
|
||
import { dashboard } from '#/api/license/customer';
|
||
import { getLicenseExpiry } from '#/api/license/license';
|
||
// import { DictTag } from '#/components/dict-tag';
|
||
import { DICT_TYPE, getDictObj } from '#/utils';
|
||
|
||
const overviewItems = shallowRef<AnalysisOverviewItem[]>([]);
|
||
const trendItems = shallowRef<WorkbenchTrendItem[]>([]);
|
||
const projectProgressItems = shallowRef<WorkbenchTrendItem[]>([]);
|
||
dayjs.extend(relativeTime);
|
||
|
||
onMounted(async () => {
|
||
const data = await dashboard();
|
||
|
||
overviewItems.value = [
|
||
{
|
||
icon: 'icon-[streamline-plump-color--user-pin-flat] size-8 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) => {
|
||
return {
|
||
avatar: '',
|
||
content: `客户【<b>${item.customerName}</b>】项目【<b>${item.projectName}</b>】的License即将在 <b>${dayjs(item.expiryDate).fromNow(true)}</b> 后到期`,
|
||
date: dayjs(item.expiryDate).format('YYYY-MM-DD HH:mm:ss') || '',
|
||
title: item.serialNo || '',
|
||
status: '',
|
||
info: '',
|
||
};
|
||
});
|
||
|
||
const comments = await getLatestCommentList();
|
||
|
||
projectProgressItems.value = comments.map((item) => {
|
||
// 获取字典对象
|
||
const dict = getDictObj(DICT_TYPE.LIC_PROJECT_STATUS, String(item.status));
|
||
|
||
let dataContent = item.content || '';
|
||
if (dataContent) {
|
||
const position = dataContent.indexOf('>') + 1;
|
||
const originalString = dataContent;
|
||
const stringToInsert = `<span style="font-size: 12px; color: #32363973">${item.author}:</span>`;
|
||
dataContent =
|
||
originalString.slice(0, position) +
|
||
stringToInsert +
|
||
originalString.slice(position);
|
||
}
|
||
|
||
return {
|
||
avatar: '',
|
||
content: dataContent,
|
||
date: dayjs(item.updateTime).format('YYYY-MM-DD HH:mm:ss') || '',
|
||
title: `${item.projectName ?? ''} `,
|
||
status: dict,
|
||
customerName: item.customerName,
|
||
serialNo: item.serialNo,
|
||
businessOwner: item.businessOwner,
|
||
technicalOwnerA: item.technicalOwnerA,
|
||
};
|
||
});
|
||
});
|
||
</script>
|
||
|
||
<template>
|
||
<div class="p-5">
|
||
<!-- <WorkbenchHeader
|
||
:avatar="userStore.userInfo?.avatar || preferences.app.defaultAvatar"
|
||
:alt="userStore.userInfo?.nickname || '管理员'"
|
||
>
|
||
<template #title>
|
||
早安, {{ userStore.userInfo?.nickname }}, 开始您一天的工作吧!
|
||
</template>
|
||
<template #description> 今日晴,20℃ - 32℃! </template>
|
||
</WorkbenchHeader> -->
|
||
|
||
<AnalysisOverview :items="overviewItems" />
|
||
|
||
<div class="mt-2 flex flex-col lg:flex-row">
|
||
<div class="mr-4 w-full lg:w-1/2">
|
||
<WorkbenchTrends
|
||
:items="trendItems"
|
||
class="mt-5"
|
||
title="License即将到期"
|
||
/>
|
||
</div>
|
||
<div class="mr-4 w-full lg:w-1/2">
|
||
<WorkbenchTrendsComment
|
||
:items="projectProgressItems"
|
||
class="mt-5"
|
||
title="项目进展"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- <AnalysisChartsTabs :tabs="chartTabs" class="mt-5">
|
||
<template #trends>
|
||
<AnalyticsTrends />
|
||
</template>
|
||
<template #visits>
|
||
<AnalyticsVisits />
|
||
</template>
|
||
</AnalysisChartsTabs> -->
|
||
|
||
<!-- <div class="mt-5 w-full md:flex">
|
||
<AnalysisChartCard class="mt-5 md:mr-4 md:mt-0 md:w-1/3" title="访问数量">
|
||
<AnalyticsVisitsData />
|
||
</AnalysisChartCard>
|
||
<AnalysisChartCard class="mt-5 md:mr-4 md:mt-0 md:w-1/3" title="访问来源">
|
||
<AnalyticsVisitsSource />
|
||
</AnalysisChartCard>
|
||
<AnalysisChartCard class="mt-5 md:mt-0 md:w-1/3" title="访问来源">
|
||
<AnalyticsVisitsSales />
|
||
</AnalysisChartCard>
|
||
</div> -->
|
||
</div>
|
||
</template>
|