refactor(backend): 重构动物相关 API 接口

- 更新了动物数据结构和相关类型定义
- 优化了动物列表、详情、创建、更新和删除接口
- 新增了更新动物状态接口
- 移除了与认领记录相关的接口
-调整了 API 响应结构
This commit is contained in:
ylweng
2025-08-31 23:26:25 +08:00
parent 5b5d65e072
commit cbee609e78
25 changed files with 3232 additions and 375 deletions

View File

@@ -6,7 +6,7 @@
>
<template #extra>
<a-space>
<a-button>刷新</a-button>
<a-button @click="loadDashboardData">刷新</a-button>
<a-button type="primary">导出数据</a-button>
</a-space>
</template>
@@ -20,7 +20,7 @@
<a-card>
<a-statistic
title="总用户数"
:value="11284"
:value="dashboardData.userCount"
:precision="0"
suffix="人"
>
@@ -34,7 +34,7 @@
<a-card>
<a-statistic
title="商家数量"
:value="356"
:value="dashboardData.merchantCount"
:precision="0"
suffix="家"
>
@@ -48,7 +48,7 @@
<a-card>
<a-statistic
title="旅行计划"
:value="1287"
:value="dashboardData.travelCount"
:precision="0"
suffix="个"
>
@@ -62,7 +62,7 @@
<a-card>
<a-statistic
title="动物认领"
:value="542"
:value="dashboardData.animalCount"
:precision="0"
suffix="只"
>
@@ -138,19 +138,44 @@
</template>
<script setup lang="ts">
import {
UserOutlined,
ShopOutlined,
CompassOutlined,
HeartOutlined,
BarChartOutlined,
PieChartOutlined
} from '@ant-design/icons-vue'
import { UserOutlined, ShopOutlined, CompassOutlined, HeartOutlined, BarChartOutlined, PieChartOutlined } from '@ant-design/icons-vue'
import { ref, onMounted } from 'vue'
import { useAppStore } from '@/stores/app'
import { getSystemStats } from '@/api/system'
import { getUsers } from '@/api/user'
import { getMerchants } from '@/api/merchant'
import { getTravels } from '@/api/travel'
import { getAnimals } from '@/api/animal'
// 定义仪表板数据结构
interface DashboardData {
userCount: number
merchantCount: number
travelCount: number
animalCount: number
orderCount: number
todayUserCount: number
todayOrderCount: number
}
const appStore = useAppStore()
const appVersion = import.meta.env.VITE_APP_VERSION || '1.0.0'
const environment = import.meta.env.MODE || 'development'
const startupTime = new Date().toLocaleString()
// 仪表板数据
const dashboardData = ref<DashboardData>({
userCount: 0,
merchantCount: 0,
travelCount: 0,
animalCount: 0,
orderCount: 0,
todayUserCount: 0,
todayOrderCount: 0
})
// 最近活动(暂时保持静态数据)
const recentActivities = [
{
title: '新用户注册',
@@ -177,6 +202,71 @@ const recentActivities = [
time: '15分钟前'
}
]
// 加载仪表板数据
const loadDashboardData = async () => {
try {
// 检查用户是否已登录
if (!appStore.state.user) {
// 尝试重新初始化应用状态
await appStore.initialize()
// 如果仍然没有用户信息,则跳转到登录页
if (!appStore.state.user) {
window.location.href = '/login'
return
}
}
// 获取系统统计信息
const statsResponse = await getSystemStats()
if (statsResponse.success) {
// 从statsResponse.data中获取统计数据
const data = statsResponse.data
dashboardData.value.userCount = data.userCount
dashboardData.value.merchantCount = data.merchantCount
dashboardData.value.travelCount = data.travelCount
dashboardData.value.animalCount = data.animalCount
dashboardData.value.orderCount = data.orderCount
dashboardData.value.todayUserCount = data.todayUserCount
dashboardData.value.todayOrderCount = data.todayOrderCount
}
// 如果系统统计API不可用则使用独立的API调用来获取各类统计数据
if (!statsResponse.success) {
// 获取用户总数
const userResponse = await getUsers({ page: 1, pageSize: 1 })
if (userResponse.data.success) {
dashboardData.value.userCount = userResponse.data.pagination?.total || 0
}
// 获取商家总数
const merchantResponse = await getMerchants({ page: 1, limit: 1 })
if (merchantResponse.data.success) {
dashboardData.value.merchantCount = merchantResponse.data.pagination?.total || 0
}
// 获取旅行计划总数
const travelResponse = await getTravels({ page: 1, limit: 1 })
if (travelResponse.data.success) {
dashboardData.value.travelCount = travelResponse.data.pagination?.total || 0
}
// 获取动物总数
const animalResponse = await getAnimals({ page: 1, limit: 1 })
if (animalResponse.data.success) {
dashboardData.value.animalCount = animalResponse.data.pagination?.total || 0
}
}
} catch (error) {
console.error('加载仪表板数据失败:', error)
}
}
// 组件挂载时加载数据
onMounted(() => {
loadDashboardData()
})
</script>
<style scoped>
@@ -199,47 +289,18 @@ const recentActivities = [
}
.chart-card,
.activity-card,
.info-card {
border-radius: 8px;
height: 100%;
}
.chart-placeholder {
height: 300px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #999;
font-size: 16px;
text-align: center;
padding: 40px 0;
color: #ccc;
}
.chart-placeholder .anticon {
font-size: 48px;
margin-bottom: 16px;
color: #1890ff;
}
:deep(.ant-card-head) {
border-bottom: 1px solid #f0f0f0;
}
:deep(.ant-card-body) {
padding: 24px;
}
:deep(.ant-statistic) {
text-align: center;
}
:deep(.ant-statistic-title) {
font-size: 14px;
color: #666;
margin-bottom: 8px;
}
:deep(.ant-statistic-content) {
font-size: 24px;
font-weight: 600;
}
</style>