This commit is contained in:
menxipeng
2025-10-26 16:41:05 +08:00
parent c79456dd55
commit d47cf290e5
2 changed files with 160 additions and 49 deletions

View File

@@ -1,4 +1,4 @@
import React from "react"
import { useState, useEffect } from "react"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../ui/card"
import { Button } from "../ui/button"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../ui/select"
@@ -16,13 +16,59 @@ import {
CheckCircle,
Clock,
MapPin,
Building2,
HardHat,
} from "lucide-react"
import { apiGet } from "@/services/api"
import { getUserData } from "@/utils/storage"
// 定义统计数据接口
interface StatisticsData {
equipmentTotal: number
equipmentGrowth: string
completedWorkOrders: number
workOrdersGrowth: string
systemUsers: number
usersGrowth: string
systemMerchants: number
merchantsGrowth: string
systemMalls: number | null
mallsGrowth: string
systemWorkers: number
workersGrowth: string
totalMerchants: number
}
export default function StatisticsPage() {
const [statisticsData, setStatisticsData] = useState<StatisticsData | null>(null)
const [loading, setLoading] = useState(true)
const userData = getUserData()
// 判断是否是总公司账号(根据实际业务逻辑调整)
const isHeadquarters = userData?.role === 'admin' || userData?.roleType === 'headquarters'
useEffect(() => {
fetchStatistics()
}, [])
const fetchStatistics = async () => {
try {
setLoading(true)
const response = await apiGet<{ code: number; msg: string; data: StatisticsData }>('/back/statistics/planTop')
if (response.code === 200) {
setStatisticsData(response.data)
}
} catch (error) {
console.error('获取统计数据失败:', error)
} finally {
setLoading(false)
}
}
const stats = {
totalEquipment: 1248,
activeWorkOrders: 23,
totalUsers: 156,
totalEquipment: statisticsData?.equipmentTotal || 0,
activeWorkOrders: statisticsData?.completedWorkOrders || 0,
totalUsers: statisticsData?.systemUsers || 0,
lowStock: 8,
equipmentStatus: {
normal: 1156,
@@ -161,21 +207,21 @@ export default function StatisticsPage() {
},
]
// 区域设备分布
const regionEquipmentData = [
{ region: "华东区", equipment: 456, workOrders: 89 },
{ region: "华南区", equipment: 342, workOrders: 67 },
{ region: "华北区", equipment: 298, workOrders: 52 },
{ region: "华中区", equipment: 152, workOrders: 34 },
]
// 区域设备分布(暂未使用)
// const regionEquipmentData = [
// { region: "华东区", equipment: 456, workOrders: 89 },
// { region: "华南区", equipment: 342, workOrders: 67 },
// { region: "华北区", equipment: 298, workOrders: 52 },
// { region: "华中区", equipment: 152, workOrders: 34 },
// ]
// 设备类型分布
const equipmentTypeData = [
{ type: "干粉灭火器", count: 567, percentage: 45.4 },
{ type: "自动喷淋", count: 234, percentage: 18.8 },
{ type: "烟感器", count: 298, percentage: 23.9 },
{ type: "消防栓", count: 149, percentage: 11.9 },
]
// 设备类型分布(暂未使用)
// const equipmentTypeData = [
// { type: "干粉灭火器", count: 567, percentage: 45.4 },
// { type: "自动喷淋", count: 234, percentage: 18.8 },
// { type: "烟感器", count: 298, percentage: 23.9 },
// { type: "消防栓", count: 149, percentage: 11.9 },
// ]
return (
<div className="space-y-6">
@@ -205,58 +251,112 @@ export default function StatisticsPage() {
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
{/* 1. 所有地区设备总数 */}
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<CardTitle className="text-sm font-medium"></CardTitle>
<Shield className="h-4 w-4 text-blue-600" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{stats.totalEquipment}</div>
<div className="text-2xl font-bold">{loading ? '-' : statisticsData?.equipmentTotal || 0}</div>
<p className="text-xs text-muted-foreground">
<TrendingUp className="inline h-3 w-3 mr-1" />
12%
{loading ? '-' : statisticsData?.equipmentGrowth || '0%'}
</p>
</CardContent>
</Card>
{/* 2. 完成工单 */}
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<Wrench className="h-4 w-4 text-green-600" />
<CardTitle className="text-sm font-medium"></CardTitle>
<CheckCircle className="h-4 w-4 text-green-600" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{stats.activeWorkOrders}</div>
<div className="text-2xl font-bold">{loading ? '-' : statisticsData?.completedWorkOrders || 0}</div>
<p className="text-xs text-muted-foreground">
<Clock className="inline h-3 w-3 mr-1" />
2.3
<TrendingUp className="inline h-3 w-3 mr-1" />
{loading ? '-' : statisticsData?.workOrdersGrowth || '0%'}
</p>
</CardContent>
</Card>
{/* 3. 系统用户 */}
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<Users className="h-4 w-4 text-purple-600" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{stats.totalUsers}</div>
<p className="text-xs text-muted-foreground"> 142 </p>
</CardContent>
</Card>
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<Package className="h-4 w-4 text-orange-600" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold text-orange-600">{stats.lowStock}</div>
<div className="text-2xl font-bold">{loading ? '-' : statisticsData?.systemUsers || 0}</div>
<p className="text-xs text-muted-foreground">
<AlertTriangle className="inline h-3 w-3 mr-1" />
<TrendingUp className="inline h-3 w-3 mr-1" />
{loading ? '-' : statisticsData?.usersGrowth || '0%'}
</p>
</CardContent>
</Card>
{/* 4. 系统商户 */}
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<Package className="h-4 w-4 text-orange-600" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{loading ? '-' : statisticsData?.systemMerchants || 0}</div>
<p className="text-xs text-muted-foreground">
<TrendingUp className="inline h-3 w-3 mr-1" />
{loading ? '-' : statisticsData?.merchantsGrowth || '0%'}
</p>
</CardContent>
</Card>
{/* 5. 系统商场 */}
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<Building2 className="h-4 w-4 text-indigo-600" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{loading ? '-' : statisticsData?.systemMalls || 0}</div>
<p className="text-xs text-muted-foreground">
<TrendingUp className="inline h-3 w-3 mr-1" />
{loading ? '-' : statisticsData?.mallsGrowth || '0%'}
</p>
</CardContent>
</Card>
{/* 6. 系统工人 */}
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<HardHat className="h-4 w-4 text-yellow-600" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{loading ? '-' : statisticsData?.systemWorkers || 0}</div>
<p className="text-xs text-muted-foreground">
<TrendingUp className="inline h-3 w-3 mr-1" />
{loading ? '-' : statisticsData?.workersGrowth || '0%'}
</p>
</CardContent>
</Card>
{/* 7. 总商户 - 仅总公司账号可见 */}
{isHeadquarters && (
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium"></CardTitle>
<Wrench className="h-4 w-4 text-red-600" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{loading ? '-' : statisticsData?.totalMerchants || 0}</div>
<p className="text-xs text-muted-foreground">
<TrendingUp className="inline h-3 w-3 mr-1" />
{loading ? '-' : statisticsData?.merchantsGrowth || '0%'}
</p>
</CardContent>
</Card>
)}
</div>
<Card>

View File

@@ -435,20 +435,22 @@ export default function WorkOrdersPage() {
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{loadingWorkOrders ? (
<TableRow>
<TableCell colSpan={7} className="text-center py-8">
<TableCell colSpan={9} className="text-center py-8">
<div className="text-gray-500">...</div>
</TableCell>
</TableRow>
) : filteredWorkOrders.length === 0 ? (
<TableRow>
<TableCell colSpan={7} className="text-center py-8">
<TableCell colSpan={9} className="text-center py-8">
<div className="text-gray-500"></div>
</TableCell>
</TableRow>
@@ -485,12 +487,21 @@ export default function WorkOrdersPage() {
</div>
</TableCell>
<TableCell>
<div className="space-y-1">
<div className="flex items-center text-sm">
<Calendar className="h-3 w-3 mr-1 text-blue-500" />
<span className="text-blue-600">: {item.scheduledDate || "未设置"}</span>
</div>
<div className="text-xs text-gray-500">: {item.createdDate}</div>
<div className="text-sm text-gray-600">{item.createdDate || "-"}</div>
</TableCell>
<TableCell>
<div className="flex items-center text-sm">
<Calendar className="h-3 w-3 mr-1 text-blue-500" />
<span className="text-blue-600">{item.scheduledDate || "未设置"}</span>
</div>
</TableCell>
<TableCell>
<div className="text-sm text-gray-600">
{item.completedDate ? (
<span className="text-green-600">{item.completedDate}</span>
) : (
<span className="text-gray-400">-</span>
)}
</div>
</TableCell>
<TableCell>