import React, { useEffect, useState } from 'react'; import { Card, Row, Col, Button, Space, Typography, message, Spin, Form, InputNumber, Divider, DatePicker, Modal } from 'antd'; import { DownloadOutlined, SaveOutlined, ReloadOutlined, SettingOutlined, ExclamationCircleOutlined } from '@ant-design/icons'; import dayjs, { Dayjs } from 'dayjs'; import http from '../../api/http'; import { useIsMobile } from '../../hooks/useBreakpoint'; const { Title, Text } = Typography; interface RuleResponse { ruleId: number; ruleKey: string; ruleValue: any; description: string | null; effectiveCycle: string | null; updatedBy: number | null; updatedAt: string; } // 规则字段配置 const RULE_FIELDS = { business: [ { name: 'business_completion_weight', label: '工作完成度', max: 70 }, { name: 'business_quality_weight', label: '工作质量', max: 70 }, { name: 'business_efficiency_weight', label: '工作效率', max: 70 }, { name: 'business_skill_weight', label: '专业技能', max: 70 }, { name: 'business_innovation_weight', label: '创新能力', max: 70 }, { name: 'business_problem_solving_weight', label: '问题解决', max: 70 }, { name: 'business_customer_satisfaction_weight', label: '客户满意度', max: 70 }, { name: 'business_teamwork_weight', label: '团队协作', max: 70 }, { name: 'business_goal_achievement_weight', label: '目标达成', max: 70 }, ], comprehensive: [ { name: 'comprehensive_responsibility_weight', label: '责任心', max: 30 }, { name: 'comprehensive_initiative_weight', label: '主动性', max: 30 }, { name: 'comprehensive_learning_weight', label: '学习能力', max: 30 }, { name: 'comprehensive_communication_weight', label: '沟通能力', max: 30 }, { name: 'comprehensive_execution_weight', label: '执行力', max: 30 }, { name: 'comprehensive_discipline_weight', label: '纪律性', max: 30 }, { name: 'comprehensive_team_spirit_weight', label: '团队精神', max: 30 }, { name: 'comprehensive_attendance_weight', label: '考勤', max: 30 }, ], reward: [ { name: 'reward_excellent', label: '优秀奖励(≥90分)', unit: '元' }, { name: 'punish_qualified_high', label: '合格扣款(80-89分)', unit: '元' }, { name: 'punish_qualified_low', label: '合格扣款(70-79分)', unit: '元' }, { name: 'punish_need_motivation', label: '需激励扣款(60-69分)', unit: '元' }, { name: 'punish_unqualified', label: '不合格扣款(<60分)', unit: '元' }, ], attendance: [ { name: 'attendance_leave_deduct', label: '事假扣分(每天)', unit: '分' }, { name: 'attendance_late_deduct', label: '迟到扣分(每次)', unit: '分' }, { name: 'attendance_lack_card_deduct', label: '缺卡扣分(每次)', unit: '分' }, { name: 'attendance_base_score', label: '考勤基础分', unit: '分' }, ], }; const ConfigManagement: React.FC = () => { const [loading, setLoading] = useState(false); const [saving, setSaving] = useState(false); const [exporting, setExporting] = useState(false); const [rules, setRules] = useState([]); const [selectedMonth, setSelectedMonth] = useState(dayjs()); const [form] = Form.useForm(); const isMobile = useIsMobile(); const loadRules = async () => { setLoading(true); try { const { data } = await http.get('/api/config/rules'); const ruleList: RuleResponse[] = data.data || data; setRules(ruleList); const formValues: Record = {}; ruleList.forEach((rule) => { formValues[rule.ruleKey] = rule.ruleValue; }); form.setFieldsValue(formValues); } catch (err: any) { message.error(err?.response?.data?.message || '加载配置规则失败'); } finally { setLoading(false); } }; useEffect(() => { loadRules(); }, []); const handleSave = async () => { try { const values = await form.validateFields(); Modal.confirm({ title: '确认修改考核规则', icon: , content: '修改后的规则将应用于后续考核周期,是否确认?', okText: '确认', cancelText: '取消', onOk: async () => { setSaving(true); try { await http.put('/api/config/rules', { rules: Object.entries(values).map(([ruleKey, ruleValue]) => ({ ruleKey, ruleValue })), }); message.success('规则更新成功'); await loadRules(); } catch (err: any) { message.error(err?.response?.data?.message || '规则更新失败'); } finally { setSaving(false); } }, }); } catch { message.error('请检查表单输入'); } }; const handleExport = async () => { setExporting(true); try { const month = selectedMonth.format('YYYY-MM'); const response = await http.get('/api/performance/export', { params: { month, type: 'all' }, responseType: 'blob' }); const url = window.URL.createObjectURL(new Blob([response.data])); const link = document.createElement('a'); link.href = url; link.setAttribute('download', `全公司绩效数据_${month}.xlsx`); document.body.appendChild(link); link.click(); link.remove(); window.URL.revokeObjectURL(url); message.success('导出成功'); } catch (err: any) { message.error(err?.response?.data?.message || '导出失败'); } finally { setExporting(false); } }; if (loading && rules.length === 0) return
; // 移动端每行2列,桌面端每行3或4列 const colSpan = isMobile ? 12 : 8; const colSpan4 = isMobile ? 12 : 6; return (
系统配置与数据导出 {/* 数据导出 */} 全量数据导出} style={{ marginBottom: 16 }} bodyStyle={{ padding: isMobile ? 12 : 24 }}> 选择考核月份,导出全公司所有员工的绩效数据(Excel 格式) d && setSelectedMonth(d)} format="YYYY-MM" /> {/* 考核规则配置 */} 考核规则配置} bodyStyle={{ padding: isMobile ? 12 : 24 }} extra={ } >
业务素质考核指标权重(总计70分) {RULE_FIELDS.business.map(f => ( ))} 综合素质考核指标权重(总计30分) {RULE_FIELDS.comprehensive.map(f => ( ))} 奖惩金额配置 {RULE_FIELDS.reward.map(f => ( ))} 考勤扣分规则 {RULE_FIELDS.attendance.map(f => ( ))}
注意:修改考核规则后,将自动应用于后续考核周期。已完成的历史绩效数据不受影响。
); }; export default ConfigManagement;