d
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user