Files
SBrainCO/client/src/components/smart-scheduling/OverallAnalysisTab.tsx
T

115 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useQuery } from '@tanstack/react-query'
import api from '@/lib/api'
import { LoadingSpinner } from '@/components/LoadingSpinner'
const LEVEL_STYLES: Record<string, { bg: string; border: string; text: string; icon: string }> = {
red: { bg: 'bg-red-50', border: 'border-red-200', text: 'text-red-700', icon: '🔴' },
orange: { bg: 'bg-orange-50', border: 'border-orange-200', text: 'text-orange-700', icon: '🟠' },
yellow: { bg: 'bg-yellow-50', border: 'border-yellow-200', text: 'text-yellow-700', icon: '🟡' },
green: { bg: 'bg-green-50', border: 'border-green-200', text: 'text-green-700', icon: '🟢' },
}
const CATEGORY_LABELS: Record<string, string> = {
'人效': '人效分析',
'成本': '成本管控',
'加班': '加班管理',
'客流': '客流规律',
'考勤': '考勤管理',
'离职': '人员稳定',
}
export function OverallAnalysisTab({ month }: { month: string }) {
const { data, isLoading } = useQuery({
queryKey: ['ss/overall-analysis', month],
queryFn: () => api.get('/smart-scheduling/overall-analysis', { params: { month } }),
})
if (isLoading) return <LoadingSpinner text="生成总体智能分析..." />
const result = (data as any)?.data || {}
const kpis: any[] = result.kpis || []
const insights: any[] = result.insights || []
const redCount = insights.filter(i => i.level === 'red').length
const orangeCount = insights.filter(i => i.level === 'orange').length
const yellowCount = insights.filter(i => i.level === 'yellow').length
const greenCount = insights.filter(i => i.level === 'green').length
return (
<div className="space-y-4">
{/* KPI 卡片 */}
<div className="grid grid-cols-5 gap-3">
{kpis.map((k) => (
<div key={k.label} className="rounded-lg border p-3 text-center">
<p className="text-xs text-muted-foreground">{k.label}</p>
<p className="text-xl font-bold mt-1">
{k.value}
<span className="text-xs font-normal text-muted-foreground ml-1">{k.unit}</span>
</p>
</div>
))}
</div>
{/* 预警汇总 */}
<div className="grid grid-cols-4 gap-3">
<div className="rounded-lg border border-red-200 bg-red-50 p-3">
<p className="text-xs text-red-600"></p>
<p className="text-2xl font-bold text-red-700">{redCount}</p>
</div>
<div className="rounded-lg border border-orange-200 bg-orange-50 p-3">
<p className="text-xs text-orange-600"></p>
<p className="text-2xl font-bold text-orange-700">{orangeCount}</p>
</div>
<div className="rounded-lg border border-yellow-200 bg-yellow-50 p-3">
<p className="text-xs text-yellow-600"></p>
<p className="text-2xl font-bold text-yellow-700">{yellowCount}</p>
</div>
<div className="rounded-lg border border-green-200 bg-green-50 p-3">
<p className="text-xs text-green-600"></p>
<p className="text-2xl font-bold text-green-700">{greenCount}</p>
</div>
</div>
{/* 智能诊断建议 */}
<div className="space-y-3">
<div className="flex items-center justify-between">
<h2 className="text-lg font-bold"></h2>
<span className="text-xs text-muted-foreground"></span>
</div>
{insights.length === 0 ? (
<div className="rounded-lg border p-8 text-center text-muted-foreground">
</div>
) : (
<div className="space-y-3">
{insights.map((ins, i) => {
const style = LEVEL_STYLES[ins.level] || LEVEL_STYLES.yellow
return (
<div key={i} className={`rounded-lg border ${style.border} ${style.bg} p-4`}>
<div className="flex items-start gap-3">
<span className="text-lg mt-0.5">{style.icon}</span>
<div className="flex-1">
<div className="flex items-center gap-2 mb-1">
<span className={`text-xs px-2 py-0.5 rounded bg-white/60 ${style.text} font-medium`}>
{CATEGORY_LABELS[ins.category] || ins.category}
</span>
<h3 className="font-bold text-sm">{ins.title}</h3>
</div>
<p className="text-sm text-muted-foreground mb-2">{ins.detail}</p>
<div className="flex items-start gap-2">
<span className="text-xs text-muted-foreground whitespace-nowrap">💡 </span>
<p className="text-sm">{ins.suggestion}</p>
</div>
</div>
</div>
</div>
)
})}
</div>
)}
</div>
</div>
)
}