diff --git a/config/routes.js b/config/routes.js index a1007da..f894a1c 100644 --- a/config/routes.js +++ b/config/routes.js @@ -31,6 +31,12 @@ export default [ name: 'staffstatistics', component: './multi-d-statistics/MultiDStatistics', }, + { + path: '/topnavbar00/multidstatistics/performance', + // icon: 'bank', + name: 'performance', + component: './performance/Performance', + }, ], }, // 人员管理 @@ -45,6 +51,42 @@ export default [ name: 'staffinfo', component: './staffmanage_staffinfo/StaffInfo', }, + { + path: '/topnavbar00/staffmanage/onboarding', + // icon: 'bank', + name: 'onboarding', + component: './staffmanage_onboarding/OnBoarding', + }, + { + path: '/topnavbar00/staffmanage/onboardingregister', + // icon: 'bank', + name: 'onboardingregister', + component: './staffmanage_onboardingregister/OnBoardingRegister', + }, + { + path: '/topnavbar00/staffmanage/onboardingapproval', + // icon: 'bank', + name: 'onboardingapproval', + component: './staffmanage_onboardingapproval/OnBoardingApproval', + }, + { + path: '/topnavbar00/staffmanage/resignation', + // icon: 'bank', + name: 'resignation', + component: './staffmanage_resignation/Resignation', + }, + { + path: '/topnavbar00/staffmanage/training', + // icon: 'bank', + name: 'training', + component: './staffmanage_training/Training', + }, + { + path: '/topnavbar00/staffmanage/trainingplan', + // icon: 'bank', + name: 'trainingplan', + component: './staffmanage_trainingplan/TrainingPlan', + }, { path: '/topnavbar00/staffmanage/staffresume', // icon: 'bank', @@ -63,7 +105,7 @@ export default [ name: 'staffresume', component: './staffmanage_staffresume/StaffResume', }, - { + { path: '/topnavbar00/staffmanage/particulars', // icon: 'bank', name: 'particulars', @@ -83,6 +125,12 @@ export default [ name: 'organchart', component: './organmanage_organchart/OrganChart', }, + { + path: '/topnavbar00/organmanage/reportrelation', + // icon: 'bank', + name: 'reportrelation', + component: './organmanage_reportrelation/ReportRelation', + }, { path: '/topnavbar00/organmanage/deptmaintain', // icon: 'bank', @@ -101,7 +149,13 @@ export default [ path: '/topnavbar00/attendancemanage/attendancedata', // icon: 'bank', name: 'attendancedata', - component: './attendancemanage_attendancedata/attendancemanageAttendancedata', + component: './attendancemanage_attendancedata/AttendancemanageAttendancedata', + }, + { + path: '/topnavbar00/attendancemanage/attendancedetails', + // icon: 'bank', + name: 'attendancedetails', + component: './attendancemanage_attendancedetails/Attendancedetails', }, ], }, @@ -149,6 +203,12 @@ export default [ name: 'salaryruleset', component: './salarymanage_salaryruleset/SalaryRuleset', }, + { + path: '/topnavbar00/salarymanage/salarydetail', + // icon: 'bank', + name: 'salarydetail', + component: './salarymanage_salarydetail/SalaryDetail', + }, ], }, //效率管理 diff --git a/src/global.less b/src/global.less index 3a71f32..6143476 100644 --- a/src/global.less +++ b/src/global.less @@ -31,7 +31,7 @@ } .ant-btn-primary { - background: rgba(36, 114, 214, 1); + // background: rgba(36, 114, 214, 1); } // top导航样式开始 diff --git a/src/pages/salarymanage_salarydetail/girl.png b/src/pages/salarymanage_salarydetail/girl.png new file mode 100644 index 0000000..44ff8f5 Binary files /dev/null and b/src/pages/salarymanage_salarydetail/girl.png differ diff --git a/src/pages/staffmanage_onboarding/OnBoarding.js b/src/pages/staffmanage_onboarding/OnBoarding.js new file mode 100644 index 0000000..48fd601 --- /dev/null +++ b/src/pages/staffmanage_onboarding/OnBoarding.js @@ -0,0 +1,838 @@ +import React, { PureComponent } from 'react'; +import { + Card, + Tree, + Input, + Button, + DatePicker, + Select, + Row, + Col, + Space, + Radio, + Checkbox, + InputNumber, + Avatar, + message, + Typography +} from 'antd'; +import { + SaveOutlined, + CloseOutlined, + PlusCircleOutlined, + DeleteOutlined, + ExpandOutlined, + UserOutlined, + TeamOutlined, + ApartmentOutlined, + SyncOutlined, + DollarOutlined, + SettingOutlined, + CalendarOutlined, + UsergroupAddOutlined, + UserSwitchOutlined, + StopOutlined, + CheckCircleOutlined, + CloseCircleOutlined, + ContactsOutlined, +} from '@ant-design/icons'; +import dayjs from 'dayjs'; +import styles from './OnBoarding.less'; + +const { Option } = Select; +const { TextArea } = Input; +const { Title } = Typography; +class OnBoarding extends PureComponent { + constructor(props) { + super(props); + this.state = { + selectedOrgKeys: ['0-0-4'], // 默认选中人事部 + expandedKeys: ['0-0', '0-0-0', '0-0-1', '0-0-2'], + // 入职计划表单数据 + onboardingForm: { + // 入职部门信息 + departmentName: '人力资源部', + departmentManager: '张明远', + currentStaff: '24/30', + + // 计划时段设置 + planStartDate: dayjs('2023-09-01'), + planEndDate: dayjs('2023-09-30'), + + // 可入职岗位设置 + availablePositions: [ + { id: 1, name: '人力资源专员', count: 3, checked: true }, + { id: 2, name: '薪酬福利专员', count: 2, checked: true }, + { id: 3, name: '培训发展专员', count: 1, checked: false }, + { id: 4, name: '招聘专员', count: 2, checked: false } + ], + + // 计划入职人数 + totalPlan: 5, + confirmedCount: 2, + remainingCount: 3, + + // 人员要求 + ageRange: '22-30岁', + gender: '不限', + education: '本科及以上', + workYears: '1-3年', + otherRequirements: '', + + // 黑名单 + blacklist: [ + { id: 1, name: '林晓梅', idCard: '310***19880512****', avatar: null }, + { id: 2, name: '王建国', idCard: '420***19900215****', avatar: null } + ], + + // 白名单 + whitelist: [ + { id: 1, name: '陈思思', recommender: '张明远', avatar: null } + ] + }, + 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 } + ], + }, + ], + }, + ] + }; + } + + // 获取处理后的树形数据 + 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 ; + }; + + // 刷新树数据 + handleTreeRefresh = () => { + message.info('刷新组织架构数据'); + }; + + // 展开/收缩所有节点 + 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) }); + } + }; + + // 组织树选择 + onTreeSelect = (selectedKeys, info) => { + console.log('选中节点:', selectedKeys, info); + this.setState({ selectedOrgKeys: selectedKeys }); + + if (selectedKeys.length > 0) { + const selectedKey = selectedKeys[0]; + const findNodeByKey = (nodes, key) => { + for (let node of nodes) { + if (node.key === key) { + return node; + } + if (node.children) { + const found = findNodeByKey(node.children, key); + if (found) return found; + } + } + return null; + }; + + const selectedNode = findNodeByKey(this.state.organizationData, selectedKey); + if (selectedNode) { + this.handleOnboardingFormChange('departmentName', selectedNode.title); + const departmentInfo = this.getDepartmentInfo(selectedNode.title); + this.setState(prevState => ({ + onboardingForm: { + ...prevState.onboardingForm, + ...departmentInfo + } + })); + } + } + }; + + // 获取部门信息 + getDepartmentInfo = (departmentName) => { + const departmentMap = { + '技术部': { + departmentManager: '李技术', + currentStaff: '115/120', + availablePositions: [ + { id: 1, name: '前端工程师', count: 2, checked: true }, + { id: 2, name: '后端工程师', count: 3, checked: true }, + { id: 3, name: '测试工程师', count: 1, checked: false } + ] + }, + '产品部': { + departmentManager: '王产品', + currentStaff: '65/68', + availablePositions: [ + { id: 1, name: '产品经理', count: 1, checked: true }, + { id: 2, name: '产品设计师', count: 2, checked: true } + ] + }, + '人事部': { + departmentManager: '张明远', + currentStaff: '24/30', + availablePositions: [ + { id: 1, name: '人力资源专员', count: 3, checked: true }, + { id: 2, name: '薪酬福利专员', count: 2, checked: true }, + { id: 3, name: '培训发展专员', count: 1, checked: false }, + { id: 4, name: '招聘专员', count: 2, checked: false } + ] + }, + '财务部': { + departmentManager: '赵财务', + currentStaff: '30/32', + availablePositions: [ + { id: 1, name: '会计', count: 1, checked: true }, + { id: 2, name: '出纳', count: 1, checked: false } + ] + }, + '运营部': { + departmentManager: '钱运营', + currentStaff: '48/52', + availablePositions: [ + { id: 1, name: '市场专员', count: 2, checked: true }, + { id: 2, name: '客服专员', count: 1, checked: true } + ] + } + }; + + return departmentMap[departmentName] || { + departmentManager: '未知', + currentStaff: '0/0', + availablePositions: [] + }; + }; + + // 树展开/收缩 + onTreeExpand = (expandedKeys) => { + this.setState({ expandedKeys }); + }; + + // 入职表单字段变化 + handleOnboardingFormChange = (field, value) => { + this.setState(prevState => ({ + onboardingForm: { + ...prevState.onboardingForm, + [field]: value + } + })); + }; + + // 岗位选择变化 + handlePositionChange = (id, checked) => { + const { onboardingForm } = this.state; + const newPositions = onboardingForm.availablePositions.map(pos => + pos.id === id ? { ...pos, checked } : pos + ); + this.setState({ + onboardingForm: { + ...onboardingForm, + availablePositions: newPositions + } + }); + }; + + // 添加新岗位 + addNewPosition = () => { + const { onboardingForm } = this.state; + const newPosition = { + id: Date.now(), + name: '新岗位', + count: 1, + checked: false + }; + this.setState({ + onboardingForm: { + ...onboardingForm, + availablePositions: [...onboardingForm.availablePositions, newPosition] + } + }); + message.success('新岗位添加成功'); + }; + + // 移除黑名单人员 + removeFromBlacklist = (id) => { + const { onboardingForm } = this.state; + const newBlacklist = onboardingForm.blacklist.filter(person => person.id !== id); + this.setState({ + onboardingForm: { + ...onboardingForm, + blacklist: newBlacklist + } + }); + message.success('已移除黑名单人员'); + }; + + // 移除白名单人员 + removeFromWhitelist = (id) => { + const { onboardingForm } = this.state; + const newWhitelist = onboardingForm.whitelist.filter(person => person.id !== id); + this.setState({ + onboardingForm: { + ...onboardingForm, + whitelist: newWhitelist + } + }); + message.success('已移除白名单人员'); + }; + + // 添加黑名单人员 + addToBlacklist = () => { + message.info('功能开发中,敬请期待'); + }; + + // 添加白名单人员 + addToWhitelist = () => { + message.info('功能开发中,敬请期待'); + }; + + // 保存设置 + handleSave = () => { + const { onboardingForm } = this.state; + + if (!onboardingForm.departmentName) { + message.error('请选择部门'); + return; + } + + if (!onboardingForm.planStartDate || !onboardingForm.planEndDate) { + message.error('请选择计划时段'); + return; + } + + if (onboardingForm.planStartDate.isAfter(onboardingForm.planEndDate)) { + message.error('开始日期不能晚于结束日期'); + return; + } + + if (onboardingForm.totalPlan <= 0) { + message.error('计划总人数必须大于0'); + return; + } + + console.log('保存入职计划设置:', onboardingForm); + message.success('入职计划设置保存成功'); + }; + + // 取消操作 + handleCancel = () => { + message.info('已取消操作'); + }; + + render() { + const { selectedOrgKeys, expandedKeys, onboardingForm } = this.state; + + return ( +
+
+ + + {/* 左侧组织架构树 - 保持不变 */} + + +
+ + 组织架构 +
+ +
+ } + className={styles.treeCard} + > +
+ +
+ + + + {/* 右侧入职计划设置 - 替换为HTML内容 */} + + + {/* 头部标题 */} +
+ + 入职计划设置 + + + + + +
+ + {/* 表单内容区 */} +
+ {/* 入职部门信息 */} + + + 入职部门信息 + + } + size="small" + className={styles.formCard} + > + + +
+ +
+ {onboardingForm.departmentName} +
+
+ + +
+ +
+ {onboardingForm.departmentManager} +
+
+ + +
+ +
+ {onboardingForm.currentStaff} +
+
+ +
+
+ + {/* 计划时段设置 */} + + + 计划时段设置 + + } + size="small" + className={styles.formCard} + > + + +
+ + this.handleOnboardingFormChange('planStartDate', date)} + placeholder="选择开始日期" + /> +
+ + +
+ + this.handleOnboardingFormChange('planEndDate', date)} + placeholder="选择结束日期" + /> +
+ +
+
+ + {/* 可入职岗位设置 */} + + + 可入职岗位设置 + + } + size="small" + className={styles.formCard} + > +
+ {onboardingForm.availablePositions.map(position => ( +
+ this.handlePositionChange(position.id, e.target.checked)} + > + {position.name} ({position.count}人) + +
+ ))} + +
+
+ + {/* 计划入职人数 */} + + + 计划入职人数 + + } + size="small" + className={styles.formCard} + > + + +
+ + this.handleOnboardingFormChange('totalPlan', value)} + placeholder="请输入计划总人数" + /> +
+ + +
+ + +
+ + +
+ + +
+ +
+
+ + {/* 人员要求 */} + + + 人员要求 + + } + size="small" + className={styles.formCard} + > +
+
+ + this.handleOnboardingFormChange('ageRange', e.target.value)} + > + 22-30岁 + 30-35岁 + 不限 + +
+ +
+ + this.handleOnboardingFormChange('gender', e.target.value)} + > + + + 不限 + +
+ + + +
+ + +
+ + +
+ + +
+ +
+ +
+ +