diff --git a/package.json b/package.json
index 4a5ff19..912e2fe 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
"braft-finder": "^0.0.21",
"braft-utils": "^3.0.2",
"echarts": "^4.9.0",
+ "echarts-for-react": "^3.0.2",
"moment": "^2.29.1",
"qs": "^6.11.0",
"react": "^18.2.0",
diff --git a/src/pages/organmanage_organchart/OrganChart.js b/src/pages/organmanage_organchart/OrganChart.js
index 76bf05a..5f73836 100644
--- a/src/pages/organmanage_organchart/OrganChart.js
+++ b/src/pages/organmanage_organchart/OrganChart.js
@@ -1,14 +1,472 @@
-import React, {Fragment, PureComponent} from 'react';
+import React, { PureComponent } from 'react';
+import { Card, Button, Alert, Dropdown, Row, Col, Tree, Statistic } from 'antd';
+import {
+ BuildingOutlined,
+ TeamOutlined,
+ ClockCircleOutlined,
+ DownloadOutlined,
+ DownOutlined,
+ SyncOutlined,
+ UserOutlined,
+ DollarOutlined,
+ SettingOutlined,
+ BellOutlined
+} from '@ant-design/icons';
+import ReactECharts from 'echarts-for-react';
import styles from './OrganChart.less';
+
class OrganChart extends PureComponent {
- render() {
-
- return (
- <>
-
- >
- )
- }
+ constructor(props) {
+ super(props);
+ this.state = {
+ selectedYear: '2023',
+ expandedKeys: ['0-0', '0-0-0', '0-0-1', '0-0-2'],
+ organizationData: [
+ {
+ title: '集团公司',
+ key: '0-0',
+ count: 1284,
+ children: [
+ {
+ title: '行政中心',
+ key: '0-0-0',
+ count: 356,
+ children: [
+ { title: '人力资源部', key: '0-0-0-0', count: 45 },
+ { title: '财务部', key: '0-0-0-1', count: 32 },
+ { title: 'IT部', key: '0-0-0-2', count: 28 }
+ ]
+ },
+ {
+ title: '营销中心',
+ key: '0-0-1',
+ count: 268,
+ children: [
+ { title: '市场部', key: '0-0-1-0', count: 86 },
+ { title: '销售部', key: '0-0-1-1', count: 124 },
+ { title: '客户服务部', key: '0-0-1-2', count: 58 }
+ ]
+ },
+ {
+ title: '研发中心',
+ key: '0-0-2',
+ count: 232,
+ children: [
+ { title: '前端开发部', key: '0-0-2-0', count: 76 },
+ { title: '后端开发部', key: '0-0-2-1', count: 92 },
+ { title: '移动开发部', key: '0-0-2-2', count: 64 }
+ ]
+ }
+ ]
+ }
+ ]
+ };
+ }
+
+ // 获取处理后的树形数据
+ 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('集团')) return ;
+ if (title.includes('中心')) return ;
+ if (title.includes('人力')) return ;
+ if (title.includes('财务')) return ;
+ if (title.includes('IT') || title.includes('开发')) return ;
+ return ;
+ };
+
+ // 获取年份菜单
+ getYearMenu = () => {
+ const years = ['2021', '2022', '2023', '2024'];
+ const menuItems = years.map(year => ({
+ key: year,
+ label: year,
+ }));
+
+ return {
+ items: menuItems,
+ onClick: ({ key }) => this.setState({ selectedYear: key })
+ };
+ };
+
+ // ECharts配置选项
+ getDepartmentChartOption = () => {
+ return {
+ title: {
+ text: '各部门人员分布',
+ left: 'center',
+ textStyle: {
+ fontSize: 16,
+ fontWeight: 'normal'
+ }
+ },
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: {
+ type: 'shadow'
+ },
+ formatter: '{b}: {c}人'
+ },
+ grid: {
+ left: '3%',
+ right: '4%',
+ bottom: '3%',
+ top: '15%',
+ containLabel: true
+ },
+ xAxis: {
+ type: 'value',
+ axisLine: { show: false },
+ axisTick: { show: false },
+ splitLine: {
+ lineStyle: { color: '#f0f0f0' }
+ }
+ },
+ yAxis: {
+ type: 'category',
+ data: ['人力资源部', '财务部', 'IT部', '市场部', '销售部', '客户服务部', '前端开发部', '后端开发部', '移动开发部'],
+ axisLine: { show: false },
+ axisTick: { show: false },
+ axisLabel: {
+ fontSize: 12
+ }
+ },
+ series: [
+ {
+ name: '人数',
+ type: 'bar',
+ data: [45, 32, 28, 86, 124, 58, 76, 92, 64],
+ itemStyle: {
+ color: '#1890ff',
+ borderRadius: [0, 4, 4, 0]
+ },
+ barWidth: 20,
+ label: {
+ show: true,
+ position: 'right',
+ formatter: '{c}人',
+ fontSize: 11
+ }
+ }
+ ]
+ };
+ };
+
+ // 组织架构分布饼图配置
+ getOrgPieChartOption = () => {
+ return {
+ title: {
+ text: '部门人员占比',
+ left: 'center',
+ textStyle: {
+ fontSize: 16,
+ fontWeight: 'normal'
+ }
+ },
+ tooltip: {
+ trigger: 'item',
+ formatter: '{a}
{b}: {c}人 ({d}%)'
+ },
+ legend: {
+ orient: 'vertical',
+ left: 10,
+ top: 'middle',
+ textStyle: {
+ fontSize: 12
+ }
+ },
+ series: [
+ {
+ name: '部门分布',
+ type: 'pie',
+ radius: ['40%', '70%'],
+ center: ['65%', '50%'],
+ avoidLabelOverlap: false,
+ label: {
+ show: false,
+ position: 'center'
+ },
+ emphasis: {
+ label: {
+ show: true,
+ fontSize: '14',
+ fontWeight: 'bold'
+ }
+ },
+ labelLine: {
+ show: false
+ },
+ data: [
+ { value: 356, name: '行政中心' },
+ { value: 268, name: '营销中心' },
+ { value: 232, name: '研发中心' },
+ { value: 428, name: '其他部门' }
+ ],
+ itemStyle: {
+ borderRadius: 5,
+ borderColor: '#fff',
+ borderWidth: 2
+ }
+ }
+ ]
+ };
+ };
+
+ // 树节点展开/收起处理
+ onExpand = (expandedKeys) => {
+ this.setState({ expandedKeys });
+ };
+
+ render() {
+ const { selectedYear, expandedKeys } = this.state;
+
+ return (
+
+ {/* 公告栏 */}
+
+
+
+ 公告
+
+
+
+ 2023年度绩效考核方案已发布,请各部门负责人及时查阅
+ 系统将于2023年12月25日00:00-06:00进行升级维护
+ 新员工入职培训计划已更新,请相关人员注意查收邮件
+ 年度优秀员工评选活动正式启动,详情请见内网公告
+
+
+
+ }
+ type="info"
+ closable
+ className={styles['organ-chart-announcement']}
+ />
+
+
+ {/* 左侧组织架构树 */}
+
+
+
+
+ 组织架构
+
+ }
+ size="small"
+ style={{ color: '#1890ff' }}
+ />
+
+ }
+ className={styles['org-sidebar']}
+ style={{ height: 'calc(100vh - 200px)', overflowY: 'auto' }}
+ >
+
+
+
+
+
+
+ {/* 右侧内容区 */}
+
+
+ {/* 筛选区域 */}
+
+
+
组织架构详情
+
+
+ 年份:
+
+
+
+
+
}>
+ 导出
+
+
+
+
+
+ {/* 主要内容区 */}
+
+ {/* 组织架构图 */}
+
+
+ 集团公司
+ 1,284人
+
+
+
+
+
+ 行政中心
+ 356人
+
+
+
+ 人力资源部
+ 45人
+
+
+ 财务部
+ 32人
+
+
+ IT部
+ 28人
+
+
+
+
+
+
+ 营销中心
+ 268人
+
+
+
+ 市场部
+ 86人
+
+
+ 销售部
+ 124人
+
+
+ 客户服务部
+ 58人
+
+
+
+
+
+
+ 研发中心
+ 232人
+
+
+
+ 前端开发部
+ 76人
+
+
+ 后端开发部
+ 92人
+
+
+ 移动开发部
+ 64人
+
+
+
+
+
+
+ {/* 统计卡片 */}
+
+
+
+ }
+ suffix="个"
+ valueStyle={{ color: '#1890ff' }}
+ />
+ 较上月增加2个
+
+
+
+
+ }
+ suffix="人"
+ valueStyle={{ color: '#52c41a' }}
+ />
+ 较上月增加56人
+
+
+
+
+ }
+ suffix="年"
+ precision={1}
+ valueStyle={{ color: '#fa8c16' }}
+ />
+ 较上月增加0.1年
+
+
+
+
+
+ {/* 图表区域 */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ }
}
-export default OrganChart
+export default OrganChart;
\ No newline at end of file
diff --git a/src/pages/organmanage_organchart/OrganChart.less b/src/pages/organmanage_organchart/OrganChart.less
index d5bff80..18ef0f6 100644
--- a/src/pages/organmanage_organchart/OrganChart.less
+++ b/src/pages/organmanage_organchart/OrganChart.less
@@ -1,10 +1,478 @@
@import '~@/utils/utils.less';
-.frameContent {
+/* 组织架构页面样式 */
+.organ-chart-page {
+ padding: 16px;
+ background-color: #f9fafb;
+ min-height: 100vh;
+
+ /* 自定义滚动条样式 */
+ &::-webkit-scrollbar {
+ width: 8px;
+ height: 8px;
+ }
+
+ &::-webkit-scrollbar-track {
+ background: #f1f1f1;
+ border-radius: 4px;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background: #c1c1c1;
+ border-radius: 4px;
+
+ &:hover {
+ background: #a8a8a8;
+ }
+ }
+
+ /* 内容滚动区域的滚动条样式 */
+ div[style*="overflowY: auto"] {
+ &::-webkit-scrollbar {
+ width: 6px;
+ }
+
+ &::-webkit-scrollbar-track {
+ background: transparent;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background: #d9d9d9;
+ border-radius: 3px;
+
+ &:hover {
+ background: #bfbfbf;
+ }
+ }
+ }
+}
+
+/* 公告栏样式 */
+.organ-chart-announcement {
+ margin-bottom: 24px;
+ border-radius: 6px;
+ overflow: hidden;
+}
+
+.announcement-container {
+ display: flex;
+ align-items: center;
+}
+
+.announcement-badge {
+ 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;
+ }
+}
+
+.announcement-content {
+ overflow: hidden;
+ flex: 1;
+}
+
+.marquee-text {
+ white-space: nowrap;
+ animation: marquee 20s linear infinite;
+ display: inline-block;
+
+ span {
+ font-size: 14px;
+ margin-right: 32px;
+
+ &:last-child {
+ margin-right: 0;
+ }
+ }
+}
+
+@keyframes marquee {
+ 0% {
+ transform: translateX(100%);
+ }
+ 100% {
+ transform: translateX(-100%);
+ }
+}
+
+/* 组织架构侧边栏样式 */
+.org-sidebar {
+ height: fit-content;
+
+ .ant-card-body {
+ padding: 16px 8px 16px 16px;
+ }
+
+ /* 树形组件滚动区域样式 */
+ .ant-tree {
+ &::-webkit-scrollbar {
+ width: 4px;
+ }
+
+ &::-webkit-scrollbar-track {
+ background: transparent;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background: #d9d9d9;
+ border-radius: 2px;
+
+ &:hover {
+ background: #bfbfbf;
+ }
+ }
+ }
+}
+
+/* Tree节点标题样式 */
+.tree-node-title {
+ display: flex;
+ align-items: center;
+
+ .node-text {
+ flex: 1;
+ font-size: 14px;
+ margin-left: 8px;
+ }
+
+ .node-count {
+ color: #999;
+ font-size: 12px;
+ margin-left: auto;
+ }
+}
+
+.org-node {
+ background-color: #F5F6FA;
+ padding: 8px;
+ border-radius: 4px;
+ cursor: pointer;
+ margin-bottom: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ transition: all 0.3s ease;
+
+ &.has-children {
+ cursor: pointer;
+ }
+
+ &:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
+ }
+}
+
+.node-content {
+ display: flex;
+ align-items: center;
+
+ .node-icon {
+ color: #6b7280;
+ display: flex;
+ align-items: center;
+
+ .anticon {
+ color: #6b7280;
+ }
+ }
+}
+
+.node-text {
+ font-size: 14px;
+ margin-left: 8px;
+}
+
+.expand-icon {
+ font-size: 12px;
+ color: #9ca3af;
+}
+
+.org-children {
+ margin-left: 24px;
+}
+
+/* 筛选区域样式 */
+.filter-section {
+ margin-bottom: 24px;
+}
+
+.section-title {
+ font-size: 18px;
+ font-weight: 500;
+}
+
+.filter-actions {
+ display: flex;
+ align-items: center;
+ gap: 16px;
+}
+
+.year-selector {
+ display: flex;
+ align-items: center;
+
+ span {
+ font-size: 14px;
+ color: #6b7280;
+ margin-right: 8px;
+ }
+}
+
+/* 主要内容区样式 */
+.main-content {
+ border-radius: 6px;
+}
+
+/* 组织架构图样式 */
+.org-chart-container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.org-chart-node {
+ text-align: center;
+ transition: all 0.3s ease;
+ cursor: pointer;
+
+ &:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
+ }
+}
+
+.company-node {
+ background: #2D5CF6;
+ color: #fff;
+ width: 192px;
+ margin-bottom: 16px;
+
+ :global(.ant-card-body) {
+ padding: 12px;
+ }
+
+ .node-title {
+ font-weight: 500;
+ font-size: 16px;
+ }
+
+ .node-count {
+ font-size: 12px;
+ opacity: 0.8;
+ }
+}
+
+.center-row {
width: 100%;
- height: 100vh;
- border: none;
- display: block;
- margin: 0;
- padding: 0;
-}
\ No newline at end of file
+}
+
+.center-column {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.center-node {
+ background: #dbeafe;
+ width: 160px;
+ margin-bottom: 16px;
+
+ :global(.ant-card-body) {
+ padding: 12px;
+ }
+
+ .node-title {
+ font-weight: 500;
+ }
+
+ .node-count {
+ font-size: 12px;
+ color: #6b7280;
+ }
+}
+
+.department-list {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+}
+
+.department-node {
+ background: #eff6ff;
+ width: 128px;
+
+ :global(.ant-card-body) {
+ padding: 8px;
+ }
+
+ .node-title {
+ font-size: 14px;
+ }
+
+ .node-count {
+ font-size: 12px;
+ color: #6b7280;
+ }
+}
+
+/* 统计卡片样式 */
+.statistics-row {
+ margin-top: 32px;
+}
+
+.stat-card {
+ background: #F5F6FA;
+ border-radius: 6px;
+}
+
+.stat-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 8px;
+}
+
+.stat-title {
+ font-size: 14px;
+ font-weight: 500;
+ color: #6b7280;
+}
+
+.stat-icon {
+ .anticon {
+ font-size: 20px;
+ color: #2d5cf6;
+ }
+}
+
+.stat-value {
+ font-size: 24px;
+ font-weight: bold;
+ margin-bottom: 4px;
+}
+
+.stat-desc {
+ font-size: 12px;
+ color: #6b7280;
+}
+
+/* 图表区域样式 */
+.chart-section {
+ margin-top: 32px;
+}
+
+.chart-title {
+ font-size: 18px;
+ font-weight: 500;
+ margin-bottom: 16px;
+}
+
+.chart-container {
+ background: #F5F6FA;
+ border-radius: 6px;
+}
+
+/* 图表区域样式 */
+.charts-row {
+ margin-top: 16px;
+}
+
+.chart-section {
+ border-radius: 8px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+
+ :global(.ant-card-head-title) {
+ font-size: 16px;
+ font-weight: 500;
+ }
+
+ :global(.ant-card-body) {
+ padding: 20px;
+ }
+}
+
+/* 统计描述样式 */
+.stat-desc {
+ margin-top: 8px;
+ font-size: 12px;
+ color: #52c41a;
+}
+
+/* 响应式样式 */
+@media (max-width: 768px) {
+ .organ-chart-page {
+ padding: 8px;
+ }
+
+ .announcement-badge {
+ display: none;
+ }
+
+ .announcement-content {
+ overflow: hidden;
+ }
+
+ .filter-actions {
+ flex-direction: column;
+ gap: 8px;
+ align-items: flex-end;
+ }
+
+ .center-row {
+ flex-direction: column;
+ align-items: center;
+ gap: 24px;
+ }
+
+ .statistics-row {
+ :global(.ant-col) {
+ margin-bottom: 16px;
+ }
+ }
+
+ .charts-row {
+ :global(.ant-col) {
+ margin-bottom: 16px;
+ }
+ }
+
+ /* 移动端下的滚动优化 */
+ .organ-chart-page {
+ padding: 8px;
+ }
+
+ .org-sidebar {
+ margin-bottom: 16px;
+ }
+}
+
+/* 移动端触摸滚动优化 */
+@media screen and (max-width: 768px) {
+ .organ-chart-page {
+ -webkit-overflow-scrolling: touch;
+
+ div[style*="overflowY: auto"] {
+ -webkit-overflow-scrolling: touch;
+ }
+ }
+
+ /* 移动端隐藏滚动条但保留滚动功能 */
+ .org-sidebar .ant-tree {
+ &::-webkit-scrollbar {
+ display: none;
+ }
+ scrollbar-width: none;
+ -ms-overflow-style: none;
+ }
+}