From 87325fc3ad5520dd353aebf6d3c4c19e104f5fdf Mon Sep 17 00:00:00 2001 From: jiangxucong Date: Fri, 12 Sep 2025 14:00:46 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=88=E7=8E=87=E7=AE=A1=E7=90=86=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app.tsx | 2 +- .../hrefficiency_workreport/WorkReport.js | 684 ++++++++++++++++- .../hrefficiency_workreport/WorkReport.less | 525 ++++++++++++- .../form/WorkReportAdd.js | 321 ++++++++ .../form/WorkReportRenderSimpleForm.js | 309 ++++++++ .../form/WorkReportRenderSimpleForm.less | 0 .../nav_system_content/SystemContentList.js | 36 +- src/pages/performance/Performance.js | 717 ++++++++++++++++++ src/pages/performance/Performance.less | 429 +++++++++++ .../salarymanage_salarydata/SalaryData.js | 605 ++++++++++++++- .../salarymanage_salarydata/SalaryData.less | 525 ++++++++++++- .../form/SalaryDataAdd.js | 197 +++++ .../form/SalaryDataRenderSimpleForm.js | 104 +++ .../form/SalaryDataRenderSimpleForm.less | 0 .../salarymanage_salarydetail/SalaryDetail.js | 395 ++++++++++ .../SalaryDetail.less | 489 ++++++++++++ .../SalaryRuleset.js | 638 +++++++++++++++- .../SalaryRuleset.less | 549 +++++++++++++- src/pages/topnavbar/TopNavBar.js | 81 +- 19 files changed, 6543 insertions(+), 63 deletions(-) create mode 100644 src/pages/hrefficiency_workreport/form/WorkReportAdd.js create mode 100644 src/pages/hrefficiency_workreport/form/WorkReportRenderSimpleForm.js create mode 100644 src/pages/hrefficiency_workreport/form/WorkReportRenderSimpleForm.less create mode 100644 src/pages/performance/Performance.js create mode 100644 src/pages/performance/Performance.less create mode 100644 src/pages/salarymanage_salarydata/form/SalaryDataAdd.js create mode 100644 src/pages/salarymanage_salarydata/form/SalaryDataRenderSimpleForm.js create mode 100644 src/pages/salarymanage_salarydata/form/SalaryDataRenderSimpleForm.less create mode 100644 src/pages/salarymanage_salarydetail/SalaryDetail.js create mode 100644 src/pages/salarymanage_salarydetail/SalaryDetail.less diff --git a/src/app.tsx b/src/app.tsx index d952148..8ed90ad 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -128,7 +128,7 @@ export async function getInitialState (type) { // history.replace({ // pathname: loginPath // }) - /topnavbar00/hrefficiency + // /topnavbar00/hrefficiency } } diff --git a/src/pages/hrefficiency_workreport/WorkReport.js b/src/pages/hrefficiency_workreport/WorkReport.js index 80dabfd..9a37d87 100644 --- a/src/pages/hrefficiency_workreport/WorkReport.js +++ b/src/pages/hrefficiency_workreport/WorkReport.js @@ -1,14 +1,686 @@ -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 +} from '@ant-design/icons'; import styles from './WorkReport.less'; +import StandardTable from '@/components/StandardTable'; +import WorkReportAdd from './form/WorkReportAdd'; +import WorkReportRenderSimpleForm from "./form/WorkReportRenderSimpleForm" //表单 + +const { Option } = Select; + class WorkReport 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', + id: 1, + workType: '招聘面试', + workPerson: '张三', + department: '人事部', + startTime: '2025-09-03 09:00', + endTime: '2025-09-03 17:30', + duration: '8.5小时', + workQuantity: 3 + }, + { + key: '2', + id: 2, + workType: '培训组织', + workPerson: '李四', + department: '人事部', + startTime: '2025-09-03 08:30', + endTime: '2025-09-03 18:00', + duration: '9.5小时', + workQuantity: 2 + }, + { + key: '3', + id: 3, + workType: '绩效考核', + workPerson: '王五', + department: '人事部', + startTime: '2025-09-03 09:15', + endTime: '2025-09-03 17:45', + duration: '8.5小时', + workQuantity: 5 + }, + { + key: '4', + id: 4, + workType: '薪酬核算', + workPerson: '赵六', + department: '人事部', + startTime: '2025-09-03 08:45', + endTime: '2025-09-03 17:15', + duration: '8.5小时', + workQuantity: 4 + }, + { + key: '5', + id: 5, + workType: '招聘面试', + workPerson: '陈七', + department: '人事部', + startTime: '2025-09-03 09:30', + endTime: '2025-09-03 16:30', + duration: '7小时', + workQuantity: 1 + }, + ], + pagination: { + current: 1, + pageSize: 5, + total: 356, + }, + selectedRecord: null, // 选中的记录,用于编辑 + }; + + // 默认列配置 + this.defaultColumns = [ + { + title: '序号', + dataIndex: 'id', + key: 'id', + width: 80, + align: 'center', + render: (text, record, index) => ( + + {index + 1} + + ), + }, + { + title: '作业类型', + dataIndex: 'workType', + key: 'workType', + width: 120, + align: 'center', + render: (text) => ( + + {text} + + ), + }, + { + title: '作业人员', + dataIndex: 'workPerson', + key: 'workPerson', + width: 100, + align: 'center', + render: (text, record) => ( + + ), + }, + { + title: '部门', + dataIndex: 'department', + key: 'department', + width: 120, + align: 'center', + }, + { + title: '开始时间', + dataIndex: 'startTime', + key: 'startTime', + width: 150, + align: 'center', + render: (time) => ( + + {time} + + ), + }, + { + title: '结束时间', + dataIndex: 'endTime', + key: 'endTime', + width: 150, + align: 'center', + render: (time) => ( + + {time} + + ), + }, + { + title: '持续时长', + dataIndex: 'duration', + key: 'duration', + width: 100, + align: 'center', + render: (duration) => ( + + {duration} + + ), + sorter: (a, b) => { + const aHours = parseFloat(a.duration); + const bHours = parseFloat(b.duration); + return aHours - bHours; + }, + }, + { + title: '作业数量', + dataIndex: 'workQuantity', + key: 'workQuantity', + width: 100, + align: 'center', + render: (quantity) => ( + = 4 ? '#52c41a' : + quantity >= 2 ? '#1890ff' : '#faad14' + }}> + {quantity} + + ), + sorter: (a, b) => a.workQuantity - b.workQuantity, + }, + { + title: '操作', + key: 'action', + width: 120, + align: 'center', + render: (_, 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 + } + }); + }; + + // 处理作业人员点击事件 + handlePersonClick = (record) => { + Modal.info({ + title: `${record.workPerson} - 作业详情`, + width: 600, + content: ( +
+ + 作业人员:{record.workPerson} + 所属部门:{record.department} + 作业类型:{record.workType} + 作业数量:{record.workQuantity} + +

时间统计

+ + 开始时间:{record.startTime} + 结束时间:{record.endTime} + 持续时长:{record.duration} + 工作效率: + {(record.workQuantity / parseFloat(record.duration)).toFixed(2)} 件/小时 + +
+
+ ), + okText: '确定' + }); + }; + + // 处理编辑 + handleEdit = (record) => { + console.log('编辑工作报告:', record); + this.setState({ + selectedRecord: record, + addModalVisible: true + }); + }; + + // 处理删除 + handleDelete = (record) => { + Modal.confirm({ + title: '删除确认', + content: `确定要删除 "${record.workPerson}" 的工作报告记录吗?`, + 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 ( - <> -