- {/* 头部保持不变 */}
-
-
-
-
-

+
+
+
+ {/* 头部 */}
+
+
+
+
+
+ {this.state.configBanner.slice(0, 3).map((item, index) => (
this.handleTabClick(item)}
>
- {this.state.configBanner &&
- this.state.configBanner.slice(0, 3).map((item, index) => (
-
this.handleTabClick(item)}
- onKeyPress={(e) => e.key === 'Enter' && this.handleTabClick(item)}
- tabIndex={0}
- title={`点击进入${item}`}
- role="button"
- style={{ cursor: 'pointer' }}
- >
- {item}
-
- ))}
+ {item}
-
-
-
-
-
-
-
- {this.state.configBanner &&
- this.state.configBanner.slice(3, 6).map((item, index) => (
-
this.handleTabClick(item)}
- onKeyPress={(e) => e.key === 'Enter' && this.handleTabClick(item)}
- tabIndex={0}
- title={`点击进入${item}`}
- role="button"
- style={{ cursor: 'pointer' }}
- >
- {item}
-
- ))}
-
-
- {/* {this.state.nowWeek} */}
- {this.state.nowDate}
-
-
-
-
-
- {/* 条件渲染的内容区域 */}
- {renderContent()}
+ ))}
+
+
+
+
金源公司安全生产管控平台
+
+
+
+ {this.state.configBanner.slice(3, 6).map((item, index) => (
+
this.handleTabClick(item)}
+ >
+ {item}
+
+ ))}
+
+
+
+ {this.state.nowDate}
+
+
+
+
+ {/* 内容区域 */}
+ {activeTab === '首页' ? (
+
+ ) : (
+ this.renderOtherTabContent()
+ )}
-
+
);
}
}
diff --git a/src/layout/fullinter.less b/src/layout/fullinter.less
index 78156c9..0e7a020 100644
--- a/src/layout/fullinter.less
+++ b/src/layout/fullinter.less
@@ -1,3 +1,4 @@
+// fullinter.less - 修复后的完整样式
@font-face {
font-family: pangmenzhengdao;
src: url('../assets/fonts/pangmenzhengdao.ttf');
@@ -16,6 +17,7 @@
font-display: swap;
}
+// 主容器
.box {
transform-origin: 0 0;
position: absolute;
@@ -25,76 +27,72 @@
}
.blackBack {
- background-image: url('../assets/login/bg.png');
width: 100%;
- // height: calc(100% - 10px); // 进入全屏
height: 100%;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
+
.backImage {
- background-color: #021428; //021428
+ background-color: #f2f5f9;
width: 100%;
height: 100%;
- opacity: 0.9;
display: flex;
flex-direction: column;
overflow: hidden;
}
+
+// 头部
.header {
- // background-image: url('../assets/layout/full-header.png');
- // background-size: cover;
- // background-position: center;
- // background-repeat: no-repeat;
height: 60px;
display: flex;
align-items: center;
justify-content: space-between;
flex-direction: row;
margin: 10px;
- background-color: rgba(73, 122, 175, 0.3);
+ background-color: #fff;
+ flex-shrink: 0;
}
+
.headerText {
- color: GoldenRod;
+ color: #000;
font-size: 32px;
white-space: nowrap;
- // font-weight: bold;
- // margin-top: 10px;
- font-family: 'pangmenzhengdao';
+ font-weight: bold;
}
+
.configBanners {
- // height: 100%;
width: 110px;
height: 48px;
- font-size: 20px; // 适当减小字体大小
+ font-size: 20px;
margin: 0px 10px;
font-style: italic;
font-weight: bold;
- color: #fff;
- border: 1px solid transparent; // 默认透明边框
- // border: 1px solid #00caf7;
+ color: #000;
+ border: 1px solid transparent;
white-space: nowrap;
- background: linear-gradient(to bottom, #01408e, #07295e);
- display: flex; // 使用flex布局
- align-items: center; // 垂直居中
- justify-content: center; // 水平居中
- text-align: center; // 文字居中
- box-sizing: border-box; // 确保边框计算在内
- padding: 0 2px; // 如果需要可以添加内边距
- overflow: hidden; // 防止内容溢出
- text-overflow: ellipsis; // 文字过长显示省略号
- position: relative;
+ background: #e3f2e9;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ text-align: center;
+ box-sizing: border-box;
+ padding: 0 2px;
overflow: hidden;
+ text-overflow: ellipsis;
+ position: relative;
+ cursor: pointer;
+
&:hover {
- border-color: #00caf7; // 悬停效果
+ border-color: #00caf7;
opacity: 0.9;
}
&.active {
border: 1px solid #00caf7 !important;
- background: linear-gradient(to bottom, #0150a0, #083070); // 激活时背景加深
- box-shadow: 0 0 10px rgba(0, 202, 247, 0.5); // 可选:添加发光效果
+ background: linear-gradient(to bottom, #01408e, #07295e);
+ color: #fff;
}
&::after {
@@ -116,6 +114,7 @@
animation: pulse 2s infinite;
}
}
+
@keyframes pulse {
0% {
box-shadow: 0 0 5px rgba(0, 202, 247, 0.5);
@@ -127,18 +126,10 @@
box-shadow: 0 0 5px rgba(0, 202, 247, 0.5);
}
}
-.boxBack {
- width: 100%;
- height: 100%;
- display: flex;
- align-items: center;
- flex-direction: column;
- padding: 0px 20px;
-}
+
+// 其他tab内容
.otherTabContent {
- flex: 1; // 占据剩余空间
- // width: 100%;
- height: 100%;
+ flex: 1;
display: flex;
align-items: center;
justify-content: center;
@@ -147,405 +138,455 @@
margin: 0px 10px 10px 10px;
border: 1px solid rgba(0, 202, 247, 0.3);
}
-.row {
- // height: calc(65% - 200px);
+
+// ========== HomeContent 组件样式 ==========
+.homeContentWrapper {
flex: 1;
width: 100%;
+ overflow: hidden;
+ padding: 0 10px 10px 10px;
+ box-sizing: border-box;
}
-.rowTwo {
- height: 30%;
+
+.homeContentRow {
+ height: 100%;
width: 100%;
+}
+
+// 左右列通用样式
+.leftCol,
+.rightCol,
+.middleCol {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+}
+
+// 左侧和右侧卡片样式
+.riskCard {
+ flex: 1;
+ background-color: #fff;
+ border-radius: 4px;
+ overflow: hidden;
+ min-height: 0;
+}
+
+.hiddenCard {
+ flex: 1;
+ background-color: #fff;
+ border-radius: 4px;
+ overflow: hidden;
margin-top: 10px;
+ min-height: 0;
}
-.boxleft {
+
+.dangerCard {
+ flex: 1;
+ background-color: #fff;
+ border-radius: 4px;
+ overflow: hidden;
+ min-height: 0;
+}
+
+.spacer {
+ height: 10px;
+ flex-shrink: 0;
+}
+
+.riskRow {
height: 100%;
- // width: 100%;
+ width: 100%;
+}
+
+.riskStatsCol,
+.hiddenStatsCol,
+.trainingStatsCol {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ padding: 10px 0;
+}
+
+.chartCol {
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.chartContainer {
+ width: 100%;
+ height: 100%;
+ min-height: 0;
+}
+
+.fullChartContainer {
+ width: 100%;
+ height: 100%;
+ min-height: 0;
+}
+
+// 风险等级统计项
+.riskStatItem {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
-}
-.fullBorderBox {
- width: 100%;
- height: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 10px; // 如果需要内边距
- box-sizing: border-box; // 确保内边距计算在内
-}
-.risklevel {
- height: 50%;
- width: 100%;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- padding: 0px 10px;
-}
-.risklevelOne {
- height: 50%;
- width: 100%;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- padding: 0px 10px;
-}
-.risklevelTwo {
- height: 100%;
- width: 100%;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- padding: 0px 10px 10px 10px;
-}
-.riskChange {
- width: 30%;
- height: 100%;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: space-around;
- padding: 20px 10px;
-}
-.riskChangeTwo {
- width: 70%;
- height: 100%;
- padding: 26px 10px;
- display: flex;
- align-items: center;
- justify-content: flex-start;
-}
-.gradient {
- background-image: linear-gradient(
- 250deg,
- rgba(47, 109, 255, 1) 0%,
- rgba(255, 255, 255, 54) 50%,
- rgba(47, 109, 255, 1) 100%
- );
- width: 100%;
- height: 30%;
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 2px;
- // margin: 10px;
-}
-.gradientTwo {
- background-image: linear-gradient(
- 250deg,
- rgba(47, 109, 255, 1) 0%,
- rgba(255, 255, 255, 54) 50%,
- rgba(47, 109, 255, 1) 100%
- );
- width: 100%;
- height: 100%;
- display: flex;
- align-items: center;
- justify-content: space-around;
- padding: 2px;
-}
-.gradientThree {
- background-image: linear-gradient(
- 275deg,
- rgba(47, 109, 255, 1) 0%,
- rgba(255, 255, 255, 54) 50%,
- rgba(47, 109, 255, 1) 100%
- );
- display: flex;
- align-items: center;
- justify-content: space-around;
- padding: 2px;
-}
-.gradientNext {
- width: 100%;
- height: 100%;
- background-color: #021428;
- // z-index: 999;
-}
-.gradientNextTwo {
- width: 100%;
- height: 100%;
- background-color: rgba(47, 109, 255, 0.1);
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- padding: 5px;
- color: #fff;
-}
-.gradientText {
- font-size: 34px;
font-weight: bold;
- color: #49ebff;
- font-style: italic;
- font-family: '站酷庆科黄油体';
-}
-.gradientName {
- font-size: 12px;
-}
-.gradientTextTwo {
- font-size: 86px;
- font-weight: bold;
- // color: #ef595a;
- color: #12f714;
-}
-.gradientNameTwo {
- font-size: 28px;
-}
-.title {
- background-image: url('../assets/layout/title.png');
- background-size: cover;
- background-position: bottom;
- background-repeat: no-repeat;
- width: 90%;
- height: 25px;
- padding-bottom: 10px;
- display: flex;
- flex-direction: row;
- align-items: center;
- // justify-content: center;
-}
-.circle {
- width: 12px;
- height: 12px;
- background: #021428;
- border-radius: 50%;
- border: 3px solid #fff;
- margin-right: 5px;
-}
-.titlename {
color: #fff;
- font-size: 16px;
- font-family: '站酷庆科黄油体';
- letter-spacing: 3px;
-}
-// .risklevelOne {
-// height: 60%;
-// width: 90%;
-// }
-.boxTwo {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- height: 100%;
- // width: 100%;
-}
-.capsuleChart {
- width: 100%;
- height: 100%;
- display: flex;
- align-items: flex-start;
- justify-content: center;
- flex-direction: column;
- padding: 20px;
-}
-.scrollboard {
- width: 90%;
- height: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
- margin: 0px 20px 20px 20px;
+ margin: 10px 20px;
+ padding: 5px 10px;
+ border-radius: 4px;
flex: 1;
}
-.scrollboard :global(.header) {
- height: auto;
+
+.riskStatName {
+ margin-bottom: 5px;
+ font-size: 16px;
+}
+
+.riskStatValue {
+ font-size: 26px;
+}
+
+// 风险等级背景色
+.riskLevel重大风险 {
+ background-color: #c92a2a;
+}
+.riskLevel较大风险 {
+ background-color: #ffa94d;
+}
+.riskLevel一般风险 {
+ background-color: #ffe066;
+}
+.riskLevel低风险 {
+ background-color: #4285f4;
+}
+
+// 隐患统计样式
+.hiddenTitle {
+ color: #000;
+ font-size: 16px;
+ margin: 10px 0;
+ font-weight: bold;
+ text-align: center;
+}
+
+.hiddenStatItem {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ font-weight: bold;
+ color: #fff;
+ background-color: #1e2a3a;
+ margin: 10px 20px;
+ padding: 5px 10px;
+ border-radius: 4px;
+ flex: 1;
+}
+
+.hiddenStatName {
+ margin-bottom: 5px;
+ font-size: 14px;
+}
+
+.hiddenStatValue {
+ font-size: 36px;
+}
+
+// 培训统计样式
+.trainingTitle {
+ color: #000;
+ font-size: 16px;
+ margin: 10px 0;
+ font-weight: bold;
+ text-align: center;
+}
+
+.trainingStatItem {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ font-weight: bold;
+ color: #fff;
+ background-color: #1e2a3a;
+ margin: 10px 20px;
+ padding: 5px 10px;
+ border-radius: 4px;
+ flex: 1;
+}
+
+.trainingStatName {
+ margin-bottom: 5px;
+ font-size: 14px;
+}
+
+.trainingStatValue {
+ font-size: 36px;
+}
+
+// 中间区域样式
+.middleCol {
+ padding: 0 10px;
+}
+
+.sloganCard {
+ background-color: #fff;
+ border-radius: 4px;
+ padding: 15px;
+ text-align: center;
+ flex-shrink: 0;
+}
+
+.sloganText {
+ font-size: 20px;
+ font-weight: bold;
+ margin-bottom: 8px;
+ color: #000;
+}
+
+.sloganSubText {
+ font-size: 20px;
+ font-weight: bold;
+ color: #000;
+}
+
+.carouselCard {
+ flex: 4;
+ background-color: #fff;
+ border-radius: 4px;
+ margin-top: 10px;
+ overflow: hidden;
+ min-height: 0;
+}
+
+.carouselWrapper {
+ position: relative;
+ width: 100%;
+ height: 100%;
+}
+
+.carousel {
+ width: 100%;
+ height: 100%;
+}
+
+.carouselItem {
+ width: 100%;
+ height: 100%;
+}
+
+.mediaVideo {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.mediaImage {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.announcementCard {
+ flex: 3;
+ background-color: #fff;
+ border-radius: 4px;
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+ min-height: 0;
+}
+
+.announcementHeader {
+ width: 100%;
+ padding: 12px 16px;
+ border-bottom: 2px solid #1890ff;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ flex-shrink: 0;
+}
+
+.announcementTitle {
+ display: flex;
+ align-items: center;
+}
+
+.announcementIcon {
+ font-size: 20px;
+ color: #1890ff;
+ margin-right: 8px;
+}
+
+.announcementTitle span {
+ font-size: 20px;
+ font-weight: bold;
+ color: #1890ff;
+}
+
+.announcementCount {
+ font-size: 14px;
+ color: #999;
+}
+
+.announcementList {
+ flex: 1;
+ overflow-y: auto;
+ padding: 8px 0;
+}
+
+.announcementUl {
+ list-style: none;
+ margin: 0;
padding: 0;
}
-.scrollboard :global(.dv-scroll-board .rows .ceil) {
- text-align: center;
-}
-.scrollboard :global(.dv-scroll-board .header .header-item) {
- text-align: center;
+
+.announcementItem {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 10px 16px;
+ border-bottom: 1px solid #f0f0f0;
+ cursor: pointer;
+ transition: background-color 0.3s;
+
+ &:hover {
+ background-color: #f5f5f5;
+ }
}
-.scoreBox {
- // background-image: url("../assets/layout/score-box.png");
- // background-size: cover;
- // background-position: center;
- // background-repeat: no-repeat;
- width: 100%;
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 20px;
+.announcementItemTitle {
+ font-size: 18px;
+ color: #333;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ flex: 1;
+ text-align: left;
}
-.scoreBox1 {
- background-image: url('../assets/layout/score-box.png');
- background-size: contain;
- background-position: center;
- background-repeat: no-repeat;
- width: 100%;
- // height: 140px;
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-around;
- margin-bottom: 20px;
- padding: 5px;
+
+.announcementItemTime {
+ font-size: 16px;
+ color: #999;
+ margin-left: 16px;
+ white-space: nowrap;
}
-.score {
- display: flex;
- flex-direction: row;
- // align-items: center;
- // justify-content: space-between;
- background-image: url('../assets/layout/ks.png');
- background-size: cover;
- background-position: center;
- background-repeat: no-repeat;
- object-fit: cover;
- // width: 230px;
- width: 33%;
- height: auto;
- margin: 10px;
-}
-.score2 {
- display: flex;
- flex-direction: row;
- // align-items: center;
- // justify-content: space-between;
- background-image: url('../assets/layout/xk.png');
- background-size: cover;
- background-position: center;
- background-repeat: no-repeat;
- object-fit: cover;
- width: 33%;
- height: auto;
- margin: 10px;
-}
-.score3 {
- display: flex;
- flex-direction: row;
- // align-items: center;
- // justify-content: space-between;
- background-image: url('../assets/layout/wk.png');
- background-size: cover;
- background-position: center;
- background-repeat: no-repeat;
- object-fit: cover;
- width: 33%;
- height: auto;
- margin: 10px;
-}
-.score4 {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: space-between;
- background-image: url('../assets/layout/score.png');
- background-size: contain;
- background-position: center;
- background-repeat: no-repeat;
- width: 30%;
- padding: 0px 15px;
- // height: 100%;
- // margin: 10px;
-}
-.scoreRight {
+
+.emptyAnnouncement {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
- width: 40%;
- margin-left: 50%;
-}
-.scoreLeft {
- font-size: 12px;
- font-weight: bold;
- color: #6cc8d9;
- margin-top: 5px;
-}
-.scoreText {
- font-size: 13px;
- font-weight: bold;
- color: #6cc8d9;
-}
-.scoreText2 {
- font-size: 33px;
- color: #7fffff;
- font-weight: bold;
- // font-style: oblique;
-}
-.scoreText3 {
- font-size: 12px;
- color: #6cc8d9;
- font-weight: bold;
-}
-.ulData {
- li {
- // transform: rotate(45deg);
- position: absolute;
- left: 50%;
- top: 50%;
- // margin-left: -20px;
- // margin-right: -20px;
- transform: translate(-50%, -50%);
- }
- li:nth-of-type(1) {
- // transform: rotate(45deg);
- transform: translate(-50%, -50%) rotate(12deg) translate(-280px) rotate(-12deg);
- // transform-origin: 20px 220px;
- }
- li:nth-of-type(2) {
- transform: translate(-50%, -50%) rotate(38deg) translate(-280px) rotate(-38deg);
- }
- li:nth-of-type(3) {
- transform: translate(-50%, -50%) rotate(64deg) translate(-280px) rotate(-64deg);
- }
- li:nth-of-type(4) {
- transform: translate(-50%, -50%) rotate(90deg) translate(-280px) rotate(-90deg);
- }
- li:nth-of-type(5) {
- transform: translate(-50%, -50%) rotate(116deg) translate(-280px) rotate(-116deg);
- }
- li:nth-of-type(6) {
- transform: translate(-50%, -50%) rotate(142deg) translate(-280px) rotate(-142deg);
- }
- li:nth-of-type(7) {
- transform: translate(-50%, -50%) rotate(168deg) translate(-280px) rotate(-168deg);
- }
- li:nth-of-type(8) {
- transform: translate(-50%, -50%) rotate(-12deg) translate(-280px) rotate(12deg);
- }
- li:nth-of-type(9) {
- transform: translate(-50%, -50%) rotate(-38deg) translate(-280px) rotate(38deg);
- }
- li:nth-of-type(10) {
- transform: translate(-50%, -50%) rotate(-64deg) translate(-280px) rotate(64deg);
- }
- li:nth-of-type(11) {
- transform: translate(-50%, -50%) rotate(-116deg) translate(-280px) rotate(116deg);
- }
-
- li:nth-of-type(12) {
- transform: translate(-50%, -50%) rotate(-142deg) translate(-280px) rotate(142deg);
- }
- li:nth-of-type(13) {
- transform: translate(-50%, -50%) rotate(-168deg) translate(-280px) rotate(168deg);
- }
+ height: 100%;
+ color: #999;
}
-.roateData {
- background-image: linear-gradient(
- 275deg,
- rgba(47, 109, 255, 1) 0%,
- rgba(255, 255, 255, 54) 50%,
- rgba(47, 109, 255, 1) 100%
- );
+.emptyIcon {
+ font-size: 48px;
+ margin-bottom: 16px;
+}
+
+// 轮播图控件
+.customArrowLeft,
+.customArrowRight {
+ position: absolute;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 40px;
+ height: 60px;
display: flex;
align-items: center;
- justify-content: space-around;
- padding: 2px;
- // background-color: rgba(47, 109, 255, 0.1);
+ justify-content: center;
+ cursor: pointer;
+ z-index: 10;
+ transition: all 0.3s ease;
+ backdrop-filter: blur(4px);
+
+ &:hover {
+ background-color: rgba(0, 0, 0, 0.3);
+ transform: translateY(-50%) scale(1.1);
+ }
+
+ &:active {
+ transform: translateY(-50%) scale(0.95);
+ }
}
-.roatBack {
- background-color: #021428;
- width: 100%;
- height: 100%;
- padding: 5px;
+
+.customArrowLeft {
+ left: 20px;
+}
+
+.customArrowRight {
+ right: 20px;
+}
+
+.customDots {
+ position: absolute;
+ bottom: 16px;
+ left: 0;
+ right: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 12px;
+ z-index: 10;
+}
+
+.dot {
+ width: 24px;
+ height: 6px;
+ border-radius: 5px;
+ background-color: rgba(255, 255, 255, 0.5);
+ cursor: pointer;
+ transition: all 0.3s ease;
+
+ &:hover {
+ background-color: rgba(255, 255, 255, 0.8);
+ transform: scale(1.2);
+ }
+}
+
+.activeDot {
+ width: 24px;
+ border-radius: 5px;
+ background-color: rgba(255, 255, 255, 0.8);
+}
+
+// 全局 Carousel 样式
+:global {
+ .ant-carousel {
+ height: 100%;
+ width: 100%;
+ }
+ .slick-slider {
+ height: 100%;
+ width: 100%;
+ }
+ .slick-list {
+ height: 100%;
+ }
+ .slick-track {
+ height: 100%;
+ }
+ .slick-slider > div,
+ .slick-list > div,
+ .slick-track > div,
+ .slick-slide > div {
+ height: 100%;
+ }
+ .slick-slide,
+ .slick-slide > div {
+ height: 100%;
+ }
+ .slick-slider div,
+ .slick-list div,
+ .slick-track div {
+ height: 100%;
+ }
}
From 32c619a778d44c7f5c817d3ea8e5a377feb28057 Mon Sep 17 00:00:00 2001
From: yunkexin <760754045@qq.com>
Date: Wed, 22 Apr 2026 16:14:55 +0800
Subject: [PATCH 8/8] =?UTF-8?q?=E5=AE=89=E5=85=A8=E5=9F=B9=E8=AE=AD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/layout/FullOther/HomeContent.js | 158 ++++--
src/layout/FullOther/TrainingContent.js | 623 ++++++++++++++++++++++++
src/layout/FullScreenInter.js | 138 +++++-
src/layout/fullinter.less | 83 ++++
4 files changed, 964 insertions(+), 38 deletions(-)
create mode 100644 src/layout/FullOther/TrainingContent.js
diff --git a/src/layout/FullOther/HomeContent.js b/src/layout/FullOther/HomeContent.js
index acfb817..15bff2e 100644
--- a/src/layout/FullOther/HomeContent.js
+++ b/src/layout/FullOther/HomeContent.js
@@ -290,7 +290,7 @@ class HomeContent extends React.Component {
type: 'bar',
data: seriesData,
itemStyle: {
- normal: { color: '#4285F4', borderRadius: 12 },
+ normal: { color: '#4285F4', barBorderRadius: 12 },
emphasis: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)' },
},
label: { show: true, position: 'top', textStyle: { color: '#000', fontSize: 12 }, formatter: '{c}' },
@@ -323,60 +323,141 @@ class HomeContent extends React.Component {
let backLogCharts = document.getElementById('backLogChart');
if (!backLogCharts) return;
- const taskData = this.props.taskTop3 || [];
- if (taskData.length === 0) return;
+ // 使用培训数据
+ const { trainingData } = this.props;
+ const listNAME = trainingData?.listNAME || [];
+ const monthRecordCount = trainingData?.MonthRecordCount || []; // 培训场次
+ const monthPersonCount = trainingData?.MonthPersonCount || []; // 培训人次
- const barTopColor = [
- ['#75baf3', '#2177d5'],
- ['#ffa94d', '#f76707'],
- ['#99ca6e', '#48a447'],
- ];
+ if (listNAME.length === 0) {
+ this.echartsInstances.backLogChart = echarts.init(backLogCharts);
+ this.echartsInstances.backLogChart.setOption({
+ title: {
+ text: '当月工作培训统计数量',
+ x: 'center',
+ y: 'center',
+ textStyle: { fontSize: 16, color: '#999' },
+ },
+ graphic: {
+ type: 'text',
+ left: 'center',
+ top: 'middle',
+ style: {
+ text: '暂无培训数据',
+ fill: '#999',
+ fontSize: 14,
+ },
+ },
+ });
+ return;
+ }
this.echartsInstances.backLogChart = echarts.init(backLogCharts);
- let xdata = this.transformDat(taskData, barTopColor, 2);
- const legendColors = barTopColor.map((gradient) => gradient[0]);
- this.echartsInstances.backLogChart.setOption({
+ const option = {
title: {
- text: '各事项排名前三名统计',
+ text: '当月工作培训统计数量',
x: 'center',
y: '5%',
textStyle: { fontSize: 16, color: '#000' },
},
- tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: { type: 'shadow' },
+ formatter: function (params) {
+ let result = `${params[0].axisValue}
`;
+ params.forEach((param) => {
+ result += `${param.marker}${param.seriesName}: ${param.value}
`;
+ });
+ return result;
+ },
+ },
legend: {
- data: xdata.legendData.map((name, index) => ({
- name: name,
- itemStyle: { color: legendColors[index], borderWidth: 0 },
- textStyle: { color: '#000', fontSize: 14 },
- })),
- align: 'right',
- top: 10,
- right: 10,
- itemGap: 16,
+ data: ['培训人次', '培训场次'],
+ orient: 'vertical', // 垂直排列
+ right: 0, // 水平居中
+ top: 'middle', // 垂直居中
+ itemGap: 16, // 图例项间隔
itemWidth: 18,
itemHeight: 12,
+ textStyle: { color: '#000', fontSize: 14 },
+ },
+ grid: {
+ left: '5%',
+ right: '5%', // 为右侧垂直图例留出空间
+ top: '18%',
+ bottom: '5%',
+ containLabel: true,
},
- color: legendColors,
- grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
xAxis: [
{
type: 'category',
- data: xdata.companyNames,
- axisLine: { lineStyle: { color: '#3eb2e8' } },
- axisLabel: { textStyle: { color: '#000' } },
+ data: listNAME,
+ axisLine: { show: false }, // 隐藏x轴线
+ axisTick: { show: false }, // 隐藏x轴刻度线
+ axisLabel: {
+ textStyle: { color: '#000' },
+ rotate: listNAME.length > 4 ? 15 : 0,
+ interval: 0,
+ },
},
],
yAxis: [
{
type: 'value',
- axisLine: { show: false },
- axisLabel: { textStyle: { color: '#000' } },
- splitLine: { lineStyle: { color: '#4784e8' } },
+ show: true, // 显示y轴
+ axisLine: { show: false }, // 隐藏y轴线
+ axisTick: { show: false }, // 隐藏y轴刻度线
+ axisLabel: {
+ show: true, // 显示数值标签
+ textStyle: { color: '#000' },
+ },
+ splitLine: { show: false }, // 隐藏横向网格线
+ name: '', // 不显示单位名称
+ nameTextStyle: { show: false }, // 隐藏单位文字
},
],
- series: xdata.series,
- });
+ series: [
+ {
+ name: '培训人次',
+ type: 'bar',
+ data: monthPersonCount,
+ itemStyle: {
+ normal: {
+ color: '#4285F4', // 蓝色
+ barBorderRadius: 12, // 柱体圆角
+ },
+ },
+ label: {
+ show: true,
+ position: 'top',
+ textStyle: { color: '#4285F4', fontSize: 12 },
+ formatter: '{c}',
+ },
+ barWidth: '35%',
+ },
+ {
+ name: '培训场次',
+ type: 'bar',
+ data: monthRecordCount,
+ itemStyle: {
+ normal: {
+ color: '#ffe066', // 黄色
+ barBorderRadius: 12, // 柱体圆角(上左、上右、下右、下左)
+ },
+ },
+ label: {
+ show: true,
+ position: 'top',
+ textStyle: { color: '#ffe066', fontSize: 12 },
+ formatter: '{c}',
+ },
+ barWidth: '35%',
+ },
+ ],
+ };
+
+ this.echartsInstances.backLogChart.setOption(option);
const resizeHandler = () => {
if (this.echartsInstances.backLogChart && !this.isUnmounted) {
@@ -451,7 +532,8 @@ class HomeContent extends React.Component {
prevProps.riskTypeRate !== this.props.riskTypeRate ||
prevProps.jobTodayTop3 !== this.props.jobTodayTop3 ||
prevProps.linkSum !== this.props.linkSum ||
- prevProps.taskTop3 !== this.props.taskTop3
+ prevProps.taskTop3 !== this.props.taskTop3 ||
+ prevProps.trainingData !== this.props.trainingData // 新增
) {
this.disposeAllCharts();
this.initAllCharts();
@@ -602,12 +684,16 @@ class HomeContent extends React.Component {
年度培训数据
- {riskTotal.map((item, index) => (
+ {this.props.trainingData?.listNAME?.map((name, index) => (
-
{item.name}
-
{item.value}
+
{name}
+
{this.props.trainingData?.YearCount?.[index] || 0}
))}
+ {/* 如果 listNAME 为空,显示默认提示 */}
+ {(!this.props.trainingData?.listNAME || this.props.trainingData.listNAME.length === 0) && (
+ 暂无培训数据
+ )}
diff --git a/src/layout/FullOther/TrainingContent.js b/src/layout/FullOther/TrainingContent.js
new file mode 100644
index 0000000..ee7dfb1
--- /dev/null
+++ b/src/layout/FullOther/TrainingContent.js
@@ -0,0 +1,623 @@
+// TrainingContent.js - 安全培训页面组件
+import React from 'react';
+import { Row, Col, Select } from 'antd';
+import styles from './../fullinter.less';
+import echarts from 'echarts';
+const { Option } = Select;
+
+class TrainingContent extends React.Component {
+ constructor(props) {
+ super(props);
+ this.echartsInstances = {
+ chart1: null, // 各部门培训统计(柱状图)
+ chart2: null, // 各部门培训完成率
+ chart3: null, // 培训类型分布
+ chart4: null, // 月度培训对比
+ };
+ this.chartResizeHandlers = {};
+ this.isUnmounted = false;
+ }
+
+ waitForElement = (elementId, maxRetries = 10) => {
+ return new Promise((resolve) => {
+ let retries = 0;
+ const checkInterval = setInterval(() => {
+ const element = document.getElementById(elementId);
+ if (element || retries >= maxRetries) {
+ clearInterval(checkInterval);
+ resolve(!!element);
+ }
+ retries++;
+ }, 50);
+ });
+ };
+
+ // 图表1: 各部门培训统计(柱状图)- 使用 trainingSubData 数据
+ renderChart1 = async () => {
+ if (this.isUnmounted) return;
+ const elementExists = await this.waitForElement('trainingChart1');
+ if (!elementExists || this.isUnmounted) return;
+
+ if (this.echartsInstances.chart1) {
+ this.echartsInstances.chart1.dispose();
+ this.echartsInstances.chart1 = null;
+ }
+
+ const chartDom = document.getElementById('trainingChart1');
+ if (!chartDom) return;
+
+ this.echartsInstances.chart1 = echarts.init(chartDom);
+
+ // 使用 props 传入的 trainingSubData 数据(来自 getHomeSESubYear 接口)
+ const { trainingSubData } = this.props;
+ const companyNames = trainingSubData?.listNAME || []; // CName 数组
+ const personCounts = trainingSubData?.MonthPersonCount || []; // PCount 数组(培训人次)
+ const recordCounts = trainingSubData?.MonthRecordCount || []; // RCount 数组(培训场次)
+
+ // 如果没有数据,显示暂无数据提示
+ if (companyNames.length === 0) {
+ this.echartsInstances.chart1.setOption({
+ title: {
+ text: '本年度各公司培训分析',
+ x: 'center',
+ y: 'center',
+ textStyle: { fontSize: 16, color: '#999' },
+ },
+ graphic: {
+ type: 'text',
+ left: 'center',
+ top: 'middle',
+ style: {
+ text: '暂无培训数据',
+ fill: '#999',
+ fontSize: 14,
+ },
+ },
+ });
+ return;
+ }
+
+ const option = {
+ title: {
+ text: '本年度各公司培训分析',
+ x: 'center',
+ y: '5%',
+ textStyle: { fontSize: 16, color: '#000', fontWeight: 'bold' },
+ },
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: { type: 'shadow' },
+ formatter: function (params) {
+ let result = `${params[0].axisValue}
`;
+ params.forEach((param) => {
+ const unit = param.seriesName === '培训人次' ? '人次' : '场次';
+ result += `${param.marker}${param.seriesName}: ${param.value}${unit}
`;
+ });
+ return result;
+ },
+ },
+ legend: {
+ data: ['培训人次', '培训场次'],
+ right: '3%', // 靠右
+ top: '5%', // 垂直居中
+ itemGap: 16,
+ itemWidth: 18,
+ itemHeight: 12,
+ textStyle: { color: '#000', fontSize: 14 },
+ },
+ grid: {
+ left: '5%',
+ right: '5%', // 为右侧垂直图例留出空间
+ top: '18%',
+ bottom: '8%',
+ containLabel: true,
+ },
+ xAxis: [
+ {
+ type: 'category',
+ data: companyNames,
+ axisLine: { show: false },
+ axisTick: { show: false },
+ axisLabel: {
+ textStyle: { color: '#000' },
+ rotate: companyNames.length > 4 ? 15 : 0,
+ interval: 0,
+ },
+ },
+ ],
+ yAxis: [
+ {
+ type: 'value',
+ show: true,
+ axisLine: { show: false },
+ axisTick: { show: false },
+ axisLabel: {
+ show: true,
+ textStyle: { color: '#000' },
+ },
+ splitLine: { show: false },
+ name: '',
+ nameTextStyle: { show: false },
+ },
+ ],
+ series: [
+ {
+ name: '培训人次',
+ type: 'bar',
+ data: personCounts,
+ itemStyle: {
+ normal: {
+ color: '#4285F4', // 蓝色
+ },
+ },
+ label: {
+ show: true,
+ position: 'top',
+ textStyle: { color: '#4285F4', fontSize: 12 },
+ formatter: (params) => `${params.value}`,
+ },
+ barWidth: '35%',
+ },
+ {
+ name: '培训场次',
+ type: 'bar',
+ data: recordCounts,
+ itemStyle: {
+ normal: {
+ color: '#ffe066', // 黄色
+ },
+ },
+ label: {
+ show: true,
+ position: 'top',
+ textStyle: { color: '#d4a000', fontSize: 12 },
+ formatter: (params) => `${params.value}`,
+ },
+ barWidth: '35%',
+ },
+ ],
+ };
+
+ this.echartsInstances.chart1.setOption(option);
+ this.setupResizeHandler('chart1', this.renderChart1);
+ };
+ // 生成月份选项(1-12月)
+ getMonthOptions = () => {
+ const months = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'];
+ return months.map((month, index) => (
+
+ ));
+ };
+
+ // 图表2: 各部门培训完成率(横向柱状图)
+ renderChart2 = async () => {
+ if (this.isUnmounted) return;
+ const elementExists = await this.waitForElement('trainingChart2');
+ if (!elementExists || this.isUnmounted) return;
+
+ if (this.echartsInstances.chart2) {
+ this.echartsInstances.chart2.dispose();
+ this.echartsInstances.chart2 = null;
+ }
+
+ const chartDom = document.getElementById('trainingChart2');
+ if (!chartDom) return;
+
+ this.echartsInstances.chart2 = echarts.init(chartDom);
+
+ // 使用 props 传入的 trainingSubData 数据(来自 getHomeSESubYear 接口)
+ const { trainingSubDataMonth } = this.props;
+ const companyNames = trainingSubDataMonth?.listNAME || []; // CName 数组
+ const personCounts = trainingSubDataMonth?.MonthPersonCount || []; // PCount 数组(培训人次)
+ const recordCounts = trainingSubDataMonth?.MonthRecordCount || []; // RCount 数组(培训场次)
+
+ // 如果没有数据,显示暂无数据提示
+ if (companyNames.length === 0) {
+ this.echartsInstances.chart2.setOption({
+ title: {
+ text: '本年度各公司培训分析',
+ x: 'center',
+ y: 'center',
+ textStyle: { fontSize: 16, color: '#999' },
+ },
+ graphic: {
+ type: 'text',
+ left: 'center',
+ top: 'middle',
+ style: {
+ text: '暂无培训数据',
+ fill: '#999',
+ fontSize: 14,
+ },
+ },
+ });
+ return;
+ }
+
+ const option = {
+ title: {
+ text: '本年度各公司培训分析',
+ x: 'center',
+ y: '5%',
+ textStyle: { fontSize: 16, color: '#000', fontWeight: 'bold' },
+ },
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: { type: 'shadow' },
+ formatter: function (params) {
+ let result = `${params[0].axisValue}
`;
+ params.forEach((param) => {
+ const unit = param.seriesName === '培训人次' ? '人次' : '场次';
+ result += `${param.marker}${param.seriesName}: ${param.value}${unit}
`;
+ });
+ return result;
+ },
+ },
+ legend: {
+ data: ['培训人次', '培训场次'],
+ right: '3%', // 靠右
+ top: '5%', // 垂直居中
+ itemGap: 16,
+ itemWidth: 18,
+ itemHeight: 12,
+ textStyle: { color: '#000', fontSize: 14 },
+ },
+ grid: {
+ left: '5%',
+ right: '5%', // 为右侧垂直图例留出空间
+ top: '18%',
+ bottom: '8%',
+ containLabel: true,
+ },
+ xAxis: [
+ {
+ type: 'category',
+ data: companyNames,
+ axisLine: { show: false },
+ axisTick: { show: false },
+ axisLabel: {
+ textStyle: { color: '#000' },
+ rotate: companyNames.length > 4 ? 15 : 0,
+ interval: 0,
+ },
+ },
+ ],
+ yAxis: [
+ {
+ type: 'value',
+ show: true,
+ axisLine: { show: false },
+ axisTick: { show: false },
+ axisLabel: {
+ show: true,
+ textStyle: { color: '#000' },
+ },
+ splitLine: { show: false },
+ name: '',
+ nameTextStyle: { show: false },
+ },
+ ],
+ series: [
+ {
+ name: '培训人次',
+ type: 'bar',
+ data: personCounts,
+ itemStyle: {
+ normal: {
+ color: '#4285F4', // 蓝色
+ },
+ },
+ label: {
+ show: true,
+ position: 'top',
+ textStyle: { color: '#4285F4', fontSize: 12 },
+ formatter: (params) => `${params.value}`,
+ },
+ barWidth: '35%',
+ },
+ {
+ name: '培训场次',
+ type: 'bar',
+ data: recordCounts,
+ itemStyle: {
+ normal: {
+ color: '#ffe066', // 黄色
+ },
+ },
+ label: {
+ show: true,
+ position: 'top',
+ textStyle: { color: '#d4a000', fontSize: 12 },
+ formatter: (params) => `${params.value}`,
+ },
+ barWidth: '35%',
+ },
+ ],
+ };
+
+ this.echartsInstances.chart2.setOption(option);
+ this.setupResizeHandler('chart2', this.renderChart2);
+ };
+
+ // 图表3: 培训类型分布(饼图)
+ renderChart3 = async () => {
+ if (this.isUnmounted) return;
+ const elementExists = await this.waitForElement('trainingChart3');
+ if (!elementExists || this.isUnmounted) return;
+
+ if (this.echartsInstances.chart3) {
+ this.echartsInstances.chart3.dispose();
+ this.echartsInstances.chart3 = null;
+ }
+
+ const chartDom = document.getElementById('trainingChart3');
+ if (!chartDom) return;
+
+ this.echartsInstances.chart3 = echarts.init(chartDom);
+
+ // 培训类型分布数据
+ const trainingTypes = [
+ { name: '安全法规培训', value: 35 },
+ { name: '操作规程培训', value: 28 },
+ { name: '应急演练培训', value: 20 },
+ { name: '职业健康培训', value: 12 },
+ { name: '其他培训', value: 5 },
+ ];
+
+ const option = {
+ title: {
+ text: '培训类型分布',
+ x: 'center',
+ y: '5%',
+ textStyle: { fontSize: 16, color: '#000', fontWeight: 'bold' },
+ },
+ tooltip: {
+ trigger: 'item',
+ formatter: function (params) {
+ return `${params.name}: ${params.value}场 (${params.percent}%)`;
+ },
+ },
+ legend: {
+ orient: 'vertical',
+ right: '5%',
+ top: 'middle',
+ itemGap: 12,
+ itemWidth: 14,
+ itemHeight: 10,
+ textStyle: { color: '#333', fontSize: 11 },
+ formatter: function (name) {
+ const item = trainingTypes.find((t) => t.name === name);
+ return `${name} ${item?.value || 0}场`;
+ },
+ },
+ color: ['#4285F4', '#66bb6a', '#ffa94d', '#ab47bc', '#ef5350'],
+ series: [
+ {
+ name: '培训场次',
+ type: 'pie',
+ radius: ['45%', '70%'],
+ center: ['40%', '55%'],
+ avoidLabelOverlap: false,
+ label: {
+ show: true,
+ position: 'outside',
+ formatter: '{b}: {d}%',
+ textStyle: { fontSize: 11, color: '#333' },
+ },
+ emphasis: {
+ label: { show: true, fontSize: 14, fontWeight: 'bold' },
+ },
+ labelLine: { length: 8, length2: 8, smooth: true },
+ data: trainingTypes,
+ },
+ ],
+ };
+
+ this.echartsInstances.chart3.setOption(option);
+ this.setupResizeHandler('chart3', this.renderChart3);
+ };
+
+ // 图表4: 月度培训对比(分组柱状图)
+ renderChart4 = async () => {
+ if (this.isUnmounted) return;
+ const elementExists = await this.waitForElement('trainingChart4');
+ if (!elementExists || this.isUnmounted) return;
+
+ if (this.echartsInstances.chart4) {
+ this.echartsInstances.chart4.dispose();
+ this.echartsInstances.chart4 = null;
+ }
+
+ const chartDom = document.getElementById('trainingChart4');
+ if (!chartDom) return;
+
+ this.echartsInstances.chart4 = echarts.init(chartDom);
+
+ // 近6个月各部门培训场次对比
+ const months = ['1月', '2月', '3月', '4月', '5月', '6月'];
+ const departments = ['安全部', '生产部', '技术部'];
+
+ const seriesData = [
+ { name: '安全部', data: [5, 6, 7, 8, 7, 9], color: '#4285F4' },
+ { name: '生产部', data: [8, 9, 10, 11, 12, 13], color: '#66bb6a' },
+ { name: '技术部', data: [4, 5, 6, 6, 7, 8], color: '#ffa94d' },
+ ];
+
+ const option = {
+ title: {
+ text: '各部门月度培训场次对比',
+ x: 'center',
+ y: '5%',
+ textStyle: { fontSize: 16, color: '#000', fontWeight: 'bold' },
+ },
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: { type: 'shadow' },
+ formatter: function (params) {
+ let result = `${params[0].axisValue}
`;
+ params.forEach((param) => {
+ result += `${param.marker}${param.seriesName}: ${param.value}场
`;
+ });
+ return result;
+ },
+ },
+ legend: {
+ data: seriesData.map((s) => s.name),
+ orient: 'horizontal',
+ left: 'center',
+ top: '15%',
+ itemGap: 20,
+ itemWidth: 18,
+ itemHeight: 12,
+ textStyle: { color: '#333', fontSize: 12 },
+ },
+ grid: {
+ left: '8%',
+ right: '5%',
+ top: '25%',
+ bottom: '8%',
+ containLabel: true,
+ },
+ xAxis: {
+ type: 'category',
+ data: months,
+ axisLine: { lineStyle: { color: '#666' } },
+ axisLabel: { textStyle: { color: '#333' } },
+ },
+ yAxis: {
+ type: 'value',
+ name: '培训场次',
+ axisLabel: { textStyle: { color: '#666' } },
+ splitLine: { lineStyle: { color: '#e0e0e0' } },
+ },
+ series: seriesData.map((s) => ({
+ name: s.name,
+ type: 'bar',
+ data: s.data,
+ itemStyle: {
+ normal: {
+ color: s.color,
+ barBorderRadius: [4, 4, 0, 0],
+ },
+ },
+ label: {
+ show: true,
+ position: 'top',
+ textStyle: { fontSize: 10 },
+ formatter: '{c}',
+ },
+ barWidth: '25%',
+ })),
+ };
+
+ this.echartsInstances.chart4.setOption(option);
+ this.setupResizeHandler('chart4', this.renderChart4);
+ };
+
+ setupResizeHandler = (chartName, renderMethod) => {
+ const resizeHandler = () => {
+ if (this.echartsInstances[chartName] && !this.isUnmounted) {
+ this.echartsInstances[chartName].resize();
+ }
+ };
+ this.chartResizeHandlers[chartName] = resizeHandler;
+ window.addEventListener('resize', resizeHandler);
+ };
+
+ initAllCharts = () => {
+ if (this.isUnmounted) return;
+ setTimeout(() => {
+ if (this.isUnmounted) return;
+ this.renderChart1();
+ this.renderChart2();
+ this.renderChart3();
+ this.renderChart4();
+ }, 100);
+ };
+
+ disposeAllCharts = () => {
+ Object.keys(this.echartsInstances).forEach((key) => {
+ if (this.echartsInstances[key]) {
+ try {
+ this.echartsInstances[key].dispose();
+ } catch (e) {
+ console.warn(`Dispose chart ${key} error:`, e);
+ }
+ this.echartsInstances[key] = null;
+ }
+ });
+
+ Object.keys(this.chartResizeHandlers).forEach((key) => {
+ if (this.chartResizeHandlers[key]) {
+ window.removeEventListener('resize', this.chartResizeHandlers[key]);
+ }
+ });
+ this.chartResizeHandlers = {};
+ };
+
+ componentDidMount() {
+ this.isUnmounted = false;
+ this.initAllCharts();
+ }
+
+ componentDidUpdate(prevProps) {
+ // 当 trainingSubData 或 trainingSubDataMonth 变化时重新渲染图表
+ if (
+ prevProps.trainingSubData !== this.props.trainingSubData ||
+ prevProps.trainingSubDataMonth !== this.props.trainingSubDataMonth ||
+ prevProps.selectedMonth !== this.props.selectedMonth
+ ) {
+ // this.renderChart1();
+ this.renderChart2();
+ }
+ }
+
+ componentWillUnmount() {
+ this.isUnmounted = true;
+ this.disposeAllCharts();
+ }
+
+ render() {
+ const { selectedMonth = 1, onMonthChange } = this.props;
+ return (
+
+
+ {/* 第一行 - 图表1和图表2 */}
+
+
+
+ {/* 添加月份选择器 */}
+
+ 选择月份:
+
+
+
+
+
+ {/* 第二行 - 图表3和图表4 */}
+
+
+
+ );
+ }
+}
+
+export default TrainingContent;
diff --git a/src/layout/FullScreenInter.js b/src/layout/FullScreenInter.js
index 60d6efa..123da73 100644
--- a/src/layout/FullScreenInter.js
+++ b/src/layout/FullScreenInter.js
@@ -9,6 +9,7 @@ import debounce from 'lodash.debounce';
import storage from '../utils/storage';
import { initFilter } from '../utils/common';
import HomeContent from './FullOther/HomeContent';
+import TrainingContent from './FullOther/TrainingContent'; // 新增导入
const getScale = () => {
const width = 1920,
@@ -38,6 +39,28 @@ class FullScreen extends React.Component {
currentMediaIndex: 0,
announcementList: [],
activeTab: '首页',
+ // 新增:培训数据
+ trainingData: {
+ listNAME: [],
+ YearCount: [],
+ MonthRecordCount: [],
+ MonthPersonCount: [],
+ },
+ // 新增:安全培训页面专用数据
+ trainingSubData: {
+ listNAME: [],
+ YearCount: [],
+ MonthRecordCount: [],
+ MonthPersonCount: [],
+ },
+ trainingSubDataMonth: {
+ listNAME: [],
+ YearCount: [],
+ MonthRecordCount: [],
+ MonthPersonCount: [],
+ },
+ // 新增:当前选择的月份
+ selectedMonth: new Date().getMonth() + 1, // 默认当前月份,1-12
};
this.isUnmounted = false;
}
@@ -58,7 +81,8 @@ class FullScreen extends React.Component {
componentDidMount() {
this.isUnmounted = false;
window.addEventListener('resize', this.setScale);
- this.getHomeDataArray();
+ // this.getHomeDataArray();
+ this.getYearPXData();
this.loadMediaFiles();
this.getAnnouncementData();
@@ -100,6 +124,11 @@ class FullScreen extends React.Component {
handleTabClick = (name) => {
this.setState({ activeTab: name });
+ // 当点击安全培训tab时,获取对应数据
+ if (name === '安全培训') {
+ this.getHomeSESubYearData();
+ this.getHomeSESubYearMonthData();
+ }
};
handleFullscreenChange = () => {
@@ -146,9 +175,112 @@ class FullScreen extends React.Component {
},
});
};
+ getYearPXData = () => {
+ const orgId = storage('lacal').getItem('webOrgId')?.val;
+ const json = initFilter(orgId);
+ this.props.dispatch({
+ type: 'app/getDataByPost',
+ payload: json,
+ url: 'BI/BIHeadSE/SEtrInfo',
+ onComplete: (ret) => {
+ if (ret && !this.isUnmounted) {
+ this.setState({
+ trainingData: {
+ listNAME: ret.listNAME || [],
+ YearCount: ret.YearCount || [],
+ MonthRecordCount: ret.MonthRecordCount || [],
+ MonthPersonCount: ret.MonthPersonCount || [],
+ },
+ });
+ }
+ },
+ });
+ };
+ // 获取安全培训页面数据
+ getHomeSESubYearData = () => {
+ const orgId = storage('lacal').getItem('webOrgId')?.val;
+ const json = initFilter(orgId);
+ const currentYear = new Date().getFullYear(); // 获取当前年份
+ json.Parameter1 = currentYear.toString(); // 设置为当前年份
+ this.props.dispatch({
+ type: 'app/getDataByPost',
+ payload: json,
+ url: 'BI/BIHeadSE/HomeSESubYear',
+ onComplete: (ret) => {
+ if (ret && !this.isUnmounted) {
+ // ret 是数组格式: [{ CName: "邦泰", PCount: 0, RCount: 13 }, ...]
+ const listNAME = ret.map((item) => item.CName);
+ const MonthPersonCount = ret.map((item) => item.PCount); // 培训人次
+ const MonthRecordCount = ret.map((item) => item.RCount); // 培训场次
+ // YearCount 暂时用 PCount 的总和或保持为空数组
+ const YearCount = ret.map((item) => item.PCount);
+
+ this.setState({
+ trainingSubData: {
+ listNAME: listNAME,
+ YearCount: YearCount,
+ MonthRecordCount: MonthRecordCount,
+ MonthPersonCount: MonthPersonCount,
+ },
+ });
+ }
+ },
+ });
+ };
+ // 新增:处理月份变化
+ handleMonthChange = (month) => {
+ this.setState({ selectedMonth: month }, () => {
+ // 重新获取月份数据
+ this.getHomeSESubYearMonthData();
+ });
+ };
+ // 获取安全培训页面数据
+ getHomeSESubYearMonthData = () => {
+ const orgId = storage('lacal').getItem('webOrgId')?.val;
+ const json = initFilter(orgId);
+ const currentYear = new Date().getFullYear(); // 获取当前年份
+ json.Parameter1 = currentYear.toString(); // 设置为当前年份
+ json.Parameter2 = this.state.selectedMonth.toString(); // 月份
+ this.props.dispatch({
+ type: 'app/getDataByPost',
+ payload: json,
+ url: 'BI/BIHeadSE/HomeSESubYear',
+ onComplete: (ret) => {
+ if (ret && !this.isUnmounted) {
+ // ret 是数组格式: [{ CName: "邦泰", PCount: 0, RCount: 13 }, ...]
+ const listNAME = ret.map((item) => item.CName);
+ const MonthPersonCount = ret.map((item) => item.PCount); // 培训人次
+ const MonthRecordCount = ret.map((item) => item.RCount); // 培训场次
+ // YearCount 暂时用 PCount 的总和或保持为空数组
+ const YearCount = ret.map((item) => item.PCount);
+
+ this.setState({
+ trainingSubDataMonth: {
+ listNAME: listNAME,
+ YearCount: YearCount,
+ MonthRecordCount: MonthRecordCount,
+ MonthPersonCount: MonthPersonCount,
+ },
+ });
+ }
+ },
+ });
+ };
renderOtherTabContent = () => {
- const { activeTab } = this.state;
+ const { activeTab, trainingData, trainingSubData, trainingSubDataMonth, selectedMonth } = this.state;
+ // 如果是安全培训,显示专门的培训页面
+ if (activeTab === '安全培训') {
+ return (
+
+ );
+ }
return (
@@ -174,6 +306,7 @@ class FullScreen extends React.Component {
mediaList,
announcementList,
currentMediaIndex,
+ trainingData,
} = this.state;
return (
@@ -237,6 +370,7 @@ class FullScreen extends React.Component {
currentMediaIndex={currentMediaIndex}
onCarouselChange={this.handleCarouselChange}
onDotClick={this.handleDotClick}
+ trainingData={trainingData} // 新增传递
/>
) : (
this.renderOtherTabContent()
diff --git a/src/layout/fullinter.less b/src/layout/fullinter.less
index 0e7a020..7905938 100644
--- a/src/layout/fullinter.less
+++ b/src/layout/fullinter.less
@@ -590,3 +590,86 @@
height: 100%;
}
}
+// fullinter.less - 在文件末尾添加以下样式
+
+// ========== TrainingContent 组件样式 ==========
+.trainingContentWrapper {
+ flex: 1;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ padding: 0 10px 10px 10px;
+ box-sizing: border-box;
+}
+
+.trainingGrid {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+.trainingRow {
+ flex: 1;
+ display: flex;
+ gap: 10px;
+ min-height: 0;
+}
+
+.trainingCard {
+ flex: 1;
+ min-width: 0; // 防止内容溢出
+ background-color: #fff;
+ border-radius: 8px;
+ overflow: hidden;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+ transition: box-shadow 0.3s ease;
+ min-height: 0;
+ display: flex;
+ flex-direction: column;
+
+ position: relative;
+ overflow: hidden;
+
+ &:hover {
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
+ }
+}
+
+.trainingChartContainer {
+ width: 100%;
+ height: 100%;
+ min-height: 0;
+}
+// 月份选择器样式
+.monthSelectorWrapper {
+ position: absolute;
+ top: 15px;
+ left: 20px;
+ z-index: 10;
+ display: flex;
+ align-items: center;
+ background: rgba(255, 255, 255, 0.9);
+ padding: 4px 12px;
+ border-radius: 20px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+}
+
+.monthSelectorLabel {
+ font-size: 13px;
+ color: #333;
+ margin-right: 8px;
+ font-weight: 500;
+}
+
+.monthSelect {
+ .ant-select-selector {
+ border-radius: 16px !important;
+ border-color: #4285f4 !important;
+
+ &:hover {
+ border-color: #66bb6a !important;
+ }
+ }
+}