diff --git a/src/pages/performancemanage_performanceassess/PerformanceAssess.js b/src/pages/performancemanage_performanceassess/PerformanceAssess.js
index c326e77..75d4750 100644
--- a/src/pages/performancemanage_performanceassess/PerformanceAssess.js
+++ b/src/pages/performancemanage_performanceassess/PerformanceAssess.js
@@ -1,14 +1,349 @@
-import React, {Fragment, PureComponent} from 'react';
+import React, { PureComponent } from 'react';
+import { Card, Input, Button, Select, Row, Col, Avatar, Rate, message } from 'antd';
+import { SearchOutlined, ReloadOutlined, SaveOutlined, RollbackOutlined, UserOutlined } from '@ant-design/icons';
+import { history } from 'umi';
import styles from './PerformanceAssess.less';
+
+const { TextArea } = Input;
+const { Option } = Select;
+
class PerformanceAssess extends PureComponent {
- render() {
-
- return (
- <>
-
- >
- )
- }
+ constructor(props) {
+ super(props);
+ this.state = {
+ // 筛选条件
+ searchForm: {
+ name: '',
+ phone: '',
+ idCard: '',
+ performancePlan: '2025年度'
+ },
+ // 员工信息
+ employeeInfo: {
+ gender: '男',
+ age: 32,
+ department: '技术研发中心',
+ position: '高级软件工程师',
+ planName: '2025年度技术岗绩效计划'
+ },
+ // 绩效数据
+ performanceData: {
+ totalScore: 92,
+ status: '已确认',
+ objective: {
+ codeLines: '15,672',
+ docWords: '28,500',
+ trainings: '8',
+ projectAmount: '¥1,250,000',
+ projectRatio: '35%',
+ workHours: '1,850'
+ },
+ subjective: {
+ execution: {
+ score: 4.0,
+ comment: '该员工能够高效执行分配的任务,在项目开发过程中表现出色,能够按时保质完成工作。在团队协作中主动承担责任,遇到问题能够积极寻求解决方案。'
+ },
+ loyalty: {
+ score: 4.5,
+ comment: '该员工高度认同公司文化和价值观,积极参与公司组织的各项活动。在日常工作中能够主动传播正能量,对新员工起到良好的示范作用。对公司发展战略有深刻理解并积极支持。'
+ }
+ }
+ }
+ };
+ }
+
+ // 处理搜索表单变化
+ handleSearchFormChange = (field, value) => {
+ this.setState(prevState => ({
+ searchForm: {
+ ...prevState.searchForm,
+ [field]: value
+ }
+ }));
+ };
+
+ // 处理主观评价变化
+ handleSubjectiveChange = (type, field, value) => {
+ this.setState(prevState => ({
+ performanceData: {
+ ...prevState.performanceData,
+ subjective: {
+ ...prevState.performanceData.subjective,
+ [type]: {
+ ...prevState.performanceData.subjective[type],
+ [field]: value
+ }
+ }
+ }
+ }));
+ };
+
+ // 查询按钮处理
+ handleSearch = () => {
+ message.success('查询成功');
+ };
+
+ // 重置按钮处理
+ handleReset = () => {
+ this.setState({
+ searchForm: {
+ name: '',
+ phone: '',
+ idCard: '',
+ performancePlan: '2025年度'
+ }
+ });
+ message.info('已重置查询条件');
+ };
+
+ // 保存评价
+ handleSave = () => {
+ message.success('评价已保存');
+ };
+
+ // 返回列表
+ handleBack = () => {
+ history.push('/topnavbar00/performancemanage/performancelist');
+ };
+
+ render() {
+ const { searchForm, employeeInfo, performanceData } = this.state;
+
+ return (
+
+ {/* 筛选区 */}
+
+
+
+
+
+ this.handleSearchFormChange('name', e.target.value)}
+ />
+
+
+
+
+
+ this.handleSearchFormChange('phone', e.target.value)}
+ />
+
+
+
+
+
+ this.handleSearchFormChange('idCard', e.target.value)}
+ />
+
+
+
+
+
+
+
+
+
+
+ } onClick={this.handleSearch}>
+ 查询
+
+ } onClick={this.handleReset}>
+ 重置
+
+
+
+
+ {/* 人员信息 */}
+
+
+
} className={styles['employee-avatar']} />
+
+
+
+
+ 性别
+ {employeeInfo.gender}
+
+
+
+
+ 年龄
+ {employeeInfo.age}
+
+
+
+
+ 部门
+ {employeeInfo.department}
+
+
+
+
+ 岗位
+ {employeeInfo.position}
+
+
+
+
+
+
+ 绩效计划名称
+ {employeeInfo.planName}
+
+
+
+
+
+ {/* 绩效公式 */}
+
+ 绩效公式
+
+ 总分 = 代码量 × 0.1 + 文档字数 × 0.01 + 培训次数 × 3 + 项目金额 × 0.01 + 项目比重 × 0.1 + 工作时长 × 0.01 + 执行力 × 0.1 + 对公司认同度 × 0.1
+
+
+
+ {/* 绩效总分 */}
+
+
+
+
+ 绩效总分
+ {performanceData.totalScore}
+
+
+
+
+ 审批状态
+ {performanceData.status}
+
+
+
+
+
+ {/* 客观指标 */}
+
+ 客观指标
+
+
+
+ 代码量
+ {performanceData.objective.codeLines} 行
+
+
+
+
+ 文档字数
+ {performanceData.objective.docWords} 字
+
+
+
+
+ 培训次数
+ {performanceData.objective.trainings} 次
+
+
+
+
+ 项目金额
+ {performanceData.objective.projectAmount}
+
+
+
+
+ 项目比重
+ {performanceData.objective.projectRatio}
+
+
+
+
+ 工作时长
+ {performanceData.objective.workHours} 小时
+
+
+
+
+
+ {/* 主观指标 */}
+
+ {/* 执行力 */}
+
+
+ 执行力
+
+ 评分:
+ this.handleSubjectiveChange('execution', 'score', value)}
+ />
+ {performanceData.subjective.execution.score}
+
+
+
+
+
+
+
+ {/* 对公司认同度 */}
+
+
+ 对公司认同度
+
+ 评分:
+ this.handleSubjectiveChange('loyalty', 'score', value)}
+ />
+ {performanceData.subjective.loyalty.score}
+
+
+
+
+
+
+
+
+ {/* 操作按钮 */}
+
+ } onClick={this.handleSave}>
+ 保存评价
+
+ } onClick={this.handleBack}>
+ 返回列表
+
+
+
+ );
+ }
}
-export default PerformanceAssess
+export default PerformanceAssess;
diff --git a/src/pages/performancemanage_performanceassess/PerformanceAssess.less b/src/pages/performancemanage_performanceassess/PerformanceAssess.less
index d5bff80..0c72016 100644
--- a/src/pages/performancemanage_performanceassess/PerformanceAssess.less
+++ b/src/pages/performancemanage_performanceassess/PerformanceAssess.less
@@ -1,10 +1,456 @@
@import '~@/utils/utils.less';
-.frameContent {
- width: 100%;
- height: 100vh;
- border: none;
- display: block;
- margin: 0;
- padding: 0;
+/* 绩效评估页面样式 */
+.performance-assess-page {
+ padding: 24px;
+ background-color: #f5f6fa;
+ min-height: 90vh;
+ max-height: 90vh; /* 限制最大高度 */
+ overflow-y: auto; /* 添加垂直滚动条 */
+ overflow-x: hidden; /* 隐藏水平滚动条 */
+
+ /* 自定义滚动条样式 */
+ &::-webkit-scrollbar {
+ width: 8px;
+ }
+
+ &::-webkit-scrollbar-track {
+ background: #f1f1f1;
+ border-radius: 4px;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background: #c1c1c1;
+ border-radius: 4px;
+
+ &:hover {
+ background: #a8a8a8;
+ }
+ }
+
+ .ant-card {
+ border-radius: 8px;
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
+ margin-bottom: 20px; /* 增加卡片间隔 */
+ transition: all 0.3s ease;
+
+ &:hover {
+ box-shadow: 0 8px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
+ transform: translateY(-2px);
+ }
+
+ /* 最后一个卡片不需要下边距 */
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+}
+
+/* 筛选区样式 */
+.search-section {
+ margin-bottom: 10px; /* 增加与后续内容的间隔 */
+
+ .ant-card-body {
+ padding: 20px; /* 调整内边距 */
+ }
+
+ .form-item {
+ margin-bottom: 16px;
+
+ .form-label {
+ display: block;
+ font-size: 12px;
+ color: #6b7280;
+ margin-bottom: 4px;
+ }
+ }
+
+ .search-actions {
+ display: flex;
+ justify-content: flex-end;
+ gap: 8px;
+ margin-top: 16px;
+ padding-top: 16px;
+ border-top: 1px solid #f3f4f6; /* 添加分隔线 */
+
+ .ant-btn {
+ font-size: 14px;
+ height: 32px;
+ padding: 0 16px;
+ border-radius: 4px;
+ }
+ }
+}
+
+/* 人员信息样式 */
+.employee-section {
+ margin-bottom: 10px;
+
+ .ant-card-body {
+ padding: 20px;
+ }
+
+ .employee-info {
+ display: flex;
+ align-items: center;
+ gap: 20px; /* 增加元素间隔 */
+
+ .employee-avatar {
+ flex-shrink: 0;
+ background-color: #e5e7eb;
+ }
+
+ .employee-details {
+ flex: 1;
+ }
+
+ .plan-info {
+ flex-shrink: 0;
+ min-width: 200px; /* 确保有足够空间 */
+ }
+
+ .info-item {
+ display: flex;
+ flex-direction: column;
+ margin-bottom: 8px; /* 增加项目间隔 */
+
+ .info-label {
+ font-size: 12px;
+ color: #6b7280;
+ margin-bottom: 4px;
+ }
+
+ .info-value {
+ font-size: 14px;
+ color: #111827;
+ font-weight: 500;
+ }
+ }
+ }
+}
+
+/* 绩效公式样式 */
+.formula-section {
+ margin-bottom: 10px;
+
+ .ant-card-body {
+ padding: 20px;
+ }
+
+ .section-title {
+ font-size: 14px;
+ font-weight: 500;
+ color: #111827;
+ margin-bottom: 12px;
+ margin-top: 0;
+ }
+
+ .formula-content {
+ background-color: #f3f4f6;
+ padding: 12px; /* 增加内边距 */
+ border-radius: 6px;
+ font-size: 12px;
+ color: #374151;
+ line-height: 1.5; /* 增加行高 */
+ border-left: 4px solid #2d5cf6; /* 添加左边框 */
+ }
+}
+
+/* 绩效总分样式 */
+.score-section {
+ margin-bottom: 10px;
+
+ .ant-card-body {
+ padding: 20px;
+ }
+
+ .score-info {
+ display: flex;
+ flex-direction: column;
+
+ .score-label {
+ font-size: 12px;
+ color: #6b7280;
+ margin-bottom: 6px;
+ }
+
+ .score-value {
+ font-size: 36px; /* 增大字体 */
+ font-weight: bold;
+ color: #2d5cf6;
+ line-height: 1;
+ }
+ }
+
+ .status-info {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+
+ .status-label {
+ font-size: 12px;
+ color: #6b7280;
+ margin-bottom: 6px;
+ }
+
+ .status-value {
+ font-size: 16px; /* 增大字体 */
+ color: #059669;
+ font-weight: 500;
+ padding: 4px 12px;
+ background-color: #d1fae5;
+ border-radius: 12px;
+ }
+ }
+}
+
+/* 客观指标样式 */
+.objective-section {
+ margin-bottom: 10px;
+
+ .ant-card-body {
+ padding: 20px;
+ }
+
+ .section-title {
+ font-size: 14px;
+ font-weight: 500;
+ color: #111827;
+ margin-bottom: 16px;
+ margin-top: 0;
+ padding-bottom: 8px;
+ border-bottom: 2px solid #f3f4f6;
+ }
+
+ .metric-item {
+ display: flex;
+ flex-direction: column;
+ padding: 12px;
+ background-color: #f9fafb;
+ border-radius: 6px;
+ border: 1px solid #e5e7eb;
+ margin-bottom: 8px;
+
+ .metric-label {
+ font-size: 12px;
+ color: #6b7280;
+ margin-bottom: 4px;
+ }
+
+ .metric-value {
+ font-size: 16px;
+ color: #111827;
+ font-weight: 600;
+ }
+ }
+}
+
+/* 主观指标样式 */
+.subjective-section {
+ // margin-bottom: 10px;
+
+ .subjective-card {
+ height: auto;
+ margin-bottom: 16px;
+
+ .ant-card-body {
+ padding: 20px;
+ }
+
+ .section-title {
+ font-size: 14px;
+ font-weight: 500;
+ color: #111827;
+ margin-bottom: 16px;
+ margin-top: 0;
+ padding-bottom: 8px;
+ border-bottom: 2px solid #f3f4f6;
+ }
+
+ .rating-section {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ margin-bottom: 16px;
+ padding: 12px;
+ background-color: #f9fafb;
+ border-radius: 6px;
+
+ .rating-label {
+ font-size: 14px;
+ color: #374151;
+ font-weight: 500;
+ }
+
+ .rating-value {
+ font-size: 14px;
+ color: #111827;
+ font-weight: 600;
+ background-color: #2d5cf6;
+ color: white;
+ padding: 2px 8px;
+ border-radius: 4px;
+ }
+ }
+
+ .comment-section {
+ .comment-label {
+ display: block;
+ font-size: 12px;
+ color: #6b7280;
+ margin-bottom: 8px;
+ font-weight: 500;
+ }
+
+ .ant-input {
+ font-size: 14px;
+ border-radius: 6px;
+ border: 2px solid #e5e7eb;
+ padding: 12px;
+ min-height: 120px; /* 增加最小高度 */
+
+ &:focus {
+ border-color: #2d5cf6;
+ box-shadow: 0 0 0 3px rgba(45, 92, 246, 0.1);
+ }
+ }
+ }
+ }
+}
+
+/* 操作按钮样式 */
+.action-section {
+ display: flex;
+ justify-content: flex-end;
+ gap: 16px;
+ // margin-top: 32px;
+ // padding-top: 24px;
+ // border-top: 2px solid #f3f4f6;
+
+ .ant-btn {
+ padding: 12px 32px;
+ height: auto;
+ font-size: 14px;
+ border-radius: 6px;
+ font-weight: 500;
+ }
+
+ .ant-btn-primary {
+ background-color: #2d5cf6;
+ border-color: #2d5cf6;
+
+ &:hover {
+ background-color: #1d4ed8;
+ border-color: #1d4ed8;
+ transform: translateY(-1px);
+ box-shadow: 0 4px 12px rgba(45, 92, 246, 0.3);
+ }
+ }
+
+ .ant-btn:not(.ant-btn-primary) {
+ border: 2px solid #e5e7eb;
+ color: #374151;
+
+ &:hover {
+ border-color: #d1d5db;
+ transform: translateY(-1px);
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+ }
+ }
+}
+
+/* 响应式样式 */
+@media (max-width: 768px) {
+ .performance-assess-page {
+ padding: 16px;
+ max-height: 90vh;
+ overflow-y: auto;
+ }
+
+ .ant-card {
+ margin-bottom: 16px;
+
+ .ant-card-body {
+ padding: 16px !important;
+ }
+ }
+
+ .employee-section {
+ .employee-info {
+ flex-direction: column;
+ align-items: flex-start;
+ gap: 16px;
+
+ .employee-details {
+ width: 100%;
+ }
+
+ .plan-info {
+ width: 100%;
+ min-width: auto;
+ }
+ }
+ }
+
+ .subjective-section {
+ .ant-col {
+ margin-bottom: 16px;
+ }
+ }
+
+ .action-section {
+ flex-direction: column;
+ gap: 12px;
+
+ .ant-btn {
+ width: 100%;
+ }
+ }
+
+ .objective-section {
+ .ant-row {
+ .ant-col {
+ margin-bottom: 12px;
+ }
+ }
+ }
+}
+
+/* 自定义Rate组件样式 */
+.ant-rate {
+ font-size: 18px;
+
+ .ant-rate-star {
+ margin-right: 6px;
+ }
+
+ .ant-rate-star-full .ant-rate-star-first,
+ .ant-rate-star-full .ant-rate-star-second {
+ color: #faad14;
+ }
+}
+
+/* Firefox 滚动条样式 */
+.performance-assess-page {
+ scrollbar-width: thin;
+ scrollbar-color: #c1c1c1 #f1f1f1;
+}
+
+/* 输入框聚焦效果增强 */
+.ant-input:focus,
+.ant-select-focused .ant-select-selector {
+ border-color: #2d5cf6;
+ box-shadow: 0 0 0 3px rgba(45, 92, 246, 0.1);
+}
+
+/* 卡片内容区域滚动优化 */
+.ant-card-body {
+ overflow: hidden; /* 防止内容溢出 */
+}
+
+/* 长文本内容滚动 */
+.comment-section .ant-input {
+ resize: vertical; /* 允许垂直调整大小 */
+ max-height: 200px; /* 限制最大高度 */
+ overflow-y: auto; /* 超出时显示滚动条 */
}
\ No newline at end of file
diff --git a/src/pages/performancemanage_performancelist/PerformanceList.js b/src/pages/performancemanage_performancelist/PerformanceList.js
index 613c948..88429c0 100644
--- a/src/pages/performancemanage_performancelist/PerformanceList.js
+++ b/src/pages/performancemanage_performancelist/PerformanceList.js
@@ -1,14 +1,647 @@
-import React, {Fragment, PureComponent} from 'react';
+import React, { PureComponent } from 'react';
+import {
+ Card,
+ Tree,
+ Button,
+ Select,
+ Space,
+ Row,
+ Col,
+ Pagination,
+ Modal,
+ message
+} from 'antd';
+import { history } from 'umi';
+import {
+ ExpandOutlined,
+ UserOutlined,
+ TeamOutlined,
+ ApartmentOutlined,
+ SyncOutlined,
+ DollarOutlined,
+ SettingOutlined,
+ DownloadOutlined,
+ UserAddOutlined,
+ EditOutlined,
+ DeleteOutlined,
+ PlusOutlined
+} from '@ant-design/icons';
import styles from './PerformanceList.less';
+import StandardTable from '@/components/StandardTable';
+import PerformanceAdd from './form/PerformanceAdd';
+import PerformanceRenderSimpleForm from "./form/PerformanceRenderSimpleForm" //表单
+
+const { Option } = Select;
+
class PerformanceList extends PureComponent {
+ constructor(props) {
+ super(props);
+ this.state = {
+ searchForm: {},
+ selectedKeys: [],
+ expandedKeys: ['0-0', '0-0-0', '0-0-1', '0-0-2'],
+ addModalVisible: false, // 新增弹窗显示状态
+ addLoading: false, // 新增loading状态
+ organizationData: [
+ {
+ title: '飞利信科技有限公司',
+ key: '0-0',
+ count: 356,
+ children: [
+ {
+ title: '技术部',
+ key: '0-0-0',
+ count: 120,
+ children: [
+ { title: '前端组', key: '0-0-0-0', count: 45 },
+ { title: '后端组', key: '0-0-0-1', count: 52 },
+ { title: '测试组', key: '0-0-0-2', count: 23 }
+ ],
+ },
+ {
+ title: '产品部',
+ key: '0-0-1',
+ count: 68,
+ children: [
+ { title: '产品设计组', key: '0-0-1-0', count: 28 },
+ { title: '用户体验组', key: '0-0-1-1', count: 25 },
+ { title: '产品运营组', key: '0-0-1-2', count: 15 }
+ ],
+ },
+ {
+ title: '运营部',
+ key: '0-0-2',
+ count: 52,
+ children: [
+ { title: '市场营销组', key: '0-0-2-0', count: 22 },
+ { title: '客户服务组', key: '0-0-2-1', count: 18 },
+ { title: '商务合作组', key: '0-0-2-2', count: 12 }
+ ],
+ },
+ {
+ title: '财务部',
+ key: '0-0-3',
+ count: 32,
+ children: [
+ { title: '会计组', key: '0-0-3-0', count: 18 },
+ { title: '审计组', key: '0-0-3-1', count: 14 }
+ ],
+ },
+ {
+ title: '人事部',
+ key: '0-0-4',
+ count: 84,
+ children: [
+ { title: 'HR专员组', key: '0-0-4-0', count: 25 },
+ { title: '招聘组', key: '0-0-4-1', count: 22 },
+ { title: '培训组', key: '0-0-4-2', count: 18 },
+ { title: '薪酬组', key: '0-0-4-3', count: 19 }
+ ],
+ },
+ ],
+ },
+ ],
+ tableData: [
+ {
+ key: '1',
+ name: '张三',
+ gender: '男',
+ age: 28,
+ department: '技术部',
+ position: '高级工程师',
+ totalScore: 92,
+ performanceStatus: '优秀'
+ },
+ {
+ key: '2',
+ name: '李四',
+ gender: '男',
+ age: 30,
+ department: '产品部',
+ position: '产品经理',
+ totalScore: 88,
+ performanceStatus: '良好'
+ },
+ {
+ key: '3',
+ name: '王五',
+ gender: '女',
+ age: 25,
+ department: '运营部',
+ position: '运营专员',
+ totalScore: 85,
+ performanceStatus: '良好'
+ },
+ {
+ key: '4',
+ name: '赵六',
+ gender: '男',
+ age: 32,
+ department: '财务部',
+ position: '会计',
+ totalScore: 78,
+ performanceStatus: '合格'
+ },
+ {
+ key: '5',
+ name: '陈七',
+ gender: '女',
+ age: 26,
+ department: '人事部',
+ position: 'HR专员',
+ totalScore: 65,
+ performanceStatus: '不合格'
+ },
+ ],
+ pagination: {
+ current: 1,
+ pageSize: 5,
+ total: 356,
+ },
+ selectedRecord: null, // 选中的记录,用于编辑
+ };
+
+ // 默认列配置
+ this.defaultColumns = [
+ {
+ title: '姓名',
+ dataIndex: 'name',
+ key: 'name',
+ width: 100,
+ align: 'center',
+ render: (text, record) => (
+
+ ),
+ },
+ {
+ title: '性别',
+ dataIndex: 'gender',
+ key: 'gender',
+ width: 80,
+ align: 'center',
+ },
+ {
+ title: '年龄',
+ dataIndex: 'age',
+ key: 'age',
+ width: 80,
+ align: 'center',
+ },
+ {
+ title: '部门',
+ dataIndex: 'department',
+ key: 'department',
+ width: 120,
+ align: 'center',
+ },
+ {
+ title: '职位',
+ dataIndex: 'position',
+ key: 'position',
+ width: 140,
+ align: 'center',
+ },
+ {
+ title: '绩效总分',
+ dataIndex: 'totalScore',
+ key: 'totalScore',
+ width: 100,
+ align: 'center',
+ render: (score) => (
+ = 90 ? '#52c41a' :
+ score >= 80 ? '#1890ff' :
+ score >= 70 ? '#faad14' : '#ff4d4f'
+ }}>
+ {score}
+
+ ),
+ sorter: (a, b) => a.totalScore - b.totalScore,
+ },
+ {
+ title: '绩效状态',
+ dataIndex: 'performanceStatus',
+ key: 'performanceStatus',
+ width: 120,
+ align: 'center',
+ render: (status) => {
+ const statusConfig = {
+ '优秀': { color: '#52c41a', bgColor: '#f6ffed', borderColor: '#b7eb8f' },
+ '良好': { color: '#1890ff', bgColor: '#e6f7ff', borderColor: '#91d5ff' },
+ '合格': { color: '#faad14', bgColor: '#fffbe6', borderColor: '#ffd666' },
+ '不合格': { color: '#ff4d4f', bgColor: '#fff2f0', borderColor: '#ffadd2' },
+ '待评估': { color: '#666', bgColor: '#f5f5f5', borderColor: '#d9d9d9' }
+ };
+ const config = statusConfig[status] || statusConfig['待评估'];
+
+ return (
+
+ {status}
+
+ );
+ }
+ },
+ {
+ title: '操作',
+ key: 'action',
+ width: 120,
+ align: 'center',
+ render: (_, record) => (
+
+ }
+ title="编辑绩效"
+ onClick={() => this.handleEdit(record)}
+ >
+ {/* 编辑 */}
+
+ }
+ title="删除记录"
+ onClick={() => this.handleDelete(record)}
+ >
+ {/* 删除 */}
+
+
+ ),
+ },
+ ];
+ }
+
+ // 获取处理后的树形数据
+ getTreeData = () => {
+ const { organizationData } = this.state;
+
+ const processNode = (node) => ({
+ key: node.key,
+ title: (
+
+ {this.getNodeIcon(node.title)}
+ {node.title}
+ ({node.count})
+
+ ),
+ children: node.children ? node.children.map(processNode) : undefined
+ });
+
+ return organizationData.map(processNode);
+ };
+
+ // 获取节点图标
+ getNodeIcon = (title) => {
+ if (title.includes('公司') || title.includes('集团')) return ;
+ if (title.includes('技术') || title.includes('开发') || title.includes('测试')) return ;
+ if (title.includes('产品') || title.includes('设计') || title.includes('体验')) return ;
+ if (title.includes('运营') || title.includes('市场') || title.includes('客户') || title.includes('商务')) return ;
+ if (title.includes('财务') || title.includes('会计') || title.includes('审计')) return ;
+ if (title.includes('人事') || title.includes('HR') || title.includes('招聘') || title.includes('培训') || title.includes('薪酬')) return ;
+ return ;
+ };
+
+ // 搜索处理
+ handleSearch = (values) => {
+ console.log('搜索参数:', values);
+ this.setState({ searchForm: values });
+ };
+
+ // 重置搜索
+ handleReset = () => {
+ this.formRef?.resetFields();
+ this.setState({ searchForm: {} });
+ };
+
+ // 树节点选择
+ onTreeSelect = (selectedKeys, info) => {
+ console.log('选中节点:', selectedKeys, info);
+ this.setState({ selectedKeys });
+ };
+
+ // 树节点展开
+ onTreeExpand = (expandedKeys) => {
+ this.setState({ expandedKeys });
+ };
+
+ // 刷新树数据
+ handleTreeRefresh = () => {
+ // console.log('刷新组织架构');
+ // 这里可以添加刷新树数据的逻辑
+ };
+
+ // 展开/收缩所有节点
+ handleTreeToggle = () => {
+ const { expandedKeys, organizationData } = this.state;
+ if (expandedKeys.length > 0) {
+ // 收缩所有节点
+ this.setState({ expandedKeys: [] });
+ } else {
+ // 展开所有节点
+ const getAllKeys = (nodes) => {
+ let keys = [];
+ nodes.forEach(node => {
+ keys.push(node.key);
+ if (node.children) {
+ keys = keys.concat(getAllKeys(node.children));
+ }
+ });
+ return keys;
+ };
+ this.setState({ expandedKeys: getAllKeys(organizationData) });
+ }
+ };
+
+ renderSimpleForm() {
+ const { prooperlog = {} } = this.props;
+ const { params = {} } = prooperlog;
+ const parentMethods = {
+ handleSearch: this.handleSearch,
+ handleFormReset: this.handleFormReset,
+ toggleForm: this.toggleForm,
+ submitButtons: styles.submitButtons,
+ params
+ };
+ return (
+
+ );
+ }
+
+ renderAdvancedForm() {
+ const { prooperlog: { params } } = this.props;
+ const parentMethods = {
+ handleSearch: this.handleSearch,
+ handleFormReset: this.handleFormReset,
+ toggleForm: this.toggleForm,
+ params
+ };
+
+ return (
+
+ );
+ }
+
+ renderForm() {
+ const { expandForm } = this.state;
+ return expandForm ? this.renderAdvancedForm() : this.renderSimpleForm();
+ }
+
+ // 分页处理
+ onPaginationChange = (page, pageSize) => {
+ this.setState({
+ pagination: {
+ ...this.state.pagination,
+ current: page,
+ pageSize,
+ }
+ });
+ };
+
+ // 显示新增弹窗
+ showAddModal = () => {
+ this.setState({ addModalVisible: true });
+ };
+
+ // 关闭新增/编辑弹窗
+ hideAddModal = () => {
+ this.setState({
+ addModalVisible: false,
+ selectedRecord: null // 清空选中记录
+ });
+ };
+
+ // 新增成功回调
+ handleAddSuccess = (values) => {
+ console.log('新增成功:', values);
+
+ // 这里可以刷新列表数据
+ // 模拟添加到表格数据中
+ const newStaff = {
+ key: String(Date.now()),
+ id: this.state.tableData.length + 1,
+ name: values.name,
+ phone: values.age, // 年龄
+ idCard: values.department, // 部门
+ department: values.position, // 岗位
+ position: values.workType, // 工作性质
+ status: values.phone, // 电话
+ entryDate: new Date().toISOString().split('T')[0]
+ };
+
+ this.setState({
+ tableData: [...this.state.tableData, newStaff],
+ pagination: {
+ ...this.state.pagination,
+ total: this.state.pagination.total + 1
+ }
+ });
+ };
+
+ // 处理姓名点击事件
+ handleNameClick = (record) => {
+ console.log('查看员工绩效详情:', record);
+ // 可以跳转到绩效详情页面或显示详情模态框
+ Modal.info({
+ title: `${record.name} - 绩效详情`,
+ width: 600,
+ content: (
+
+
员工姓名:{record.name}
+
性别:{record.gender}
+
年龄:{record.age}岁
+
部门:{record.department}
+
职位:{record.position}
+
绩效总分:= 90 ? '#52c41a' :
+ record.totalScore >= 80 ? '#1890ff' :
+ record.totalScore >= 70 ? '#faad14' : '#ff4d4f'
+ }}>{record.totalScore}
+
绩效状态:{record.performanceStatus}
+
+ ),
+ okText: '确定'
+ });
+ };
+
+ // 处理编辑
+ handleEdit = (record) => {
+ console.log('编辑员工绩效:', record);
+ this.setState({
+ selectedRecord: record,
+ showPerformanceAdd: true
+ });
+ };
+
+ // 处理删除
+ handleDelete = (record) => {
+ Modal.confirm({
+ title: '删除确认',
+ content: `确定要删除员工 "${record.name}" 的绩效记录吗?`,
+ okText: '确定',
+ cancelText: '取消',
+ onOk: () => {
+ // 实际项目中这里应该调用删除接口
+ console.log('删除绩效记录:', record.id);
+
+ const newData = this.state.tableData.filter(item => item.id !== record.id);
+ this.setState({
+ tableData: newData,
+ pagination: {
+ ...this.state.pagination,
+ total: newData.length
+ }
+ });
+ message.success('删除成功');
+ }
+ });
+ };
+
render() {
+ const { tableData, pagination, expandedKeys, addModalVisible, addLoading } = this.state;
return (
- <>
-
- >
- )
+
+ {/* 主体内容 */}
+
+
+
+ {/* 左侧组织架构树 */}
+
+
+
+
+ 组织架构
+
+
+ }
+ size="small"
+ style={{ color: '#1890ff' }}
+ onClick={this.handleTreeRefresh}
+ title="刷新"
+ />
+ }
+ size="small"
+ style={{ color: '#1890ff' }}
+ onClick={this.handleTreeToggle}
+ title={expandedKeys.length > 0 ? "收缩全部" : "展开全部"}
+ />
+
+
+ }
+ className={styles.treeCard}
+ >
+
+
+
+
+
+
+ {/* 右侧人员信息区 */}
+
+ {/* 筛选条件 */}
+
+ {this.renderForm()}
+
+
+ {/* 操作按钮和统计 */}
+
+
+ {/* 共 {pagination.total} 条记录 */}
+
+
+ }
+ size="middle"
+ className={styles.exportButton}
+ >
+ 导出
+
+ }
+ size="middle"
+ className={styles.addButton}
+ onClick={this.showAddModal}
+ >
+ 新增
+
+
+
+
+ {/* 人员表格 */}
+
+
+
+ {/* 分页 */}
+
+
+ `显示 ${range[0]} 到 ${range[1]} 条,共 ${total} 条记录`
+ }
+ onChange={this.onPaginationChange}
+ onShowSizeChange={this.onPaginationChange}
+ />
+
+
+
+
+
+
+
+ {/* 新增/编辑绩效弹窗 */}
+
+
+ );
}
}
-export default PerformanceList
+export default PerformanceList;
\ No newline at end of file
diff --git a/src/pages/performancemanage_performancelist/PerformanceList.less b/src/pages/performancemanage_performancelist/PerformanceList.less
index d5bff80..b7d2aa3 100644
--- a/src/pages/performancemanage_performancelist/PerformanceList.less
+++ b/src/pages/performancemanage_performancelist/PerformanceList.less
@@ -1,10 +1,523 @@
@import '~@/utils/utils.less';
-.frameContent {
- width: 100%;
+.staffInfoContainer {
+ min-height: 100vh;
height: 100vh;
- border: none;
- display: block;
- margin: 0;
- padding: 0;
+ // background-color: #f5f6fa;
+
+ .announcementBar {
+ background: #e6f7ff;
+ border: 1px solid #91d5ff;
+ margin-bottom: 16px;
+ border-radius: 6px;
+ overflow: hidden;
+
+ .announcement {
+ display: flex;
+ align-items: center;
+
+ .announcementLabel {
+ background-color: #fef3c7;
+ color: #92400e;
+ border-radius: 4px;
+ padding: 4px 8px;
+ font-size: 12px;
+ font-weight: 500;
+ margin-right: 12px;
+ white-space: nowrap;
+ display: flex;
+ align-items: center;
+
+ .anticon {
+ margin-right: 4px;
+ }
+ }
+
+ .scrollContainer {
+ flex: 1;
+ overflow: hidden;
+ white-space: nowrap;
+ }
+
+ .scrollContent {
+ display: inline-block;
+ animation: scroll 30s linear infinite;
+ color: #666;
+ font-size: 14px;
+ }
+ }
+ }
+
+ .mainContent {
+ // padding: 12px;
+
+ .contentCard {
+ .ant-card-head {
+ .ant-card-head-title {
+ font-size: 18px;
+ font-weight: 600;
+ color: #333;
+ }
+ }
+ }
+
+ .treeCard {
+ height: 600px;
+ border: 1px solid #e8e8e8;
+ border-radius: 8px;
+
+ .treeHeader {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ font-size: 14px;
+ font-weight: 500;
+ }
+
+ .treeContainer {
+ height: 520px;
+ overflow-y: auto;
+
+ /* 自定义滚动条样式 */
+ &::-webkit-scrollbar {
+ width: 6px;
+ }
+
+ &::-webkit-scrollbar-track {
+ background: transparent;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background: #d9d9d9;
+ border-radius: 3px;
+
+ &:hover {
+ background: #bfbfbf;
+ }
+ }
+
+ .orgTree {
+ .ant-tree-treenode {
+ padding: 2px 0;
+
+ .ant-tree-node-content-wrapper {
+ border-radius: 4px;
+ transition: all 0.3s ease;
+ padding: 4px 8px;
+
+ &:hover {
+ background-color: #f0f9ff;
+ transform: translateX(2px);
+ }
+
+ &.ant-tree-node-selected {
+ background-color: #e6f7ff !important;
+ box-shadow: 0 2px 8px rgba(24, 144, 255, 0.2);
+ }
+ }
+
+ .ant-tree-iconEle {
+ margin-right: 8px;
+ }
+
+ .ant-tree-title {
+ font-size: 14px;
+ }
+ }
+ }
+ }
+ }
+
+ /* Tree节点标题样式 */
+ .tree-node-title {
+ display: flex;
+ align-items: center;
+ width: 100%;
+
+ .node-title {
+ flex: 1;
+ font-size: 14px;
+ margin-left: 8px;
+ color: #333;
+ }
+
+ .node-count {
+ color: #999;
+ font-size: 12px;
+ margin-left: auto;
+ background: #f0f0f0;
+ padding: 1px 6px;
+ border-radius: 10px;
+ min-width: 20px;
+ text-align: center;
+ }
+ }
+
+ .searchCard {
+ margin-bottom: 16px;
+ border-radius: 8px;
+ border: 1px solid #e8e8e8;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+
+ .ant-card-body {
+ padding: 16px;
+ }
+
+ /* 搜索表单容器样式 */
+ .searchFormContainer {
+ .searchForm {
+ .ant-form-item {
+ margin-bottom: 16px;
+
+ .ant-form-item-label {
+ font-weight: 500;
+ color: #333;
+
+ label {
+ color: #333 !important;
+ font-size: 14px;
+ }
+ }
+
+ .ant-input,
+ .ant-select-selector,
+ .ant-picker {
+ border-radius: 6px;
+ border: 1px solid #d9d9d9;
+ transition: all 0.3s ease;
+
+ &:hover {
+ border-color: #4c7bff;
+ }
+
+ &:focus,
+ &.ant-select-focused .ant-select-selector,
+ &.ant-picker-focused {
+ border-color: #2d5cf6;
+ box-shadow: 0 0 0 2px rgba(45, 92, 246, 0.2);
+ }
+ }
+
+ .ant-select-selection-placeholder,
+ .ant-input::placeholder,
+ .ant-picker-input input::placeholder {
+ color: #bfbfbf;
+ }
+ }
+ }
+ }
+
+ /* 搜索按钮样式 */
+ .searchButton {
+ background: linear-gradient(135deg, #2d5cf6 0%, #4c7bff 100%);
+ border: none;
+ border-radius: 6px;
+ color: white;
+ font-weight: 500;
+ font-size: 14px;
+ box-shadow: 0 2px 8px rgba(45, 92, 246, 0.3);
+ transition: all 0.3s ease;
+ height: 32px;
+ padding: 0 16px;
+
+ &:hover,
+ &:focus {
+ background: linear-gradient(135deg, #4c7bff 0%, #6b8fff 100%);
+ transform: translateY(-1px);
+ box-shadow: 0 4px 12px rgba(45, 92, 246, 0.4);
+ color: white;
+ }
+
+ &:active {
+ transform: translateY(0);
+ }
+ }
+
+ /* 重置按钮样式 */
+ .resetButton {
+ background: #fff;
+ border: 1px solid #d9d9d9;
+ color: #666;
+ border-radius: 6px;
+ font-weight: 500;
+ font-size: 14px;
+ transition: all 0.3s ease;
+ height: 32px;
+ padding: 0 16px;
+
+ &:hover,
+ &:focus {
+ border-color: #4c7bff;
+ color: #2d5cf6;
+ }
+
+ .anticon {
+ color: #ff7875;
+ }
+ }
+
+ /* 展开按钮样式 */
+ .expandButton {
+ color: #2d5cf6;
+ font-size: 14px;
+ padding: 0 8px;
+ height: 32px;
+
+ &:hover,
+ &:focus {
+ color: #4c7bff;
+ }
+ }
+ }
+
+ .actionBar {
+
+
+
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 16px;
+
+ .totalInfo {
+ color: #666;
+ font-size: 14px;
+ font-weight: 500;
+ }
+
+ .exportButton {
+ // background: linear-gradient(135deg, #52c41a 0%, #73d13d 100%);
+ // border: none;
+ // color: white;
+ // border-radius: 8px;
+ // font-weight: 500;
+ // font-size: 14px;
+ // box-shadow: 0 4px 12px rgba(82, 196, 26, 0.3);
+ // transition: all 0.3s ease;
+ // // margin-top: -8px;
+ // height: 35px;
+ // padding: 0 16px;
+
+
+ // &:hover,
+ // &:focus {
+ // background: linear-gradient(135deg, #73d13d 0%, #95de64 100%);
+ // transform: translateY(-2px);
+ // box-shadow: 0 6px 20px rgba(82, 196, 26, 0.4);
+ // color: white;
+ // }
+
+ // &:active {
+ // transform: translateY(0);
+ // }
+
+ // .anticon {
+ // color: white;
+ // }
+ }
+
+
+ .addButton {
+ // background: linear-gradient(135deg, #fa8c16 0%, #ffa940 100%);
+ // border: none;
+ // border-radius: 8px;
+ // font-weight: 600;
+ // font-size: 14px;
+ // box-shadow: 0 4px 12px rgba(250, 140, 22, 0.3);
+ // transition: all 0.3s ease;
+ // // margin-top: -8px;
+ // height: 35px;
+ // padding: 0 16px;
+
+
+ // &:hover,
+ // &:focus {
+ // background: linear-gradient(135deg, #ffa940 0%, #ffc069 100%);
+ // transform: translateY(-2px);
+ // box-shadow: 0 6px 20px rgba(250, 140, 22, 0.4);
+ // }
+
+ // &:active {
+ // transform: translateY(0);
+ // }
+ }
+ }
+
+ .tableCard {
+ border-radius: 8px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+ padding-bottom: 10px;
+
+ .ant-table-wrapper {
+ max-height: 600px;
+ overflow-y: auto;
+
+ /* 自定义滚动条样式 */
+ &::-webkit-scrollbar {
+ width: 8px;
+ }
+
+ &::-webkit-scrollbar-track {
+ background: #f5f5f5;
+ border-radius: 4px;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background: #d9d9d9;
+ border-radius: 4px;
+
+ &:hover {
+ background: #bfbfbf;
+ }
+ }
+
+ .ant-table-thead>tr>th {
+ background-color: #fafafa;
+ font-weight: 600;
+ color: #333;
+ border-bottom: 1px solid #e8e8e8;
+ position: sticky;
+ top: 0;
+ z-index: 1;
+ }
+
+ .ant-table-tbody>tr {
+ &:hover>td {
+ background-color: #f5f5f5 !important;
+ }
+
+ >td {
+ border-bottom: 1px solid #f0f0f0;
+ }
+ }
+ }
+
+ .paginationWrapper {
+ margin-top: 20px;
+ text-align: right;
+
+ .ant-pagination {
+ .ant-pagination-total-text {
+ color: #666;
+ }
+
+ .ant-pagination-item {
+ border-radius: 4px;
+
+ &.ant-pagination-item-active {
+ background-color: #2d5cf6;
+ border-color: #2d5cf6;
+ }
+ }
+
+ .ant-pagination-prev,
+ .ant-pagination-next {
+ border-radius: 4px;
+ }
+ }
+ }
+ }
+ }
+}
+
+.mainContent {
+ // padding: 12px;
+
+ .contentCard {
+ border: none !important;
+ .ant-card-head {
+ .ant-card-head-title {
+ font-size: 18px;
+ font-weight: 600;
+ color: #333;
+ }
+ }
+ }
+
+ .actionBar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 16px;
+
+ .totalInfo {
+ color: #666;
+ font-size: 14px;
+ }
+ }
+
+ :global {
+ .ant-card-body {
+ padding: 12px 24px 0px 24px;
+ }
+ }
+}
+
+
+@keyframes scroll {
+ 0% {
+ transform: translateX(0);
+ }
+
+ 100% {
+ transform: translateX(-50%);
+ }
+}
+
+// 响应式设计
+@media (max-width: 1200px) {
+ .staffInfoContainer {
+ .mainContent {
+ .searchCard {
+ .ant-row {
+ .ant-col {
+ margin-bottom: 16px;
+ }
+ }
+ }
+ }
+ }
+}
+
+// 自定义主题色
+.ant-btn-primary {
+ background-color: #2d5cf6;
+ border-color: #2d5cf6;
+
+ &:hover,
+ &:focus {
+ background-color: #4c7bff;
+ border-color: #4c7bff;
+ }
+}
+
+.ant-tree .ant-tree-node-selected {
+ background-color: #e6f7ff !important;
+}
+
+.ant-select-focused .ant-select-selector,
+.ant-input-affix-wrapper-focused,
+.ant-input:focus,
+.ant-input-focused {
+ border-color: #2d5cf6 !important;
+ box-shadow: 0 0 0 2px rgba(45, 92, 246, 0.2) !important;
+}
+
+// 标签样式优化
+.ant-tag {
+ border-radius: 4px;
+ font-size: 12px;
+}
+
+// 按钮组间距调整
+.ant-space-item {
+ .ant-btn+.ant-btn {
+ margin-left: 8px;
+ }
+}
+
+// 表格链接按钮样式
+.ant-btn-link {
+ padding: 0 4px;
+ font-size: 12px;
}
\ No newline at end of file
diff --git a/src/pages/performancemanage_performancelist/form/PerformanceAdd.js b/src/pages/performancemanage_performancelist/form/PerformanceAdd.js
new file mode 100644
index 0000000..9b1a8da
--- /dev/null
+++ b/src/pages/performancemanage_performancelist/form/PerformanceAdd.js
@@ -0,0 +1,197 @@
+import React, { PureComponent } from 'react';
+import {
+ Modal,
+ Form,
+ Input,
+ Select,
+ InputNumber,
+ Row,
+ Col,
+ message
+} from 'antd';
+import {
+ UserOutlined,
+ PhoneOutlined,
+ TeamOutlined,
+ ApartmentOutlined
+} from '@ant-design/icons';
+
+const { Option } = Select;
+
+class PerformanceAdd extends PureComponent {
+ constructor(props) {
+ super(props);
+ this.formRef = React.createRef();
+ }
+
+ // 提交表单
+ handleSubmit = (values) => {
+ console.log('新增人员信息:', values);
+
+ // 这里可以调用API接口保存数据
+ // 模拟保存成功
+ message.success('新增人员成功!');
+
+ // 重置表单
+ this.formRef.current?.resetFields();
+
+ // 调用父组件的回调函数
+ if (this.props.onSuccess) {
+ this.props.onSuccess(values);
+ }
+
+ // 关闭弹窗
+ this.handleCancel();
+ };
+
+ // 取消操作
+ handleCancel = () => {
+ // 重置表单
+ this.formRef.current?.resetFields();
+
+ // 调用父组件的关闭回调
+ if (this.props.onCancel) {
+ this.props.onCancel();
+ }
+ };
+
+ render() {
+ const { visible, loading = false } = this.props;
+
+ return (
+ this.formRef.current?.submit()}
+ onCancel={this.handleCancel}
+ width={600}
+ confirmLoading={loading}
+ destroyOnClose={true}
+ maskClosable={false}
+ >
+
+
+ );
+ }
+}
+
+export default PerformanceAdd;
diff --git a/src/pages/performancemanage_performancelist/form/PerformanceRenderSimpleForm.js b/src/pages/performancemanage_performancelist/form/PerformanceRenderSimpleForm.js
new file mode 100644
index 0000000..f0a1644
--- /dev/null
+++ b/src/pages/performancemanage_performancelist/form/PerformanceRenderSimpleForm.js
@@ -0,0 +1,222 @@
+import React, { useState } from 'react';
+import { Button, Col, Form, Input, Row, message, Select, Space, InputNumber } from 'antd';
+import { ClearOutlined, SearchOutlined, ExpandOutlined, CompressOutlined, UserOutlined, PhoneOutlined, IdcardOutlined, TeamOutlined } from '@ant-design/icons';
+import styles from "../PerformanceList.less";
+
+const FormItem = Form.Item;
+const { Option } = Select;
+const PerformanceRenderSimpleForm = (props) => {
+ const [form] = Form.useForm();
+ const [expandForm, setExpandForm] = useState(false);
+ const { submitButtons, handleSearch, handleFormReset, toggleForm, params } = props;
+
+ React.useEffect(() => {
+ form.setFieldsValue({
+ name: params?.name,
+ phone: params?.phone,
+ idCard: params?.idCard,
+ department: params?.department,
+ gender: params?.gender,
+ ageMin: params?.ageMin,
+ ageMax: params?.ageMax,
+ performanceStatus: params?.performanceStatus,
+ });
+ }, [params]);
+
+ const onFinish = values => {
+ const searchParams = {
+ ...values,
+ // 年龄范围验证
+ ageMin: values.ageMin,
+ ageMax: values.ageMax,
+ };
+
+ // 验证年龄范围
+ if (values.ageMin && values.ageMax && values.ageMin > values.ageMax) {
+ message.error("最小年龄不能大于最大年龄!");
+ return;
+ }
+
+ handleSearch && handleSearch(searchParams);
+ };
+
+ const myhandleFormReset = () => {
+ form.resetFields();
+ handleFormReset && handleFormReset();
+ };
+
+ const toggleExpandForm = () => {
+ setExpandForm(!expandForm);
+ };
+
+ return (
+
+
+
+ );
+
+};
+
+export default PerformanceRenderSimpleForm;
diff --git a/src/pages/performancemanage_performancelist/form/PerformanceRenderSimpleForm.less b/src/pages/performancemanage_performancelist/form/PerformanceRenderSimpleForm.less
new file mode 100644
index 0000000..e69de29
diff --git a/src/pages/performancemanage_performanceruleset/PerformanceRuleset.js b/src/pages/performancemanage_performanceruleset/PerformanceRuleset.js
index e3139a0..d6713c8 100644
--- a/src/pages/performancemanage_performanceruleset/PerformanceRuleset.js
+++ b/src/pages/performancemanage_performanceruleset/PerformanceRuleset.js
@@ -1,14 +1,900 @@
-import React, {Fragment, PureComponent} from 'react';
+/**
+ * 数据字典管理页面
+ * 功能:管理系统中的元数据域和属性配置
+ * 包含:元数据域树形结构、属性列表、新增属性等功能
+ */
+import React, { PureComponent } from 'react';
+import {
+ Card,
+ Tree,
+ Button,
+ Select,
+ Space,
+ Row,
+ Col,
+ Pagination,
+ Modal,
+ message,
+ Input
+} from 'antd';
+import { history } from 'umi';
+import {
+ ExpandOutlined,
+ UserOutlined,
+ TeamOutlined,
+ ApartmentOutlined,
+ SyncOutlined,
+ SettingOutlined,
+ UserAddOutlined,
+ EditOutlined,
+ DeleteOutlined,
+ SearchOutlined,
+ FolderOutlined,
+ FileTextOutlined,
+ IdcardOutlined,
+ PhoneOutlined,
+ MailOutlined,
+ CalendarOutlined,
+ HomeOutlined,
+ PlusOutlined,
+ DownloadOutlined,
+ ExclamationCircleOutlined
+} from '@ant-design/icons';
import styles from './PerformanceRuleset.less';
+import StandardTable from '@/components/StandardTable';
+import PerformanceRulesetAdd from './form/PerformanceRulesetAdd';
+
+const { Option } = Select;
+
+/**
+ * 数据字典管理组件
+ * 左侧显示元数据域树形结构,右侧显示选中域的属性列表
+ */
class PerformanceRuleset extends PureComponent {
+ constructor(props) {
+ super(props);
+ this.state = {
+ searchForm: {},
+ selectedKeys: ['performance_params'],
+ expandedKeys: ['basic_info', 'performance_params'],
+ searchValue: '', // 搜索关键词
+ filteredTreeData: [], // 过滤后的树数据
+ addModalVisible: false, // 新增弹窗显示状态
+ addLoading: false, // 新增loading状态
+ organizationData: [
+ {
+ title: '基础信息',
+ key: 'basic_info',
+ code: 'EMP_BASIC_INFO',
+ description: '员工基础信息数据域,包含员工的基本身份信息和个人资料',
+ children: [
+ { title: '员工编号', key: 'employee_id', isLeaf: true },
+ { title: '姓名', key: 'name', isLeaf: true },
+ { title: '性别', key: 'gender', isLeaf: true }
+ ],
+ },
+ {
+ title: '技术职务',
+ key: 'tech_position',
+ code: 'EMP_TECH_POSITION',
+ description: '员工技术职务信息数据域,包含技术等级、职务级别等信息',
+ children: [],
+ },
+ {
+ title: '绩效参数',
+ key: 'performance_params',
+ code: 'EMP_PERFORMANCE',
+ description: '用于记录员工各项绩效指标的参数集合',
+ children: [
+ { title: '代码量', key: 'code_amount', isLeaf: true },
+ { title: '文档字数', key: 'doc_words', isLeaf: true },
+ { title: '出勤时长', key: 'attendance_hours', isLeaf: true },
+ { title: '项目金额', key: 'project_amount', isLeaf: true },
+ { title: '培训时长', key: 'training_hours', isLeaf: true },
+ { title: '会议次数', key: 'meeting_count', isLeaf: true },
+ { title: '会议时长', key: 'meeting_hours', isLeaf: true },
+ { title: '千行 bug 数', key: 'bug_count', isLeaf: true },
+ { title: '运维响应时间', key: 'response_time', isLeaf: true },
+ { title: '员工满意度', key: 'satisfaction', isLeaf: true }
+ ],
+ },
+ {
+ title: '联系方式',
+ key: 'contact_info',
+ code: 'EMP_CONTACT',
+ description: '员工联系方式信息数据域,包含电话、邮箱、地址等联系信息',
+ children: [],
+ },
+ {
+ title: '其他信息',
+ key: 'other_info',
+ code: 'EMP_OTHER',
+ description: '员工其他补充信息数据域,包含备注、特殊说明等信息',
+ children: [],
+ },
+ ],
+ tableData: [
+ {
+ key: '1',
+ id: 1,
+ fieldName: 'code_amount',
+ displayName: '代码量',
+ dataType: '数字',
+ unit: '行',
+ required: true,
+ defaultValue: '-'
+ },
+ {
+ key: '2',
+ id: 2,
+ fieldName: 'doc_words',
+ displayName: '文档字数',
+ dataType: '数字',
+ unit: '字',
+ required: true,
+ defaultValue: '-'
+ },
+ {
+ key: '3',
+ id: 3,
+ fieldName: 'attendance_hours',
+ displayName: '出勤时长',
+ dataType: '数字',
+ unit: '小时',
+ required: true,
+ defaultValue: '-'
+ },
+ {
+ key: '4',
+ id: 4,
+ fieldName: 'project_amount',
+ displayName: '项目金额',
+ dataType: '数字',
+ unit: '元',
+ required: false,
+ defaultValue: '-'
+ },
+ {
+ key: '5',
+ id: 5,
+ fieldName: 'training_hours',
+ displayName: '培训时长',
+ dataType: '数字',
+ unit: '小时',
+ required: false,
+ defaultValue: '-'
+ },
+ {
+ key: '6',
+ id: 6,
+ fieldName: 'meeting_count',
+ displayName: '会议次数',
+ dataType: '数字',
+ unit: '次',
+ required: true,
+ defaultValue: '-'
+ },
+ {
+ key: '7',
+ id: 7,
+ fieldName: 'meeting_hours',
+ displayName: '会议时长',
+ dataType: '数字',
+ unit: '分钟',
+ required: false,
+ defaultValue: '-'
+ },
+ {
+ key: '8',
+ id: 8,
+ fieldName: 'bug_count',
+ displayName: '千行 bug 数',
+ dataType: '数字',
+ unit: '个/千行',
+ required: true,
+ defaultValue: '-'
+ },
+ {
+ key: '9',
+ id: 9,
+ fieldName: 'response_time',
+ displayName: '运维响应时间',
+ dataType: '数字',
+ unit: '分钟',
+ required: true,
+ defaultValue: '-'
+ },
+ {
+ key: '10',
+ id: 10,
+ fieldName: 'satisfaction',
+ displayName: '员工满意度',
+ dataType: '数字',
+ unit: '分',
+ required: false,
+ defaultValue: '-'
+ }
+ ],
+ pagination: {
+ current: 1,
+ pageSize: 10,
+ total: 10,
+ },
+ selectedRecord: null, // 选中的记录,用于编辑
+ selectedMetadata: null, // 选中的元数据域信息
+ };
+
+ // 更新列配置 - 绩效参数管理
+ this.defaultColumns = [
+ {
+ title: '属性名称',
+ dataIndex: 'displayName',
+ key: 'displayName',
+ width: 120,
+ align: 'left',
+ },
+ {
+ title: '编码',
+ dataIndex: 'fieldName',
+ key: 'fieldName',
+ width: 150,
+ align: 'left',
+ render: (text) => (
+
+ {text}
+
+ ),
+ },
+ {
+ title: '数据类型',
+ dataIndex: 'dataType',
+ key: 'dataType',
+ width: 120,
+ align: 'center',
+ render: (type) => {
+ const typeConfig = {
+ '文本': { color: '#722ed1', bgColor: '#f9f0ff', borderColor: '#d3adf7' },
+ '数字': { color: '#52c41a', bgColor: '#f6ffed', borderColor: '#b7eb8f' },
+ '列表': { color: '#1890ff', bgColor: '#e6f7ff', borderColor: '#91d5ff' },
+ '日期': { color: '#722ed1', bgColor: '#f9f0ff', borderColor: '#d3adf7' },
+ '布尔': { color: '#eb2f96', bgColor: '#fff0f6', borderColor: '#ffadd2' }
+ };
+ const config = typeConfig[type] || typeConfig['文本'];
+
+ return (
+
+ {type}
+
+ );
+ }
+ },
+ {
+ title: '单位',
+ dataIndex: 'unit',
+ key: 'unit',
+ width: 80,
+ align: 'center',
+ render: (unit) => unit || '-'
+ },
+ {
+ title: '必填',
+ dataIndex: 'required',
+ key: 'required',
+ width: 80,
+ align: 'center',
+ render: (required) => (
+
+ {required ? '是' : '否'}
+
+ )
+ },
+ {
+ title: '操作',
+ key: 'action',
+ width: 120,
+ align: 'center',
+ render: (_, record) => (
+
+ }
+ onClick={() => this.handleEdit(record)}
+ >
+ {/* 编辑 */}
+
+ }
+ onClick={() => this.handleDelete(record)}
+ >
+ {/* 删除 */}
+
+
+ ),
+ },
+ ];
+ }
+
+ // 获取处理后的树形数据
+ getTreeData = () => {
+ const { organizationData, filteredTreeData, searchValue } = this.state;
+
+ // 如果有搜索条件,使用过滤后的数据,否则使用原始数据
+ const dataSource = searchValue ? filteredTreeData : organizationData;
+
+ const processNode = (node) => ({
+ key: node.key,
+ title: (
+
+ {this.getNodeIcon(node.title)}
+ {node.title}
+ {node.isLeaf ? null : ({node.children ? node.children.length : 0})}
+
+ ),
+ children: node.children ? node.children.map(processNode) : undefined
+ });
+
+ return dataSource.map(processNode);
+ };
+
+ // 获取节点图标
+ getNodeIcon = (title) => {
+ // 主分类图标 - 使用文件夹风格
+ if (title.includes('基础信息')) return ;
+ if (title.includes('技术职务')) return ;
+ if (title.includes('绩效参数')) return ;
+ if (title.includes('联系方式')) return ;
+ if (title.includes('其他信息')) return ;
+
+ // 绩效参数属性图标
+ if (title.includes('代码量')) return ;
+ if (title.includes('文档字数')) return ;
+ if (title.includes('出勤时长')) return ;
+ if (title.includes('项目金额')) return ;
+ if (title.includes('培训时长')) return ;
+ if (title.includes('会议次数')) return ;
+ if (title.includes('会议时长')) return ;
+ if (title.includes('bug')) return ;
+ if (title.includes('响应时间')) return ;
+ if (title.includes('满意度')) return ;
+
+ // 基础信息属性图标
+ if (title.includes('员工编号') || title.includes('编号')) return ;
+ if (title.includes('姓名') || title.includes('名称')) return ;
+ if (title.includes('性别')) return ;
+
+ // 默认图标
+ return ;
+ };
+
+ // 搜索处理
+ handleSearch = (values) => {
+ console.log('搜索参数:', values);
+ this.setState({ searchForm: values });
+ };
+
+ // 重置搜索
+ handleReset = () => {
+ this.formRef?.resetFields();
+ this.setState({ searchForm: {} });
+ };
+
+ // 树节点选择
+ onTreeSelect = (selectedKeys, info) => {
+ console.log('选中节点:', selectedKeys, info);
+ this.setState({ selectedKeys });
+
+ // 如果选中的是父节点(元数据域),显示元数据域信息
+ if (selectedKeys.length > 0 && info.selectedNodes.length > 0) {
+ const selectedNode = info.selectedNodes[0];
+ const nodeKey = selectedKeys[0];
+
+ // 查找对应的元数据域信息
+ const metadataInfo = this.findMetadataByKey(nodeKey);
+
+ if (metadataInfo && !metadataInfo.isLeaf) {
+ // 只有父节点才显示元数据域信息
+ this.setState({
+ selectedMetadata: {
+ name: metadataInfo.title,
+ code: metadataInfo.code,
+ description: metadataInfo.description,
+ key: metadataInfo.key
+ }
+ });
+ } else {
+ // 选中子节点时清空元数据域信息
+ this.setState({ selectedMetadata: null });
+ }
+ } else {
+ this.setState({ selectedMetadata: null });
+ }
+ };
+
+ // 树节点展开
+ onTreeExpand = (expandedKeys) => {
+ this.setState({ expandedKeys });
+ };
+
+ // 刷新树数据
+ handleTreeRefresh = () => {
+ // console.log('刷新组织架构');
+ // 这里可以添加刷新树数据的逻辑
+ };
+
+ // 展开/收缩所有节点
+ handleTreeToggle = () => {
+ const { expandedKeys, organizationData } = this.state;
+ if (expandedKeys.length > 0) {
+ // 收缩所有节点
+ this.setState({ expandedKeys: [] });
+ } else {
+ // 展开所有节点
+ const getAllKeys = (nodes) => {
+ let keys = [];
+ nodes.forEach(node => {
+ keys.push(node.key);
+ if (node.children) {
+ keys = keys.concat(getAllKeys(node.children));
+ }
+ });
+ return keys;
+ };
+ this.setState({ expandedKeys: getAllKeys(organizationData) });
+ }
+ };
+
+ // 搜索树节点
+ onTreeSearch = (value) => {
+ const { organizationData } = this.state;
+ this.setState({ searchValue: value });
+
+ if (!value) {
+ // 搜索为空时,显示所有数据并恢复默认展开状态
+ this.setState({
+ filteredTreeData: [],
+ expandedKeys: ['basic_info', 'admin_position']
+ });
+ return;
+ }
+
+ // 过滤树数据
+ const filterTree = (data) => {
+ return data.map(item => {
+ const match = item.title.toLowerCase().includes(value.toLowerCase());
+ let children = [];
+
+ if (item.children) {
+ children = filterTree(item.children).filter(child => child);
+ }
+
+ if (match || children.length > 0) {
+ return {
+ ...item,
+ children: children.length > 0 ? children : undefined
+ };
+ }
+ return null;
+ }).filter(item => item);
+ };
+
+ const filtered = filterTree(organizationData);
+
+ // 搜索时自动展开所有匹配的节点
+ const getAllKeys = (data) => {
+ let keys = [];
+ data.forEach(item => {
+ keys.push(item.key);
+ if (item.children) {
+ keys = keys.concat(getAllKeys(item.children));
+ }
+ });
+ return keys;
+ };
+
+ this.setState({
+ filteredTreeData: filtered,
+ expandedKeys: getAllKeys(filtered)
+ });
+ };
+
+ // 根据key查找元数据域信息
+ findMetadataByKey = (key) => {
+ const { organizationData } = this.state;
+
+ const findInData = (data) => {
+ for (let item of data) {
+ if (item.key === key) {
+ return item;
+ }
+ if (item.children) {
+ const found = findInData(item.children);
+ if (found) return found;
+ }
+ }
+ return null;
+ };
+
+ return findInData(organizationData);
+ };
+
+ // 渲染元数据域信息区域
+ renderMetadataInfo = () => {
+ const { selectedMetadata } = this.state;
+
+ if (!selectedMetadata) {
+ return null;
+ }
+
+ return (
+
+ );
+ };
+
+ renderForm() {
+ // 数据字典页面暂不需要搜索表单
+ return null;
+ }
+
+ // 分页处理
+ onPaginationChange = (page, pageSize) => {
+ this.setState({
+ pagination: {
+ ...this.state.pagination,
+ current: page,
+ pageSize,
+ }
+ });
+ };
+
+ // 显示新增弹窗
+ showAddModal = () => {
+ this.setState({ addModalVisible: true });
+ };
+
+ // 关闭新增/编辑弹窗
+ hideAddModal = () => {
+ this.setState({
+ addModalVisible: false,
+ selectedRecord: null // 清空选中记录
+ });
+ };
+
+ // 新增成功回调
+ handleAddSuccess = (values) => {
+ console.log('新增成功:', values);
+
+ // 这里可以刷新列表数据
+ // 模拟添加到表格数据中
+ const newStaff = {
+ key: String(Date.now()),
+ id: this.state.tableData.length + 1,
+ name: values.name,
+ phone: values.age, // 年龄
+ idCard: values.department, // 部门
+ department: values.position, // 岗位
+ position: values.workType, // 工作性质
+ status: values.phone, // 电话
+ entryDate: new Date().toISOString().split('T')[0]
+ };
+
+ this.setState({
+ tableData: [...this.state.tableData, newStaff],
+ pagination: {
+ ...this.state.pagination,
+ total: this.state.pagination.total + 1
+ }
+ });
+ };
+
+ // 处理姓名点击事件
+ handleNameClick = (record) => {
+ console.log('查看员工绩效详情:', record);
+ // 可以跳转到绩效详情页面或显示详情模态框
+ Modal.info({
+ title: `${record.name} - 绩效详情`,
+ width: 600,
+ content: (
+
+
员工姓名:{record.name}
+
性别:{record.gender}
+
年龄:{record.age}岁
+
部门:{record.department}
+
职位:{record.position}
+
绩效总分:= 90 ? '#52c41a' :
+ record.totalScore >= 80 ? '#1890ff' :
+ record.totalScore >= 70 ? '#faad14' : '#ff4d4f'
+ }}>{record.totalScore}
+
绩效状态:{record.performanceStatus}
+
+ ),
+ okText: '确定'
+ });
+ };
+
+ // 处理编辑
+ handleEdit = (record) => {
+ console.log('编辑员工绩效:', record);
+ this.setState({
+ selectedRecord: record,
+ showPerformanceAdd: true
+ });
+ };
+
+ // 处理删除
+ handleDelete = (record) => {
+ Modal.confirm({
+ title: '删除确认',
+ content: `确定要删除员工 "${record.name}" 的绩效记录吗?`,
+ okText: '确定',
+ cancelText: '取消',
+ onOk: () => {
+ // 实际项目中这里应该调用删除接口
+ console.log('删除绩效记录:', record.id);
+
+ const newData = this.state.tableData.filter(item => item.id !== record.id);
+ this.setState({
+ tableData: newData,
+ pagination: {
+ ...this.state.pagination,
+ total: newData.length
+ }
+ });
+ message.success('删除成功');
+ }
+ });
+ };
+
+ // 新增元数据域
+ handleAddMetadataDomain = () => {
+ console.log('新增元数据域');
+ // 这里可以打开新增元数据域的弹窗
+ message.info('新增元数据域功能开发中...');
+ };
+
+ // 导出配置
+ handleExportConfig = () => {
+ console.log('导出配置');
+ // 这里可以调用导出配置的接口
+ message.info('导出配置功能开发中...');
+ };
+
render() {
+ const { tableData, pagination, expandedKeys, addModalVisible, addLoading } = this.state;
return (
- <>
-
- >
- )
+
+ {/* 页面标题区域 */}
+
+
+ }
+ onClick={this.handleAddMetadataDomain}
+ style={{
+ backgroundColor: '#2D5CF6',
+ borderColor: '#2D5CF6',
+ borderRadius: '4px'
+ }}
+ >
+ 新增元数据域
+
+ }
+ onClick={this.handleExportConfig}
+ style={{
+ borderColor: '#d9d9d9',
+ borderRadius: '4px'
+ }}
+ >
+ 导出配置
+
+
+
+
+ {/* 主体内容 */}
+
+
+
+ {/* 左侧元数据域树 */}
+
+
+
+
+ }
+ size="small"
+ style={{ color: '#1890ff' }}
+ onClick={this.handleTreeRefresh}
+ title="刷新"
+ />
+ }
+ size="small"
+ style={{ color: '#1890ff' }}
+ onClick={this.handleTreeToggle}
+ title={expandedKeys.length > 0 ? "收缩全部" : "展开全部"}
+ />
+
+
+ }
+ className={styles.treeCard}
+ >
+ {/* 搜索框 */}
+
+ }
+ value={this.state.searchValue}
+ onChange={(e) => this.onTreeSearch(e.target.value)}
+ allowClear
+ size="middle"
+ />
+
+
+ {this.state.searchValue && this.getTreeData().length === 0 ? (
+
+
+ 未找到匹配的元数据域
+
+ 尝试使用其他关键词搜索
+
+
+ ) : (
+
+ )}
+
+
+
+
+ {/* 右侧属性信息区 */}
+
+ {/* 属性表格 */}
+
+ 绩效参数属性配置
+ }
+ onClick={this.showAddModal}
+ >
+ 新增属性
+
+
+ }
+ >
+ {/* 元数据域信息区域 */}
+ {this.renderMetadataInfo()}
+
+
+
+ {/* 分页 */}
+
+
+ `显示 ${range[0]} 到 ${range[1]} 条,共 ${total} 条记录`
+ }
+ onChange={this.onPaginationChange}
+ onShowSizeChange={this.onPaginationChange}
+ />
+
+
+
+
+
+
+
+ {/* 新增/编辑绩效弹窗 */}
+
+
+ );
}
}
-export default PerformanceRuleset
+export default PerformanceRuleset;
\ No newline at end of file
diff --git a/src/pages/performancemanage_performanceruleset/PerformanceRuleset.less b/src/pages/performancemanage_performanceruleset/PerformanceRuleset.less
index d5bff80..c39fffc 100644
--- a/src/pages/performancemanage_performanceruleset/PerformanceRuleset.less
+++ b/src/pages/performancemanage_performanceruleset/PerformanceRuleset.less
@@ -1,10 +1,830 @@
@import '~@/utils/utils.less';
-.frameContent {
- width: 100%;
- height: 100vh;
- border: none;
- display: block;
- margin: 0;
- padding: 0;
+.dataDictContainer,
+.staffInfoContainer {
+ min-height: 90vh;
+ height: 90vh;
+ // background-color: #f5f6fa;
+
+ .announcementBar {
+ background: #e6f7ff;
+ border: 1px solid #91d5ff;
+ margin-bottom: 16px;
+ border-radius: 6px;
+ overflow: hidden;
+
+ .announcement {
+ display: flex;
+ align-items: center;
+
+ .announcementLabel {
+ background-color: #fef3c7;
+ color: #92400e;
+ border-radius: 4px;
+ padding: 4px 8px;
+ font-size: 12px;
+ font-weight: 500;
+ margin-right: 12px;
+ white-space: nowrap;
+ display: flex;
+ align-items: center;
+
+ .anticon {
+ margin-right: 4px;
+ }
+ }
+
+ .scrollContainer {
+ flex: 1;
+ overflow: hidden;
+ white-space: nowrap;
+ }
+
+ .scrollContent {
+ display: inline-block;
+ animation: scroll 30s linear infinite;
+ color: #666;
+ font-size: 14px;
+ }
+ }
+ }
+
+ .mainContent {
+ // padding: 12px;
+
+ .contentCard {
+ .ant-card-head {
+ .ant-card-head-title {
+ font-size: 18px;
+ font-weight: 600;
+ color: #333;
+ }
+ }
+ }
+
+ .treeCard {
+ height: 600px;
+ border: 1px solid #e8e8e8;
+ border-radius: 8px;
+
+ /* 搜索框样式 */
+ .tree-search {
+ margin-bottom: 16px;
+
+ .ant-input-affix-wrapper {
+ border-radius: 8px;
+ border: 1px solid #d9d9d9;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.02);
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+
+ &:hover {
+ border-color: #40a9ff;
+ box-shadow: 0 2px 8px rgba(24, 144, 255, 0.1);
+ }
+
+ &:focus-within {
+ border-color: #1890ff;
+ box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
+ }
+
+ .ant-input {
+ border: none;
+ box-shadow: none;
+ font-size: 13px;
+
+ &::placeholder {
+ color: #bfbfbf;
+ font-style: italic;
+ }
+ }
+
+ .ant-input-prefix {
+ color: #bfbfbf;
+ margin-right: 8px;
+ }
+ }
+ }
+
+ .treeHeader {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ font-size: 14px;
+ font-weight: 500;
+ }
+
+ .treeContainer {
+ height: 480px; /* 减少高度为搜索框留空间 */
+ overflow-y: auto;
+
+ /* 自定义滚动条样式 */
+ &::-webkit-scrollbar {
+ width: 6px;
+ }
+
+ &::-webkit-scrollbar-track {
+ background: transparent;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background: #d9d9d9;
+ border-radius: 3px;
+
+ &:hover {
+ background: #bfbfbf;
+ }
+ }
+
+ .orgTree {
+ .ant-tree-treenode {
+ padding: 2px 0;
+
+ .ant-tree-node-content-wrapper {
+ border-radius: 6px;
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ padding: 6px 10px;
+ margin: 1px 0;
+
+ &:hover {
+ background: linear-gradient(135deg, #f0f9ff 0%, #e6f7ff 100%);
+ transform: translateX(3px);
+ box-shadow: 0 2px 8px rgba(24, 144, 255, 0.15);
+ }
+
+ &.ant-tree-node-selected {
+ background: linear-gradient(135deg, #e6f7ff 0%, #bae7ff 100%) !important;
+ box-shadow: 0 3px 12px rgba(24, 144, 255, 0.25);
+ border-left: 3px solid #1890ff;
+ }
+ }
+
+ .ant-tree-iconEle {
+ margin-right: 10px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 20px;
+ height: 20px;
+ }
+
+ .ant-tree-title {
+ font-size: 14px;
+ font-weight: 500;
+ }
+
+ /* 展开/收起图标样式 */
+ .ant-tree-switcher {
+ width: 20px;
+ height: 20px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ .ant-tree-switcher-icon {
+ color: #8c8c8c;
+ font-size: 12px;
+ transition: all 0.3s ease;
+
+ &:hover {
+ color: #1890ff;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* Tree节点标题样式 */
+ .tree-node-title {
+ display: flex;
+ align-items: center;
+ width: 100%;
+ transition: all 0.3s ease;
+
+ .anticon {
+ font-size: 16px;
+ margin-right: 8px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 24px;
+ height: 24px;
+ border-radius: 6px;
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ background: rgba(24, 144, 255, 0.06);
+
+ &:hover {
+ background: rgba(24, 144, 255, 0.12);
+ transform: scale(1.08);
+ box-shadow: 0 2px 8px rgba(24, 144, 255, 0.15);
+ }
+ }
+
+ .node-title {
+ flex: 1;
+ font-size: 14px;
+ color: #333;
+ font-weight: 500;
+ transition: color 0.3s ease;
+ }
+
+ .node-count {
+ color: #999;
+ font-size: 11px;
+ margin-left: auto;
+ background: #f5f5f5;
+ padding: 2px 8px;
+ border-radius: 10px;
+ min-width: 20px;
+ text-align: center;
+ font-weight: 500;
+ transition: all 0.3s ease;
+
+ &:hover {
+ background: #e6f7ff;
+ color: #1890ff;
+ }
+ }
+ }
+
+ .searchCard {
+ margin-bottom: 16px;
+ border-radius: 8px;
+ border: 1px solid #e8e8e8;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+
+ .ant-card-body {
+ padding: 16px;
+ }
+
+ /* 搜索表单容器样式 */
+ .searchFormContainer {
+ .searchForm {
+ .ant-form-item {
+ margin-bottom: 16px;
+
+ .ant-form-item-label {
+ font-weight: 500;
+ color: #333;
+
+ label {
+ color: #333 !important;
+ font-size: 14px;
+ }
+ }
+
+ .ant-input,
+ .ant-select-selector,
+ .ant-picker {
+ border-radius: 6px;
+ border: 1px solid #d9d9d9;
+ transition: all 0.3s ease;
+
+ &:hover {
+ border-color: #4c7bff;
+ }
+
+ &:focus,
+ &.ant-select-focused .ant-select-selector,
+ &.ant-picker-focused {
+ border-color: #2d5cf6;
+ box-shadow: 0 0 0 2px rgba(45, 92, 246, 0.2);
+ }
+ }
+
+ .ant-select-selection-placeholder,
+ .ant-input::placeholder,
+ .ant-picker-input input::placeholder {
+ color: #bfbfbf;
+ }
+ }
+ }
+ }
+
+ /* 搜索按钮样式 */
+ .searchButton {
+ background: linear-gradient(135deg, #2d5cf6 0%, #4c7bff 100%);
+ border: none;
+ border-radius: 6px;
+ color: white;
+ font-weight: 500;
+ font-size: 14px;
+ box-shadow: 0 2px 8px rgba(45, 92, 246, 0.3);
+ transition: all 0.3s ease;
+ height: 32px;
+ padding: 0 16px;
+
+ &:hover,
+ &:focus {
+ background: linear-gradient(135deg, #4c7bff 0%, #6b8fff 100%);
+ transform: translateY(-1px);
+ box-shadow: 0 4px 12px rgba(45, 92, 246, 0.4);
+ color: white;
+ }
+
+ &:active {
+ transform: translateY(0);
+ }
+ }
+
+ /* 重置按钮样式 */
+ .resetButton {
+ background: #fff;
+ border: 1px solid #d9d9d9;
+ color: #666;
+ border-radius: 6px;
+ font-weight: 500;
+ font-size: 14px;
+ transition: all 0.3s ease;
+ height: 32px;
+ padding: 0 16px;
+
+ &:hover,
+ &:focus {
+ border-color: #4c7bff;
+ color: #2d5cf6;
+ }
+
+ .anticon {
+ color: #ff7875;
+ }
+ }
+
+ /* 展开按钮样式 */
+ .expandButton {
+ color: #2d5cf6;
+ font-size: 14px;
+ padding: 0 8px;
+ height: 32px;
+
+ &:hover,
+ &:focus {
+ color: #4c7bff;
+ }
+ }
+ }
+
+ .actionBar {
+
+
+
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 16px;
+
+ .totalInfo {
+ color: #666;
+ font-size: 14px;
+ font-weight: 500;
+ }
+
+ .exportButton {
+ background: linear-gradient(135deg, #52c41a 0%, #73d13d 100%);
+ border: none;
+ color: white;
+ border-radius: 8px;
+ font-weight: 500;
+ font-size: 14px;
+ box-shadow: 0 4px 12px rgba(82, 196, 26, 0.3);
+ transition: all 0.3s ease;
+ // margin-top: -8px;
+ height: 35px;
+ padding: 0 16px;
+
+
+ &:hover,
+ &:focus {
+ background: linear-gradient(135deg, #73d13d 0%, #95de64 100%);
+ transform: translateY(-2px);
+ box-shadow: 0 6px 20px rgba(82, 196, 26, 0.4);
+ color: white;
+ }
+
+ &:active {
+ transform: translateY(0);
+ }
+
+ .anticon {
+ color: white;
+ }
+ }
+
+
+ .addButton {
+ background: linear-gradient(135deg, #fa8c16 0%, #ffa940 100%);
+ border: none;
+ border-radius: 8px;
+ font-weight: 600;
+ font-size: 14px;
+ box-shadow: 0 4px 12px rgba(250, 140, 22, 0.3);
+ transition: all 0.3s ease;
+ // margin-top: -8px;
+ height: 35px;
+ padding: 0 16px;
+
+
+ &:hover,
+ &:focus {
+ background: linear-gradient(135deg, #ffa940 0%, #ffc069 100%);
+ transform: translateY(-2px);
+ box-shadow: 0 6px 20px rgba(250, 140, 22, 0.4);
+ }
+
+ &:active {
+ transform: translateY(0);
+ }
+ }
+ }
+
+ .tableCard {
+ border-radius: 8px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+ padding-bottom: 10px;
+
+ .ant-table-wrapper {
+ max-height: 600px;
+ overflow-y: auto;
+
+ /* 自定义滚动条样式 */
+ &::-webkit-scrollbar {
+ width: 8px;
+ }
+
+ &::-webkit-scrollbar-track {
+ background: #f5f5f5;
+ border-radius: 4px;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background: #d9d9d9;
+ border-radius: 4px;
+
+ &:hover {
+ background: #bfbfbf;
+ }
+ }
+
+ .ant-table-thead>tr>th {
+ background-color: #fafafa;
+ font-weight: 600;
+ color: #333;
+ border-bottom: 1px solid #e8e8e8;
+ position: sticky;
+ top: 0;
+ z-index: 1;
+ }
+
+ .ant-table-tbody>tr {
+ &:hover>td {
+ background-color: #f5f5f5 !important;
+ }
+
+ >td {
+ border-bottom: 1px solid #f0f0f0;
+ }
+ }
+ }
+
+ .paginationWrapper {
+ margin-top: 20px;
+ text-align: right;
+
+ .ant-pagination {
+ .ant-pagination-total-text {
+ color: #666;
+ }
+
+ .ant-pagination-item {
+ border-radius: 4px;
+
+ &.ant-pagination-item-active {
+ background-color: #2d5cf6;
+ border-color: #2d5cf6;
+ }
+ }
+
+ .ant-pagination-prev,
+ .ant-pagination-next {
+ border-radius: 4px;
+ }
+ }
+ }
+ }
+ }
+}
+
+.mainContent {
+ // padding: 12px;
+
+ .contentCard {
+ border: none !important;
+ .ant-card-head {
+ .ant-card-head-title {
+ font-size: 18px;
+ font-weight: 600;
+ color: #333;
+ }
+ }
+ }
+
+ .actionBar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 16px;
+
+ .totalInfo {
+ color: #666;
+ font-size: 14px;
+ }
+ }
+
+ :global {
+ .ant-card-body {
+ padding: 0 24px;
+ }
+ }
+}
+
+/* 元数据域信息区域样式 */
+.metadataInfoSection {
+ background-color: #f9fafb;
+ border-radius: 8px;
+ padding: 16px;
+ margin: 12px 0;
+ border: 1px solid #e5e7eb;
+
+ .metadataField {
+ margin-bottom: 16px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ .metadataLabel {
+ display: block;
+ font-size: 14px;
+ font-weight: 500;
+ color: #374151;
+ margin-bottom: 4px;
+ }
+
+ .metadataInput,
+ .metadataTextarea {
+ border-radius: 4px;
+ border: 1px solid #d1d5db;
+ background-color: #ffffff;
+
+ &:focus {
+ border-color: #2d5cf6;
+ box-shadow: 0 0 0 1px #2d5cf6;
+ }
+
+ &[readonly] {
+ background-color: #f9fafb;
+ cursor: default;
+ }
+ }
+
+ .metadataInput {
+ font-size: 14px;
+ padding: 8px 12px;
+ }
+
+ .metadataTextarea {
+ font-size: 14px;
+ padding: 8px 12px;
+ resize: vertical;
+ min-height: 60px;
+ }
+}
+
+/* 表格卡片样式优化 */
+.tableCard {
+ .ant-card-body {
+ padding: 24px;
+ }
+
+ .ant-card-head {
+ border-bottom: 1px solid #f0f0f0;
+ }
+
+ .ant-card-head-title {
+ font-size: 18px;
+ font-weight: 600;
+ color: #262626;
+ }
+}
+
+/* 树形卡片样式 */
+.treeCard {
+ height: 100%;
+
+ .ant-card-body {
+ padding: 16px;
+ height: calc(100% - 57px);
+ overflow: hidden;
+ }
+
+ .ant-card-head {
+ border-bottom: 1px solid #f0f0f0;
+ }
+
+ .ant-card-head-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #262626;
+ }
+}
+
+/* 树容器样式 */
+.treeContainer {
+ height: calc(100% - 50px);
+ overflow-y: auto;
+ padding-top: 8px;
+
+ /* 自定义滚动条 */
+ &::-webkit-scrollbar {
+ width: 6px;
+ }
+
+ &::-webkit-scrollbar-track {
+ background: #f1f5f9;
+ border-radius: 3px;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background: #cbd5e1;
+ border-radius: 3px;
+
+ &:hover {
+ background: #94a3b8;
+ }
+ }
+}
+
+/* 树搜索样式 */
+.tree-search {
+ margin-bottom: 12px;
+
+ .ant-input {
+ border-radius: 4px;
+ border: 1px solid #d1d5db;
+
+ &:focus {
+ border-color: #2d5cf6;
+ box-shadow: 0 0 0 1px #2d5cf6;
+ }
+ }
+
+ .ant-input-prefix {
+ color: #9ca3af;
+ }
+}
+
+/* 树节点样式 */
+.orgTree {
+ .ant-tree-node-content-wrapper {
+ border-radius: 4px;
+ transition: all 0.2s;
+
+ &:hover {
+ background-color: #f3f4f6;
+ }
+
+ &.ant-tree-node-selected {
+ background-color: #dbeafe !important;
+ color: #2d5cf6;
+ }
+ }
+
+ .ant-tree-switcher {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ .ant-tree-iconEle {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+}
+
+.tree-node-title {
+ display: flex;
+ align-items: center;
+
+ .node-title {
+ margin-left: 8px;
+ font-size: 14px;
+ color: #374151;
+ }
+
+ .node-count {
+ margin-left: 4px;
+ font-size: 12px;
+ color: #9ca3af;
+ }
+}
+
+/* 响应式样式 */
+@media (max-width: 768px) {
+ .metadataInfoSection {
+ padding: 12px;
+ margin-bottom: 16px;
+
+ .metadataField {
+ margin-bottom: 12px;
+ }
+
+ .metadataLabel {
+ font-size: 13px;
+ }
+
+ .metadataInput,
+ .metadataTextarea {
+ font-size: 13px;
+ padding: 6px 10px;
+ }
+ }
+
+ .tableCard .ant-card-body {
+ padding: 16px;
+ }
+
+ .treeCard .ant-card-body {
+ padding: 12px;
+ }
+}
+
+@keyframes scroll {
+ 0% {
+ transform: translateX(0);
+ }
+
+ 100% {
+ transform: translateX(-50%);
+ }
+}
+
+// 响应式设计
+@media (max-width: 1200px) {
+ .staffInfoContainer {
+ .mainContent {
+ .searchCard {
+ .ant-row {
+ .ant-col {
+ margin-bottom: 16px;
+ }
+ }
+ }
+ }
+ }
+}
+
+// 自定义主题色
+.ant-btn-primary {
+ background-color: #2d5cf6;
+ border-color: #2d5cf6;
+
+ &:hover,
+ &:focus {
+ background-color: #4c7bff;
+ border-color: #4c7bff;
+ }
+}
+
+.ant-tree .ant-tree-node-selected {
+ background-color: #e6f7ff !important;
+}
+
+.ant-select-focused .ant-select-selector,
+.ant-input-affix-wrapper-focused,
+.ant-input:focus,
+.ant-input-focused {
+ border-color: #2d5cf6 !important;
+ box-shadow: 0 0 0 2px rgba(45, 92, 246, 0.2) !important;
+}
+
+// 标签样式优化
+.ant-tag {
+ border-radius: 4px;
+ font-size: 12px;
+}
+
+// 按钮组间距调整
+.ant-space-item {
+ .ant-btn+.ant-btn {
+ margin-left: 8px;
+ }
+}
+
+// 表格链接按钮样式
+.ant-btn-link {
+ padding: 0 4px;
+ font-size: 12px;
}
\ No newline at end of file
diff --git a/src/pages/performancemanage_performanceruleset/form/PerformanceRenderSimpleForm.js b/src/pages/performancemanage_performanceruleset/form/PerformanceRenderSimpleForm.js
new file mode 100644
index 0000000..f0a1644
--- /dev/null
+++ b/src/pages/performancemanage_performanceruleset/form/PerformanceRenderSimpleForm.js
@@ -0,0 +1,222 @@
+import React, { useState } from 'react';
+import { Button, Col, Form, Input, Row, message, Select, Space, InputNumber } from 'antd';
+import { ClearOutlined, SearchOutlined, ExpandOutlined, CompressOutlined, UserOutlined, PhoneOutlined, IdcardOutlined, TeamOutlined } from '@ant-design/icons';
+import styles from "../PerformanceList.less";
+
+const FormItem = Form.Item;
+const { Option } = Select;
+const PerformanceRenderSimpleForm = (props) => {
+ const [form] = Form.useForm();
+ const [expandForm, setExpandForm] = useState(false);
+ const { submitButtons, handleSearch, handleFormReset, toggleForm, params } = props;
+
+ React.useEffect(() => {
+ form.setFieldsValue({
+ name: params?.name,
+ phone: params?.phone,
+ idCard: params?.idCard,
+ department: params?.department,
+ gender: params?.gender,
+ ageMin: params?.ageMin,
+ ageMax: params?.ageMax,
+ performanceStatus: params?.performanceStatus,
+ });
+ }, [params]);
+
+ const onFinish = values => {
+ const searchParams = {
+ ...values,
+ // 年龄范围验证
+ ageMin: values.ageMin,
+ ageMax: values.ageMax,
+ };
+
+ // 验证年龄范围
+ if (values.ageMin && values.ageMax && values.ageMin > values.ageMax) {
+ message.error("最小年龄不能大于最大年龄!");
+ return;
+ }
+
+ handleSearch && handleSearch(searchParams);
+ };
+
+ const myhandleFormReset = () => {
+ form.resetFields();
+ handleFormReset && handleFormReset();
+ };
+
+ const toggleExpandForm = () => {
+ setExpandForm(!expandForm);
+ };
+
+ return (
+
+
+
+ );
+
+};
+
+export default PerformanceRenderSimpleForm;
diff --git a/src/pages/performancemanage_performanceruleset/form/PerformanceRenderSimpleForm.less b/src/pages/performancemanage_performanceruleset/form/PerformanceRenderSimpleForm.less
new file mode 100644
index 0000000..e69de29
diff --git a/src/pages/performancemanage_performanceruleset/form/PerformanceRulesetAdd.js b/src/pages/performancemanage_performanceruleset/form/PerformanceRulesetAdd.js
new file mode 100644
index 0000000..3ab4d23
--- /dev/null
+++ b/src/pages/performancemanage_performanceruleset/form/PerformanceRulesetAdd.js
@@ -0,0 +1,197 @@
+import React, { PureComponent } from 'react';
+import {
+ Modal,
+ Form,
+ Input,
+ Select,
+ InputNumber,
+ Row,
+ Col,
+ message
+} from 'antd';
+import {
+ UserOutlined,
+ PhoneOutlined,
+ TeamOutlined,
+ ApartmentOutlined
+} from '@ant-design/icons';
+
+const { Option } = Select;
+
+class PerformanceRuleset extends PureComponent {
+ constructor(props) {
+ super(props);
+ this.formRef = React.createRef();
+ }
+
+ // 提交表单
+ handleSubmit = (values) => {
+ console.log('新增人员信息:', values);
+
+ // 这里可以调用API接口保存数据
+ // 模拟保存成功
+ message.success('新增人员成功!');
+
+ // 重置表单
+ this.formRef.current?.resetFields();
+
+ // 调用父组件的回调函数
+ if (this.props.onSuccess) {
+ this.props.onSuccess(values);
+ }
+
+ // 关闭弹窗
+ this.handleCancel();
+ };
+
+ // 取消操作
+ handleCancel = () => {
+ // 重置表单
+ this.formRef.current?.resetFields();
+
+ // 调用父组件的关闭回调
+ if (this.props.onCancel) {
+ this.props.onCancel();
+ }
+ };
+
+ render() {
+ const { visible, loading = false } = this.props;
+
+ return (
+ this.formRef.current?.submit()}
+ onCancel={this.handleCancel}
+ width={600}
+ confirmLoading={loading}
+ destroyOnClose={true}
+ maskClosable={false}
+ >
+
+
+ );
+ }
+}
+
+export default PerformanceRuleset;