chore: seed migration objects batch 6
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="数据概览">
|
||||
<template #header-extra>
|
||||
<n-space align="center">
|
||||
<n-select
|
||||
v-if="isPlatformAdmin"
|
||||
v-model:value="tenantId"
|
||||
:options="imQueryTenantOptions"
|
||||
class="tenant-select"
|
||||
placeholder="请选择商户"
|
||||
/>
|
||||
<n-select v-model:value="days" :options="dayOptions" class="days-select" />
|
||||
<n-button type="primary" :loading="loading" @click="loadDashboard">刷新</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="proCard">
|
||||
<n-grid cols="1 s:2 m:3" responsive="screen" :x-gap="12" :y-gap="12">
|
||||
<n-grid-item v-for="item in metrics" :key="item.key">
|
||||
<n-statistic :label="item.label" :value="overview[item.key] || 0" />
|
||||
</n-grid-item>
|
||||
</n-grid>
|
||||
<n-divider />
|
||||
<n-h3>最近 {{ days }} 天增长趋势</n-h3>
|
||||
<n-data-table
|
||||
:columns="trendColumns"
|
||||
:data="trends"
|
||||
:loading="loading"
|
||||
:pagination="false"
|
||||
:bordered="false"
|
||||
/>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { Overview, Trends } from '@/api/imDashboard';
|
||||
import { imQueryTenantOptions, loadImQueryTenantOptions } from '@/views/imAdminQueryShared';
|
||||
|
||||
const message = useMessage();
|
||||
const userStore = useUserStore();
|
||||
const isPlatformAdmin = computed(() => userStore.isCompanyDept);
|
||||
const tenantId = ref(0);
|
||||
const days = ref(7);
|
||||
const loading = ref(false);
|
||||
const overview = ref<Recordable>({});
|
||||
const trends = ref<any[]>([]);
|
||||
const dayOptions = [
|
||||
{ label: '最近7天', value: 7 },
|
||||
{ label: '最近14天', value: 14 },
|
||||
{ label: '最近30天', value: 30 },
|
||||
];
|
||||
const metrics = [
|
||||
{ key: 'totalUsers', label: '总用户数' },
|
||||
{ key: 'activeUsers', label: '活跃用户' },
|
||||
{ key: 'totalGroups', label: '总群组数' },
|
||||
{ key: 'totalConversations', label: '总会话数' },
|
||||
{ key: 'totalMessages', label: '总消息数' },
|
||||
{ key: 'todayMessages', label: '今日消息' },
|
||||
];
|
||||
const trendColumns = [
|
||||
{ title: '日期', key: 'date' },
|
||||
{ title: '新增用户', key: 'userCount' },
|
||||
{ title: '新增消息', key: 'messageCount' },
|
||||
];
|
||||
|
||||
async function loadDashboard() {
|
||||
if (isPlatformAdmin.value && !tenantId.value) {
|
||||
message.warning('请选择商户');
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
try {
|
||||
const params = { tenantId: tenantId.value, days: days.value };
|
||||
const [summary, trendRes] = await Promise.all([Overview(params), Trends(params)]);
|
||||
overview.value = summary || {};
|
||||
trends.value = trendRes?.list || [];
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
if (isPlatformAdmin.value) {
|
||||
await loadImQueryTenantOptions();
|
||||
tenantId.value = imQueryTenantOptions.value[0]?.value || 0;
|
||||
if (!tenantId.value) message.warning('暂无可用商户');
|
||||
}
|
||||
if (!isPlatformAdmin.value || tenantId.value) await loadDashboard();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.tenant-select {
|
||||
width: 240px;
|
||||
}
|
||||
.days-select {
|
||||
width: 120px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user