人员管理

master
wangyunfei 2 weeks ago
parent 4e6d0120b1
commit 2bbfdf3891

@ -63,6 +63,12 @@ export default [
name: 'staffresume', name: 'staffresume',
component: './staffmanage_staffresume/StaffResume', component: './staffmanage_staffresume/StaffResume',
}, },
{
path: '/topnavbar00/staffmanage/particulars',
// icon: 'bank',
name: 'particulars',
component: './staffmanage_particulars/Particulars',
},
], ],
}, },
// 组织管理 // 组织管理

@ -0,0 +1,241 @@
import React, { PureComponent } from 'react';
import { Card, Avatar, Breadcrumb, Tag, Descriptions, Table, Row, Col, Button, Divider } from 'antd';
import { UserOutlined, HomeOutlined, TeamOutlined, MailOutlined, PhoneOutlined, IdcardOutlined, ApartmentOutlined, HistoryOutlined, BookOutlined, ArrowLeftOutlined, EditOutlined, PrinterOutlined } from '@ant-design/icons';
import { history } from 'umi';
import styles from './Particulars.less';
import girlAvatar from './girl.png';
const careerTableData = [
{
key: '1',
company: '上海科技有限公司',
position: '高级产品经理',
duration: '2018-06-15 至今 · 5年4个月',
description: '主导公司核心产品线的规划与设计带领5人产品团队成功推出3款市场领先产品用户增长300%',
status: 'current',
},
{
key: '2',
company: '北京云创科技',
position: '产品经理',
duration: '2015-07-01 至 2018-05-30 · 2年11个月',
description: '负责企业级SaaS产品的设计与迭代成功将产品NPS从35提升至72客户续费率提升至85%',
status: '',
},
{
key: '3',
company: '深圳创新科技',
position: '产品助理',
duration: '2013-09-01 至 2015-06-30 · 1年10个月',
description: '协助产品经理完成需求分析、原型设计参与3个移动端项目从0到1的全过程',
status: '',
},
];
const educationTableData = [
{
key: '1',
school: '复旦大学',
degree: '硕士',
major: '计算机科学与技术',
duration: '2011-09 ~ 2013-07',
},
{
key: '2',
school: '华东理工大学',
degree: '本科',
major: '软件工程',
duration: '2007-09 ~ 2011-07',
},
];
class Particulars extends PureComponent {
handleGoBack = () => {
// 跳转到人员管理页面
history.push('/topnavbar00/staffmanage');
};
render() {
return (
<div className={styles.particularsContainer}>
{/* 面包屑导航 */}
<Breadcrumb
className={styles.breadcrumb}
items={[
{
title: '人员管理',
},
{
title: '人员详情',
}
]}
/>
{/* 返回按钮 */}
<Button type="link" icon={<ArrowLeftOutlined />} onClick={this.handleGoBack} className={styles.backBtn}>
返回
</Button>
{/* 个人信息卡片 */}
<Card className={styles.profileCard}>
<Row gutter={24} align="middle">
<Col xs={24} sm={4} className={styles.avatarCol}>
<Avatar size={80} src={girlAvatar} />
</Col>
<Col xs={24} sm={14}>
<div className={styles.profileInfoHeader}>
<div className={styles.nameSection}>
<span className={styles.profileName}>林晓梅</span>
<Tag color="blue">高级产品经理</Tag>
<span className={styles.profileDept}>产品研发中心</span>
</div>
<div className={styles.profileDetails}>
<Row gutter={[24, 8]}>
<Col span={12}>
<div className={styles.detailItem}>
<span className={styles.detailLabel}>员工编号</span>
<span className={styles.detailValue}>EMP20230085</span>
</div>
</Col>
<Col span={12}>
<div className={styles.detailItem}>
<span className={styles.detailLabel}>入职日期</span>
<span className={styles.detailValue}>2018-06-15</span>
</div>
</Col>
<Col span={12}>
<div className={styles.detailItem}>
<span className={styles.detailLabel}>工作年限</span>
<span className={styles.detailValue}>5年4个月</span>
</div>
</Col>
<Col span={12}>
<div className={styles.detailItem}>
<span className={styles.detailLabel}>员工状态</span>
<Tag color="green" className={styles.statusTag}>在职</Tag>
</div>
</Col>
</Row>
</div>
</div>
</Col>
<Col xs={24} sm={6} className={styles.actionCol}>
<div className={styles.actionButtons}>
<Button type="primary" icon={<EditOutlined />} className={styles.editBtn}>
编辑
</Button>
<Button icon={<PrinterOutlined />} className={styles.printBtn}>
打印
</Button>
</div>
</Col>
</Row>
</Card>
{/* 个人信息区 */}
<Card className={styles.infoCard} title={<><UserOutlined /> 个人信息</>}>
<Descriptions column={2}>
<Descriptions.Item label="身份证号">310******19900823****</Descriptions.Item>
<Descriptions.Item label="婚姻状况">已婚</Descriptions.Item>
<Descriptions.Item label="联系电话">138****5678</Descriptions.Item>
<Descriptions.Item label="电子邮箱">linxiaomei@company.com</Descriptions.Item>
<Descriptions.Item label="现居住地" span={2}>上海市浦东新区张江高科技园区科苑路88号</Descriptions.Item>
</Descriptions>
</Card>
{/* 工作信息区 */}
<Card className={styles.infoCard} title={<><TeamOutlined /> 工作信息</>}>
<Descriptions column={2}>
<Descriptions.Item label="所属部门">产品研发中心 - 产品设计部</Descriptions.Item>
<Descriptions.Item label="直接上级">张伟产品研发中心总监</Descriptions.Item>
<Descriptions.Item label="工作职责" span={2}>负责公司核心产品线的规划与设计主导产品全生命周期管理协调跨部门资源推动产品落地</Descriptions.Item>
</Descriptions>
</Card>
{/* 职业履历表格 */}
<Card className={styles.infoCard} title={<><HistoryOutlined /> 职业履历</>}>
<div className={styles.tableWrapper}>
<Table
columns={[
{ title: '公司', dataIndex: 'company', key: 'company', width: '25%' },
{ title: '职位', dataIndex: 'position', key: 'position', width: '20%' },
{ title: '时间', dataIndex: 'duration', key: 'duration', width: '25%' },
{ title: '描述', dataIndex: 'description', key: 'description', width: '30%' },
]}
dataSource={careerTableData}
pagination={false}
size="small"
className={styles.customTable}
/>
</div>
</Card>
{/* 职业履历时间轴(自定义实现) */}
{/* <Card className={styles.infoCard} title={<><HistoryOutlined /> 职业履历时间轴</>}>
<div className={styles.careerTimeline}>
{careerTableData.map((item, idx) => (
<div key={item.key} className={styles.timelineItem}>
<div className={styles.timelineDot + (item.status === 'current' ? ' ' + styles.timelineDotActive : '')}></div>
<div className={styles.timelineContent}>
<div className={styles.timelineHeader}>
<span className={styles.timelineCompany}>{item.company}</span>
{item.status === 'current' && <Tag color="blue">当前公司</Tag>}
</div>
<div className={styles.timelinePosition}>{item.position}</div>
<div className={styles.timelineDuration}>{item.duration}</div>
<div className={styles.timelineDescription}>{item.description}</div>
</div>
</div>
))}
</div>
</Card> */}
{/* 教育经历表格 */}
<Card className={styles.infoCard} title={<><BookOutlined /> 教育经历</>}>
<div className={styles.tableWrapper}>
<Table
columns={[
{ title: '学校', dataIndex: 'school', key: 'school', width: '30%' },
{ title: '学历', dataIndex: 'degree', key: 'degree', width: '20%' },
{ title: '专业', dataIndex: 'major', key: 'major', width: '30%' },
{ title: '时间', dataIndex: 'duration', key: 'duration', width: '20%' },
]}
dataSource={educationTableData}
pagination={false}
size="small"
className={styles.customTable}
/>
</div>
</Card>
{/* 组织架构图 */}
{/* <Card className={styles.infoCard} title={<><ApartmentOutlined /> 组织架构</>}>
<div className={styles.orgChartWrapper}>
<img src="https://ai-public.mastergo.com/gen_page/map_placeholder_1280x720.png" alt="组织架构图" className={styles.orgChartImg} />
</div>
</Card> */}
{/* 页脚 */}
<Divider />
<div className={styles.footer}>
<div className={styles.footerLinks}>
<a href="#">公司简介</a>
<a href="#">发展历程</a>
<a href="#">企业文化</a>
<a href="#">管理团队</a>
<a href="#">加入我们</a>
<a href="#">隐私政策</a>
<a href="#">服务条款</a>
<a href="#">法律声明</a>
<a href="#">沪ICP备12345678号-1</a>
</div>
<div className={styles.footerCopyright}>© 2023 人力资源管理系统 版权所有</div>
</div>
</div>
);
}
}
export default Particulars;

@ -0,0 +1,334 @@
.particularsContainer {
background: #f5f6fa;
min-width: 70vw;
min-height: 100vh;
max-height: 100vh;
overflow-y: auto;
overflow-x: hidden;
padding: 16px 24px 32px 24px;
}
.announcementBar {
background: #fff;
box-shadow: 0 2px 8px #f0f1f2;
padding: 8px 24px;
font-size: 14px;
color: #666;
display: flex;
align-items: center;
gap: 24px;
}
.announcementTitle {
color: #2d5cf6;
font-weight: 500;
margin-right: 8px;
}
.announcementItem {
margin-right: 16px;
}
.breadcrumb {
margin: 24px 0 8px 0;
font-size: 13px;
}
.backBtn {
margin-bottom: 12px;
}
.profileCard {
margin-bottom: 24px;
border-radius: 12px;
box-shadow: 0 2px 8px #f0f1f2;
}
.avatarCol {
display: flex;
align-items: center;
justify-content: center;
}
.profileInfoHeader {
padding: 8px 0;
}
.nameSection {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 16px;
}
.profileName {
font-size: 24px;
font-weight: bold;
color: #222;
}
.profileDept {
color: #888;
font-size: 15px;
margin-left: 4px;
}
.profileDetails {
margin-top: 8px;
}
.detailItem {
display: flex;
flex-direction: column;
gap: 4px;
}
.detailLabel {
font-size: 13px;
color: #888;
font-weight: 500;
}
.detailValue {
font-size: 15px;
color: #333;
font-weight: 600;
}
.statusTag {
margin: 0;
font-weight: 500;
}
.actionCol {
display: flex;
align-items: center;
justify-content: center;
}
.actionButtons {
display: flex;
flex-direction: column;
gap: 12px;
width: 100%;
max-width: 120px;
}
.editBtn {
width: 100%;
height: 40px;
border-radius: 8px;
font-weight: 500;
}
.printBtn {
width: 100%;
height: 40px;
border-radius: 8px;
font-weight: 500;
}
@media (max-width: 768px) {
.actionButtons {
flex-direction: row;
max-width: none;
}
.nameSection {
flex-wrap: wrap;
gap: 8px;
}
}
.infoCard {
margin-bottom: 24px;
border-radius: 12px;
box-shadow: 0 2px 8px #f0f1f2;
// 表格包装器样式
.tableWrapper {
margin-top: 16px;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
// 自定义滚动条样式
&::-webkit-scrollbar {
width: 6px;
height: 6px;
}
&::-webkit-scrollbar-track {
background: #f5f5f5;
border-radius: 3px;
}
&::-webkit-scrollbar-thumb {
background: #d9d9d9;
border-radius: 3px;
&:hover {
background: #bfbfbf;
}
}
}
// 自定义表格样式
.customTable {
.ant-table-wrapper {
.ant-table-thead > tr > th {
background-color: #2c3e50 !important;
color: #ecf0f1 !important;
font-weight: 600;
border-bottom: 1px solid #34495e;
position: sticky;
top: 0;
z-index: 1;
text-align: center;
font-size: 14px;
padding: 16px 12px;
letter-spacing: 0.5px;
}
.ant-table-tbody > tr {
&:hover > td {
background-color: #f8f9ff !important;
}
&:nth-child(even) {
background-color: #fafbfc;
}
> td {
border-bottom: 1px solid #e8e8e8;
padding: 14px 12px;
font-size: 13px;
color: #333;
vertical-align: top;
line-height: 1.6;
}
}
.ant-table {
border-radius: 8px;
overflow: hidden;
border: 1px solid #e8e8e8;
}
.ant-table-container {
border-radius: 8px;
}
}
}
// 表格通用样式(为了向后兼容)
.ant-table-wrapper {
.ant-table-thead > tr > th {
background-color: #2c3e50 !important;
color: #ecf0f1 !important;
font-weight: 600;
border-bottom: 1px solid #34495e;
position: sticky;
top: 0;
z-index: 1;
text-align: center;
font-size: 13px;
}
.ant-table-tbody > tr {
&:hover > td {
background-color: #f8f9ff !important;
}
> td {
border-bottom: 1px solid #e8e8e8;
padding: 12px 8px;
font-size: 13px;
color: #333;
vertical-align: top;
}
}
.ant-table {
border-radius: 8px;
overflow: hidden;
}
}
}
.careerTimeline {
margin-top: 16px;
padding-left: 12px;
border-left: 2px solid #2d5cf6;
}
.timelineItem {
position: relative;
margin-bottom: 32px;
padding-left: 24px;
}
.timelineDot {
position: absolute;
left: -13px;
top: 8px;
width: 12px;
height: 12px;
background: #d9d9d9;
border-radius: 50%;
border: 2px solid #fff;
box-shadow: 0 0 0 2px #2d5cf6;
}
.timelineDotActive {
background: #2d5cf6;
box-shadow: 0 0 0 2px #2d5cf6;
}
.timelineContent {
margin-left: 8px;
}
.timelineHeader {
display: flex;
align-items: center;
gap: 8px;
font-weight: 500;
font-size: 16px;
}
.timelineCompany {
color: #222;
}
.timelinePosition {
color: #555;
font-size: 15px;
margin-top: 2px;
}
.timelineDuration {
color: #888;
font-size: 13px;
margin-top: 2px;
}
.timelineDescription {
color: #444;
font-size: 14px;
margin-top: 4px;
}
.orgChartWrapper {
display: flex;
align-items: center;
justify-content: center;
background: #f5f6fa;
border-radius: 8px;
padding: 16px;
min-height: 180px;
}
.orgChartImg {
max-width: 100%;
max-height: 220px;
object-fit: contain;
}
.footer {
margin-top: 32px;
text-align: center;
color: #888;
font-size: 13px;
}
.footerLinks {
margin-bottom: 8px;
display: flex;
flex-wrap: wrap;
gap: 16px;
justify-content: center;
}
.footerLinks a {
color: #888;
text-decoration: none;
transition: color 0.2s;
}
.footerLinks a:hover {
color: #2d5cf6;
}
.footerCopyright {
margin-top: 4px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

@ -1,13 +1,658 @@
import React, {Fragment, PureComponent} from 'react'; import React, { PureComponent } from 'react';
import {
Card,
Tree,
Input,
Button,
Table,
Select,
Space,
Pagination,
Row,
Col,
Form,
} from 'antd';
import { history } from 'umi';
import {
SearchOutlined,
ExpandOutlined,
DownloadOutlined,
UserOutlined,
TeamOutlined,
ApartmentOutlined,
SyncOutlined,
DollarOutlined,
SettingOutlined,
ClearOutlined,
UserAddOutlined,
EditOutlined,
DeleteOutlined
} from '@ant-design/icons';
import styles from './StaffInfo.less'; import styles from './StaffInfo.less';
import StaffInfoAdd from './from/StaffInfoadd';
const { Option } = Select;
class StaffInfo extends PureComponent { class StaffInfo 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,
name: '张三',
phone: 28, // 年龄
idCard: '技术部', // 部门
department: '高级工程师', // 岗位
position: '全职', // 工作性质
status: '138****1234', // 电话
entryDate: '2020-03-15'
},
{
key: '2',
id: 2,
name: '李四',
phone: 30, // 年龄
idCard: '产品部', // 部门
department: '产品经理', // 岗位
position: '全职', // 工作性质
status: '139****5678', // 电话
entryDate: '2019-08-20'
},
{
key: '3',
id: 3,
name: '王五',
phone: 25, // 年龄
idCard: '运营部', // 部门
department: '运营专员', // 岗位
position: '全职', // 工作性质
status: '136****9999', // 电话
entryDate: '2021-05-10'
},
{
key: '4',
id: 4,
name: '赵六',
phone: 32, // 年龄
idCard: '财务部', // 部门
department: '会计', // 岗位
position: '全职', // 工作性质
status: '137****8888', // 电话
entryDate: '2018-12-01'
},
{
key: '5',
id: 5,
name: '陈七',
phone: 26, // 年龄
idCard: '人事部', // 部门
department: 'HR专员', // 岗位
position: '全职', // 工作性质
status: '135****7777', // 电话
entryDate: '2022-01-15'
},
],
pagination: {
current: 1,
pageSize: 5,
total: 356,
}
};
}
// 获取处理后的树形数据
getTreeData = () => {
const { organizationData } = this.state;
const processNode = (node) => ({
key: node.key,
title: (
<span className={styles['tree-node-title']}>
{this.getNodeIcon(node.title)}
<span className={styles['node-title']}>{node.title}</span>
<span className={styles['node-count']}>({node.count})</span>
</span>
),
children: node.children ? node.children.map(processNode) : undefined
});
return organizationData.map(processNode);
};
// 获取节点图标
getNodeIcon = (title) => {
if (title.includes('公司') || title.includes('集团')) return <ApartmentOutlined style={{ color: '#1890ff' }} />;
if (title.includes('技术') || title.includes('开发') || title.includes('测试')) return <SettingOutlined style={{ color: '#52c41a' }} />;
if (title.includes('产品') || title.includes('设计') || title.includes('体验')) return <TeamOutlined style={{ color: '#fa8c16' }} />;
if (title.includes('运营') || title.includes('市场') || title.includes('客户') || title.includes('商务')) return <TeamOutlined style={{ color: '#eb2f96' }} />;
if (title.includes('财务') || title.includes('会计') || title.includes('审计')) return <DollarOutlined style={{ color: '#722ed1' }} />;
if (title.includes('人事') || title.includes('HR') || title.includes('招聘') || title.includes('培训') || title.includes('薪酬')) return <UserOutlined style={{ color: '#13c2c2' }} />;
return <TeamOutlined style={{ color: '#666' }} />;
};
// 组织架构树数据 (保留原始数据以备后用)
treeData = [
{
title: '飞利信科技有限公司',
key: '0-0',
icon: <ApartmentOutlined />,
children: [
{
title: '技术部',
key: '0-0-0',
icon: <TeamOutlined />,
children: [
{
title: '前端组',
key: '0-0-0-0',
icon: <UserOutlined />
},
{
title: '后端组',
key: '0-0-0-1',
icon: <UserOutlined />
},
],
},
{
title: '产品部',
key: '0-0-1',
icon: <TeamOutlined />,
children: [
{
title: '产品设计组',
key: '0-0-1-0',
icon: <UserOutlined />
},
],
},
{
title: '运营部',
key: '0-0-2',
icon: <TeamOutlined />,
},
{
title: '财务部',
key: '0-0-3',
icon: <TeamOutlined />,
},
{
title: '人事部',
key: '0-0-4',
icon: <TeamOutlined />,
},
],
},
];
// 表格列配置
columns = [
{
title: '序号',
dataIndex: 'id',
key: 'id',
width: 60,
align: 'center',
},
{
title: '姓名',
dataIndex: 'name',
key: 'name',
width: 60,
render: (text, record) => (
<Button
type="link"
style={{ padding: 0, fontWeight: 500 }}
onClick={() => this.handleNameClick(record)}
>
{text}
</Button>
),
},
{
title: '年龄',
dataIndex: 'phone',
key: 'phone',
width: 50,
},
{
title: '部门',
dataIndex: 'idCard',
key: 'idCard',
width: 70,
},
{
title: '岗位',
dataIndex: 'department',
key: 'department',
width: 80,
},
{
title: '工作性质',
dataIndex: 'position',
key: 'position',
width: 50,
},
{
title: '电话',
dataIndex: 'status',
key: 'status',
width: 100,
},
{
title: '操作',
key: 'action',
width: 80,
render: (_, record) => (
<Space size="middle">
<Button
type="link"
size="small"
icon={<EditOutlined />}
title="编辑"
/>
<Button
type="link"
size="small"
danger
icon={<DeleteOutlined />}
title="删除"
/>
</Space>
),
},
];
// 搜索处理
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) });
}
};
// 分页处理
onPaginationChange = (page, pageSize) => {
this.setState({
pagination: {
...this.state.pagination,
current: page,
pageSize,
}
});
};
// 显示新增弹窗
showAddModal = () => {
this.setState({ addModalVisible: true });
};
// 关闭新增弹窗
hideAddModal = () => {
this.setState({ addModalVisible: false });
};
// 新增成功回调
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);
// 跳转到人员详情页面传递员工ID参数
history.push(`/topnavbar00/staffmanage/particulars`);
};
render() { render() {
const { tableData, pagination, expandedKeys, addModalVisible, addLoading } = this.state;
return ( return (
<> <div className={styles.staffInfoContainer}>
<iframe title="人员列表" className={styles.frameContent} src="/人员列表.html"/> {/* 主体内容 */}
</> <div className={styles.mainContent}>
) <Card className={styles.contentCard}>
<Row gutter={24}>
{/* 左侧组织架构树 */}
<Col span={5}>
<Card
title={
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', width: '100%' }}>
<div style={{ display: 'flex', alignItems: 'center' }}>
<TeamOutlined style={{ marginRight: 8, color: '#1890ff' }} />
<span>组织架构</span>
</div>
<Space>
<Button
type="text"
icon={<SyncOutlined />}
size="small"
style={{ color: '#1890ff' }}
onClick={this.handleTreeRefresh}
title="刷新"
/>
<Button
type="text"
icon={<ExpandOutlined />}
size="small"
style={{ color: '#1890ff' }}
onClick={this.handleTreeToggle}
title={expandedKeys.length > 0 ? "收缩全部" : "展开全部"}
/>
</Space>
</div>
}
className={styles.treeCard}
>
<div className={styles.treeContainer}>
<Tree
showIcon
expandedKeys={expandedKeys}
onSelect={this.onTreeSelect}
onExpand={this.onTreeExpand}
treeData={this.getTreeData()}
className={styles.orgTree}
/>
</div>
</Card>
</Col>
{/* 右侧人员信息区 */}
<Col span={19}>
{/* 筛选条件 */}
<Card className={styles.searchCard}>
<Form
ref={(ref) => this.formRef = ref}
onFinish={this.handleSearch}
layout="vertical"
>
<Row gutter={12}>
<Col span={8}>
<Form.Item
name="name"
label="姓名"
>
<Input
placeholder="请输入姓名"
// prefix={<UserOutlined />}
/>
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name="phone"
label="电话"
>
<Input
placeholder="请输入电话"
// prefix={<PhoneOutlined />}
/>
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name="idCard"
label="身份证号"
>
<Input
placeholder="请输入身份证号"
// prefix={<IdcardOutlined />}
/>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={8}>
<Form.Item
name="department"
label="部门"
>
<Select placeholder="请选择部门">
<Option value="技术部">技术部</Option>
<Option value="产品部">产品部</Option>
<Option value="运营部">运营部</Option>
<Option value="财务部">财务部</Option>
<Option value="人事部">人事部</Option>
</Select>
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name="position"
label="岗位"
>
<Select placeholder="请选择岗位">
<Option value="高级工程师">高级工程师</Option>
<Option value="产品经理">产品经理</Option>
<Option value="运营专员">运营专员</Option>
<Option value="会计">会计</Option>
<Option value="HR专员">HR专员</Option>
</Select>
</Form.Item>
</Col>
<Col span={8}>
<Form.Item label=" " colon={false}>
<Space size="middle">
<Button
type="primary"
htmlType="submit"
icon={<SearchOutlined />}
size="large"
className={styles.searchButton}
>
查询
</Button>
<Button
onClick={this.handleReset}
icon={<ClearOutlined />}
size="large"
className={styles.resetButton}
>
重置
</Button>
</Space>
</Form.Item>
</Col>
</Row>
</Form>
</Card>
{/* 操作按钮和统计 */}
<div className={styles.actionBar}>
<div className={styles.totalInfo}>
{/* 共 {pagination.total} 条记录 */}
</div>
<Space size="middle">
<Button
icon={<DownloadOutlined />}
size="large"
className={styles.exportButton}
>
导出
</Button>
<Button
type="primary"
icon={<UserAddOutlined />}
size="large"
className={styles.addButton}
onClick={this.showAddModal}
>
新增
</Button>
</Space>
</div>
{/* 人员表格 */}
<Card className={styles.tableCard}>
<Table
columns={this.columns}
dataSource={tableData}
pagination={false}
// scroll={{ x: 1200 }}
size="small"
/>
{/* 分页 */}
<div className={styles.paginationWrapper}>
<Pagination
current={pagination.current}
total={pagination.total}
pageSize={pagination.pageSize}
showSizeChanger
showQuickJumper
showTotal={(total, range) =>
`显示 ${range[0]}${range[1]} 条,共 ${total} 条记录`
}
onChange={this.onPaginationChange}
onShowSizeChange={this.onPaginationChange}
/>
</div>
</Card>
</Col>
</Row>
</Card>
</div>
{/* 新增人员弹窗 */}
<StaffInfoAdd
visible={addModalVisible}
loading={addLoading}
onCancel={this.hideAddModal}
onSuccess={this.handleAddSuccess}
/>
</div>
);
} }
} }

@ -1,10 +1,714 @@
@import '~@/utils/utils.less'; @import '~@/utils/utils.less';
.frameContent { .staffInfoContainer {
min-height: 100vh;
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: 24px;
.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%; width: 100%;
height: 100vh;
.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;
background-color: #f9fbfc;
border-radius: 8px;
.ant-card-body {
padding: 12px;
background-color: #f9fbfc;
border-radius: 6px;
}
.ant-form-item-label {
font-weight: 500;
label {
color: #ecf0f1 !important;
}
}
// 深色背景下的表单项样式
.ant-input,
.ant-select-selector {
background-color: #34495e !important;
border-color: #5a6c7d !important;
color: #ecf0f1 !important;
&:hover {
border-color: #7fb3d3 !important;
}
&:focus {
border-color: #2d5cf6 !important;
box-shadow: 0 0 0 2px rgba(45, 92, 246, 0.2) !important;
}
}
.ant-select-selection-placeholder,
.ant-input::placeholder {
color: #95a5a6 !important;
}
.anticon {
color: #95a5a6 !important;
} /* 搜索按钮样式 */
.searchButton {
background: linear-gradient(135deg, #2d5cf6 0%, #4c7bff 100%);
border: none; border: none;
display: block; border-radius: 8px;
margin: 0;
padding: 0; font-weight: 600;
font-size: 14px;
box-shadow: 0 4px 12px rgba(45, 92, 246, 0.3);
transition: all 0.3s ease;
margin-top: -8px;
height: 35px;
padding: 0 16px;
&:hover,
&:focus {
background: linear-gradient(135deg, #4c7bff 0%, #6b8fff 100%);
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(45, 92, 246, 0.4);
}
&:active {
transform: translateY(0);
}
}
/* 重置按钮样式 */
.resetButton {
background: linear-gradient(135deg, #f5f5f5 0%, #e8e8e8 100%);
border: 1px solid #d9d9d9;
color: #666;
border-radius: 8px;
font-weight: 500;
font-size: 14px;
transition: all 0.3s ease;
margin-top: -8px;
height: 35px;
padding: 0 16px;
&:hover,
&:focus {
background: linear-gradient(135deg, #e8e8e8 0%, #dcdcdc 100%);
border-color: #bfbfbf;
color: #333;
transform: translateY(-1px);
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.1);
}
.anticon {
color: #ff7875;
}
}
}
.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);
.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 {
.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;
background-color: #f9fbfc;
border-radius: 8px;
.ant-card-body {
padding: 10px;
background-color: #f9fbfc;
border-radius: 6px;
}
.ant-form-item-label {
font-weight: 500;
label {
color: #ecf0f1 !important;
}
}
// 深色背景下的表单项样式
.ant-input,
.ant-select-selector {
background-color: #34495e !important;
border-color: #5a6c7d !important;
color: #ecf0f1 !important;
&:hover {
border-color: #7fb3d3 !important;
}
&:focus {
border-color: #2d5cf6 !important;
box-shadow: 0 0 0 2px rgba(45, 92, 246, 0.2) !important;
}
}
.ant-select-selection-placeholder,
.ant-input::placeholder {
color: #95a5a6 !important;
}
.anticon {
color: #95a5a6 !important;
}
}
.actionBar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
.totalInfo {
color: #666;
font-size: 14px;
}
}
.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;
}
}
}
}
: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;
} }

@ -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 StaffInfoAdd 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 (
<Modal
title="新增人员"
open={visible}
onOk={() => this.formRef.current?.submit()}
onCancel={this.handleCancel}
width={600}
confirmLoading={loading}
destroyOnClose={true}
maskClosable={false}
>
<Form
ref={this.formRef}
layout="vertical"
onFinish={this.handleSubmit}
initialValues={{
workType: '全职'
}}
>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name="name"
label="姓名"
rules={[
{ required: true, message: '请输入姓名' },
{ min: 2, max: 10, message: '姓名长度为2-10个字符' }
]}
>
<Input
placeholder="请输入姓名"
prefix={<UserOutlined />}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="age"
label="年龄"
rules={[
{ required: true, message: '请输入年龄' }
]}
>
<InputNumber
placeholder="请输入年龄"
min={18}
max={65}
style={{ width: '100%' }}
/>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name="department"
label="部门"
rules={[
{ required: true, message: '请选择部门' }
]}
>
<Select
placeholder="请选择部门"
suffixIcon={<ApartmentOutlined />}
>
<Option value="技术部">技术部</Option>
<Option value="产品部">产品部</Option>
<Option value="运营部">运营部</Option>
<Option value="财务部">财务部</Option>
<Option value="人事部">人事部</Option>
</Select>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="position"
label="岗位"
rules={[
{ required: true, message: '请选择岗位' }
]}
>
<Select
placeholder="请选择岗位"
suffixIcon={<TeamOutlined />}
>
<Option value="高级工程师">高级工程师</Option>
<Option value="产品经理">产品经理</Option>
<Option value="运营专员">运营专员</Option>
<Option value="会计">会计</Option>
<Option value="HR专员">HR专员</Option>
</Select>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name="workType"
label="工作性质"
rules={[
{ required: true, message: '请选择工作性质' }
]}
>
<Select placeholder="请选择工作性质">
<Option value="全职">全职</Option>
{/* <Option value="兼职">兼职</Option> */}
<Option value="实习">实习</Option>
<Option value="外包">外包</Option>
</Select>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="phone"
label="电话"
rules={[
{ required: true, message: '请输入电话号码' },
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码' }
]}
>
<Input
placeholder="请输入电话号码"
prefix={<PhoneOutlined />}
maxLength={11}
/>
</Form.Item>
</Col>
</Row>
</Form>
</Modal>
);
}
}
export default StaffInfoAdd;

@ -1,6 +1,6 @@
import React, {Fragment, PureComponent} from 'react'; import React, {Fragment, PureComponent} from 'react';
import styles from './StaffResume.less'; import styles from './StaffResume.less';
class StaffResume extends PureComponent { class WorkFlow extends PureComponent {
render() { render() {
return ( return (
@ -11,4 +11,4 @@ class StaffResume extends PureComponent {
} }
} }
export default StaffResume export default WorkFlow

@ -1,10 +1,475 @@
@import '~@/utils/utils.less'; @import '~@/utils/utils.less';
.frameContent { // 主容器
.container {
background-color: #F5F6FA;
min-height: 100vh;
display: flex;
flex-direction: column;
}
// 公告栏
.announcement {
width: 100%; width: 100%;
height: 100vh; background-color: #ffffff;
border: none; padding: 8px 16px;
display: block; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
.scrollContainer {
overflow: hidden;
white-space: nowrap;
.scrollContent {
display: inline-block;
animation: scroll 20s linear infinite;
.announcementLabel {
font-weight: 500;
color: #2D5CF6;
margin-right: 16px;
}
.announcementItem {
margin-right: 32px;
font-size: 14px;
color: #666;
}
}
@keyframes scroll {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-50%);
}
}
}
}
.mainContent {
flex: 1;
padding: 24px;
max-width: 1200px;
margin: 0 auto;
width: 100%;
}
// 导航栏
.navigationBar {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 16px;
.backButton {
color: #2D5CF6;
font-size: 14px;
padding-left: 0;
&:hover {
color: #1040c6;
}
}
}
// 面包屑
.breadcrumb {
.breadcrumbLink {
color: #999;
&:hover {
color: #2D5CF6;
}
}
}
// 个人信息卡片
.profileCard {
margin-bottom: 24px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
:global(.ant-card-body) {
padding: 24px;
}
}
.profileHeader {
display: flex;
flex-direction: column;
.avatarSection {
margin-bottom: 16px;
display: flex;
justify-content: flex-start;
.avatar {
border-radius: 8px;
border: 1px solid #e8e8e8;
}
}
.profileInfo {
flex: 1;
.profileMain {
display: flex;
flex-direction: column;
justify-content: space-between;
margin-bottom: 16px;
.staffName {
font-size: 32px;
font-weight: bold;
color: #262626;
margin: 0 0 8px 0;
}
.staffTitle {
color: #8c8c8c;
margin: 0;
font-size: 16px;
}
.actionButtons {
margin-top: 8px;
display: flex;
gap: 8px;
}
}
.basicInfo {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 16px;
.infoItem {
.infoLabel {
font-size: 12px;
color: #8c8c8c;
margin: 0 0 4px 0;
}
.infoValue {
font-size: 14px;
font-weight: 500;
color: #262626;
margin: 0;
}
.infoValueStatus {
font-size: 14px;
font-weight: 500;
color: #52c41a;
margin: 0;
}
}
}
}
}
// 详情容器
.detailsContainer {
display: flex;
flex-direction: column;
gap: 24px;
}
// 详情卡片
.detailCard {
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
:global(.ant-card-head) {
border-bottom: 1px solid #f0f0f0;
.ant-card-head-title {
font-size: 18px;
font-weight: 500;
}
}
}
// 节标题
.sectionTitle {
display: flex;
align-items: center;
.sectionIcon {
color: #2D5CF6;
margin-right: 8px;
font-size: 16px;
}
}
// 描述列表
.descriptions {
:global(.ant-descriptions-item-label) {
font-weight: 500;
color: #8c8c8c;
font-size: 12px;
width: 100px;
}
:global(.ant-descriptions-item-content) {
font-size: 14px;
color: #262626;
}
}
// 表格样式
.detailTable {
:global(.ant-table-thead > tr > th) {
background-color: #fafafa;
font-weight: 500;
color: #8c8c8c;
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.companyName, .schoolName {
font-weight: 500;
color: #262626;
}
.duration {
font-size: 12px;
color: #8c8c8c;
}
}
// 组织架构图
.orgChart {
background-color: #f5f5f5;
border-radius: 8px;
padding: 16px;
height: 256px;
display: flex;
align-items: center;
justify-content: center;
.orgChartImage {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
}
// 职业时间线
.careerTimeline {
:global(.ant-timeline-item-content) {
margin-left: 20px;
}
.timelineItem {
padding: 16px 0;
border-left: 2px solid #e8e8e8;
margin-left: 8px;
position: relative;
&:before {
content: '';
position: absolute;
left: -6px;
top: 20px;
width: 10px;
height: 10px;
border-radius: 50%;
background-color: #d9d9d9;
}
&:first-child:before {
background-color: #2D5CF6;
}
.timelineContent {
margin-left: 24px;
}
}
}
.timelineHeader {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 4px;
.companyName {
font-weight: 500;
color: #262626;
margin: 0;
font-size: 16px;
}
.positionName {
color: #8c8c8c;
margin: 0; margin: 0;
font-size: 14px;
}
}
.timelineDuration {
font-size: 12px;
color: #8c8c8c;
margin: 4px 0;
}
.timelineDescription {
font-size: 14px;
color: #595959;
margin: 8px 0 0 0;
line-height: 1.5;
}
// 底部通栏
.footer {
background-color: #262626;
color: white;
width: 100%;
padding: 32px 0;
margin-top: auto;
.footerContent {
max-width: 1200px;
margin: 0 auto;
padding: 0 16px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 32px;
margin-bottom: 24px;
.footerSection {
.footerTitle {
font-size: 14px;
font-weight: 500;
margin-bottom: 16px;
color: white;
}
.footerList {
list-style: none;
padding: 0; padding: 0;
margin: 0;
li {
margin-bottom: 8px;
.footerLink {
font-size: 12px;
color: #bfbfbf;
text-decoration: none;
transition: color 0.3s;
&:hover {
color: white;
}
}
.contactItem {
font-size: 12px;
color: #bfbfbf;
display: flex;
align-items: flex-start;
}
}
}
}
}
.footerBottom {
border-top: 1px solid #404040;
padding-top: 24px;
.footerBottomContent {
max-width: 1200px;
margin: 0 auto;
padding: 0 16px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
.copyright {
font-size: 12px;
color: #8c8c8c;
margin: 0 0 8px 0;
}
.footerLinks {
display: flex;
gap: 16px;
.footerBottomLink {
font-size: 12px;
color: #8c8c8c;
text-decoration: none;
transition: color 0.3s;
&:hover {
color: white;
}
}
}
}
}
}
// 响应式设计
@media (min-width: 768px) {
.profileHeader {
flex-direction: row;
align-items: flex-start;
.avatarSection {
margin-right: 24px;
margin-bottom: 0;
}
.profileMain {
flex-direction: row;
align-items: center;
.actionButtons {
margin-top: 0;
}
}
.basicInfo {
grid-template-columns: repeat(4, 1fr);
}
}
.footer {
.footerBottomContent {
flex-direction: row;
.copyright {
margin-bottom: 0;
}
}
}
}
@media (max-width: 768px) {
.mainContent {
padding: 16px;
}
.profileCard {
:global(.ant-card-body) {
padding: 16px;
}
}
.basicInfo {
grid-template-columns: repeat(2, 1fr);
}
.footer {
.footerContent {
grid-template-columns: 1fr;
}
}
} }

@ -45,6 +45,12 @@ const menuItem = [
key: '/topnavbar00/staffmanage/workflow', key: '/topnavbar00/staffmanage/workflow',
// icon: <SettingOutlined />, // icon: <SettingOutlined />,
}, },
{
label: '',
// label: '详情页',
key: '/topnavbar00/staffmanage/particulars',
// icon: <SettingOutlined />,
},
] ]
}, },
{ {

Loading…
Cancel
Save