Files
agt-web/apps/web-antd/src/views/dashboard/index.vue
2025-08-27 14:22:27 +08:00

171 lines
5.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>