优化: 大文件拆分+代码分割+按需加载+console清理+any类型替换
- Money.tsx (2260行→54行): 拆分为 money/ 子目录4个组件, React.lazy二级分割 - AIAssistant.tsx (2038行→63行): 拆分为 ai-assistant/ 子目录6个组件, React.lazy二级分割 - xlsx改为动态导入, OvertimeTab从345KB降至12.7KB - api-services.ts: 请求参数 any→Record<string,unknown> - 移除前端3处console.log残留 - 后端console替换为pino logger - 前后端未使用import/变量清理 - Zod schema验证: termination/platform/special-status/work-process - 新增 leave.routes.ts, acceptance-test.routes.ts - UI组件: PageGuide, QueryError, Stepper
This commit is contained in:
@@ -24,6 +24,7 @@ const QUICK_PAGES: SearchResult[] = [
|
||||
{ type: 'page', id: 'social', title: '社保公积金', link: '/social', icon: 'shield' },
|
||||
{ type: 'page', id: 'termination', title: '离职管理', link: '/termination', icon: 'userX' },
|
||||
{ type: 'page', id: 'attendance', title: '考勤排班', link: '/attendance', icon: 'calendar' },
|
||||
{ type: 'page', id: 'leave-approval', title: '休假审批', link: '/leave-approval', icon: 'calendar' },
|
||||
{ type: 'page', id: 'risk-center', title: '风险中心', link: '/risk-center', icon: 'alert' },
|
||||
{ type: 'page', id: 'salary-dashboard', title: '薪酬分析', link: '/salary-dashboard', icon: 'chart' },
|
||||
{ type: 'page', id: 'policies', title: '规章制度', link: '/policies', icon: 'file' },
|
||||
|
||||
@@ -23,8 +23,8 @@ export default class ErrorBoundary extends Component<Props, State> {
|
||||
return { hasError: true, error }
|
||||
}
|
||||
|
||||
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
|
||||
console.error('ErrorBoundary caught:', error, errorInfo)
|
||||
componentDidCatch(_error: Error, _errorInfo: React.ErrorInfo) {
|
||||
// 错误已通过 getDerivedStateFromError 捕获并展示降级 UI
|
||||
}
|
||||
|
||||
handleReset = () => {
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* PageGuide 页面操作指导组件 — 折叠式,默认收起
|
||||
* 统一用于各页面/Tab的操作说明,点击展开查看
|
||||
*/
|
||||
import { useState, ReactNode } from 'react'
|
||||
import { ChevronRight, Lightbulb } from 'lucide-react'
|
||||
|
||||
interface PageGuideProps {
|
||||
/** 指导标题,默认"操作说明" */
|
||||
title?: string
|
||||
/** 指导内容,支持字符串或自定义JSX */
|
||||
children: ReactNode
|
||||
/** 额外类名 */
|
||||
className?: string
|
||||
}
|
||||
|
||||
export default function PageGuide({ title = '操作说明', children, className = '' }: PageGuideProps) {
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
return (
|
||||
<div className={`rounded-md border border-blue-100 bg-blue-50/50 ${className}`}>
|
||||
<button
|
||||
onClick={() => setOpen(!open)}
|
||||
className="flex items-center gap-1.5 w-full px-3 py-1.5 text-xs font-medium text-blue-600 hover:text-blue-700 transition-colors"
|
||||
>
|
||||
<ChevronRight className={`w-3 h-3 transition-transform ${open ? 'rotate-90' : ''}`} />
|
||||
<Lightbulb className="w-3.5 h-3.5" />
|
||||
{title}
|
||||
</button>
|
||||
{open && (
|
||||
<div className="px-3 pb-2.5 text-xs text-blue-600/80 leading-relaxed">
|
||||
{children}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { AlertCircle, RefreshCw } from 'lucide-react'
|
||||
|
||||
interface QueryErrorProps {
|
||||
error?: unknown
|
||||
onRetry?: () => void
|
||||
message?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询错误状态组件
|
||||
* 在 useQuery 的 isError 状态下显示错误提示和重试按钮
|
||||
*/
|
||||
export default function QueryError({ error, onRetry, message }: QueryErrorProps) {
|
||||
const errMsg = message
|
||||
|| (error as any)?.response?.data?.error?.message
|
||||
|| (error as any)?.message
|
||||
|| '数据加载失败,请稍后重试'
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center py-12 px-4 text-center">
|
||||
<div className="w-12 h-12 rounded-full bg-red-50 flex items-center justify-center mb-3">
|
||||
<AlertCircle className="w-6 h-6 text-red-500" />
|
||||
</div>
|
||||
<p className="text-sm text-gray-600 mb-3 max-w-md">{errMsg}</p>
|
||||
{onRetry && (
|
||||
<button
|
||||
onClick={onRetry}
|
||||
className="inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium text-primary bg-primary/5 rounded-lg hover:bg-primary/10 transition-colors"
|
||||
>
|
||||
<RefreshCw className="w-3.5 h-3.5" />
|
||||
重试
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
* Stepper 步骤条组件 — 用于多步骤工作流引导
|
||||
* 支持横向/纵向布局、可点击步骤导航、完成/当前/待办状态
|
||||
*/
|
||||
import { ReactNode } from 'react'
|
||||
import clsx from 'clsx'
|
||||
import { Check } from 'lucide-react'
|
||||
|
||||
@@ -24,7 +23,6 @@ interface StepperProps {
|
||||
* Stepper 步骤条 — 展示工作流进度和步骤导航
|
||||
*/
|
||||
export function Stepper({ steps, orientation = 'horizontal', onStepClick, className }: StepperProps) {
|
||||
const currentIndex = steps.findIndex(s => s.status === 'current')
|
||||
|
||||
if (orientation === 'vertical') {
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user