feat(frontend): improve admin usability and light theme
This commit is contained in:
@@ -1,8 +1,16 @@
|
||||
<template>
|
||||
<a-spin :loading="loading" style="width: 100%">
|
||||
<a-alert v-if="errorMessage" type="error" show-icon class="dashboard-alert">
|
||||
{{ errorMessage }}
|
||||
<template #action><a-button size="small" @click="loadOverview">重新加载</a-button></template>
|
||||
</a-alert>
|
||||
<div class="dashboard-meta">当前配送点业务汇总 · 更新时间:{{ updatedAt || '尚未加载' }}</div>
|
||||
<a-grid :cols="{ xs: 1, sm: 2, lg: 4 }" :col-gap="16" :row-gap="16">
|
||||
<a-grid-item v-for="item in cards" :key="item.key">
|
||||
<a-card :bordered="false"><a-statistic :title="item.label" :value="overview[item.key]" show-group-separator /></a-card>
|
||||
<a-card :bordered="false" class="metric-card">
|
||||
<a-statistic :title="item.label" :value="overview[item.key]" show-group-separator />
|
||||
<div class="metric-hint">{{ item.hint }}</div>
|
||||
</a-card>
|
||||
</a-grid-item>
|
||||
</a-grid>
|
||||
</a-spin>
|
||||
@@ -13,15 +21,29 @@ import { onMounted, reactive, ref } from 'vue';
|
||||
import { request } from '@/api/http';
|
||||
type Overview = Record<'staff_count' | 'user_count' | 'contract_count' | 'order_count', number>;
|
||||
const loading = ref(false);
|
||||
const errorMessage = ref('');
|
||||
const updatedAt = ref('');
|
||||
const overview = reactive<Overview>({ staff_count: 0, user_count: 0, contract_count: 0, order_count: 0 });
|
||||
const cards: Array<{ key: keyof Overview; label: string }> = [
|
||||
{ key: 'staff_count', label: '配送人员' }, { key: 'user_count', label: '服务用户' },
|
||||
{ key: 'contract_count', label: '配送合同' }, { key: 'order_count', label: '配送订单' },
|
||||
const cards: Array<{ key: keyof Overview; label: string; hint: string }> = [
|
||||
{ key: 'staff_count', label: '配送人员', hint: '本站关联配送人员' }, { key: 'user_count', label: '服务用户', hint: '本站有效服务关系' },
|
||||
{ key: 'contract_count', label: '配送合同', hint: '本站合同总量' }, { key: 'order_count', label: '配送订单', hint: '本站订单总量' },
|
||||
];
|
||||
onMounted(async () => {
|
||||
async function loadOverview() {
|
||||
loading.value = true;
|
||||
try { Object.assign(overview, await request<Overview>('/dashboard/overview')); }
|
||||
catch (error) { Message.error((error as Error).message); }
|
||||
errorMessage.value = '';
|
||||
try {
|
||||
Object.assign(overview, await request<Overview>('/dashboard/overview'));
|
||||
updatedAt.value = new Date().toLocaleString('zh-CN', { hour12: false });
|
||||
}
|
||||
catch (error) { errorMessage.value = (error as Error).message; Message.error(errorMessage.value); }
|
||||
finally { loading.value = false; }
|
||||
});
|
||||
}
|
||||
onMounted(loadOverview);
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.dashboard-alert { margin-bottom: 16px; }
|
||||
.dashboard-meta { margin-bottom: 12px; color: var(--color-text-3); font-size: 12px; text-align: right; }
|
||||
.metric-card { min-height: 112px; }
|
||||
.metric-hint { margin-top: 8px; color: var(--color-text-3); font-size: 12px; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user