Files
WonderQ-Project/WonderQ-Admin-UI-Vue/src/pages/DashboardPage.vue
2026-08-27 10:11:24 +08:00

97 lines
3.1 KiB
Vue

<script setup lang="ts">
import { onMounted, ref } from "vue";
import { ElMessage } from "element-plus";
import { getDashboard } from "@/api/client";
import { leadStatusLabel } from "@/lib/leads";
import type { Dashboard } from "@/types";
const data = ref<Dashboard | null>(null);
const loading = ref(true);
const error = ref("");
async function load() {
loading.value = true;
error.value = "";
try {
data.value = await getDashboard();
} catch (err) {
error.value = err instanceof Error ? err.message : "仪表盘加载失败";
ElMessage.error(error.value);
} finally {
loading.value = false;
}
}
const formatDate = (value?: string | null) => {
if (!value) return "未填写";
const date = new Date(value);
return Number.isNaN(date.valueOf())
? value
: new Intl.DateTimeFormat("zh-CN", {
dateStyle: "medium",
timeStyle: "short",
}).format(date);
};
onMounted(load);
</script>
<template>
<div class="page-stack">
<div class="page-intro">
<div>
<p class="eyebrow">TODAY / SNAPSHOT</p>
<h2>运营概览</h2>
<p>快速查看当前内容和需求线索的状态</p>
</div>
<el-button :loading="loading" @click="load">刷新数据</el-button>
</div>
<el-alert v-if="error" :title="error" type="error" show-icon :closable="false" />
<div v-if="loading" class="loading-grid">
<el-skeleton v-for="item in 2" :key="item" animated />
</div>
<template v-else-if="data">
<div class="metric-grid">
<el-card shadow="never" class="metric-card">
<span>待处理线索</span>
<strong>{{ data.stats.newLeadCount }}</strong>
<small>需要及时跟进</small>
</el-card>
<el-card shadow="never" class="metric-card accent">
<span>全部线索</span>
<strong>{{ data.stats.leadCount }}</strong>
<small>持续沉淀中的需求</small>
</el-card>
</div>
<el-card shadow="never" class="panel-card">
<template #header>
<div class="panel-heading">
<span>最近线索</span>
<el-tag type="info" effect="plain">最多 5 </el-tag>
</div>
</template>
<el-empty v-if="!data.recentLeads.length" description="暂无线索" />
<el-table v-else :data="data.recentLeads" stripe>
<el-table-column label="联系人">
<template #default="{ row }">
{{ row.contactName || "未填写联系人" }}
</template>
</el-table-column>
<el-table-column prop="phone" label="联系方式" />
<el-table-column prop="destination" label="目的地" />
<el-table-column label="状态">
<template #default="{ row }">
{{ leadStatusLabel(row.status) }}
</template>
</el-table-column>
<el-table-column label="提交时间">
<template #default="{ row }">
{{ formatDate(row.createdAt) }}
</template>
</el-table-column>
</el-table>
</el-card>
</template>
</div>
</template>