From 42255215598e9d08b6db12351f486777430e4e6b Mon Sep 17 00:00:00 2001 From: yupeng Date: Tue, 30 Sep 2025 11:45:21 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=AE=89=E5=85=A8=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A=E8=AE=B8=E5=8F=AF=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/routes.js | 6 + src/assets/img/bookDark.svg | 3 + src/assets/img/bookLight.svg | 3 + src/assets/img/licenseLight.svg | 4 + src/locales/zh-CN/menu.js | 1 + .../nav_system_content/SystemContentList.js | 23 +- .../SpecialOperationPermit.js | 501 ++++++++++++++++++ .../SpecialOperationPermit.less | 207 ++++++++ src/pages/topnavbar/TopNavBar.js | 5 + 9 files changed, 748 insertions(+), 5 deletions(-) create mode 100644 src/assets/img/bookDark.svg create mode 100644 src/assets/img/bookLight.svg create mode 100644 src/assets/img/licenseLight.svg create mode 100644 src/pages/special_operation_permit/SpecialOperationPermit.js create mode 100644 src/pages/special_operation_permit/SpecialOperationPermit.less diff --git a/config/routes.js b/config/routes.js index 3eac525..8f63b3d 100644 --- a/config/routes.js +++ b/config/routes.js @@ -113,6 +113,12 @@ export default [ path:'/topnavbar00/hrefficiency/personnellocation', name: 'personnellocation', component: './personnel_location/PersonnelLocation', + }, + // 特殊作业许可 + { + path:'/topnavbar00/hrefficiency/specialoperationpermit', + name: 'specialoperationpermit', + component: './special_operation_permit/SpecialOperationPermit', } ], }, diff --git a/src/assets/img/bookDark.svg b/src/assets/img/bookDark.svg new file mode 100644 index 0000000..86b68e3 --- /dev/null +++ b/src/assets/img/bookDark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/img/bookLight.svg b/src/assets/img/bookLight.svg new file mode 100644 index 0000000..a9e31d3 --- /dev/null +++ b/src/assets/img/bookLight.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/img/licenseLight.svg b/src/assets/img/licenseLight.svg new file mode 100644 index 0000000..6805ba4 --- /dev/null +++ b/src/assets/img/licenseLight.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/locales/zh-CN/menu.js b/src/locales/zh-CN/menu.js index fbd61ec..1d5ab36 100644 --- a/src/locales/zh-CN/menu.js +++ b/src/locales/zh-CN/menu.js @@ -18,6 +18,7 @@ export default { 'menu.topnavbar00.hrefficiency.hiddentrouble': '隐患排查', 'menu.topnavbar00.hrefficiency.safetraining': '安全教育培训', 'menu.topnavbar00.hrefficiency.personnellocation': '人员定位', + 'menu.topnavbar00.hrefficiency.specialoperationpermit': '特殊作业许可', 'menu.topnavbar00.sysmenu': '系统配置', 'menu.topnavbar00.sysmenu.system': '系统管理', diff --git a/src/pages/nav_system_content/SystemContentList.js b/src/pages/nav_system_content/SystemContentList.js index eeaf4be..a63afc7 100644 --- a/src/pages/nav_system_content/SystemContentList.js +++ b/src/pages/nav_system_content/SystemContentList.js @@ -17,9 +17,12 @@ import book from '@/assets/img/book.svg' import danger from '@/assets/img/danger.svg' import danger1 from '@/assets/img/danger1.svg' import license from '@/assets/img/license.svg' +import licenseLight from '@/assets/img/licenseLight.svg' import people from '@/assets/img/people.svg' import risk from '@/assets/img/risk.svg' import safeEducationLight from '@/assets/img/safeEducationLight.svg' +import bookDark from '@/assets/img/bookDark.svg' +import bookLight from '@/assets/img/bookLight.svg' import personnelPosition2 from '@/assets/img/personnelPosition2.svg' import { CustomBreadcrumb } from '@/components/GlobalComponent' @@ -119,7 +122,7 @@ const SystemContentList = (props) => { "key": "/topnavbar00/hrefficiency/allstaffuph", "label": "全员效率监控" }, - { + { "path": "/topnavbar00/hrefficiency/hiddentrouble", icon: 工时仪表盘, "key": "/topnavbar00/hrefficiency/hiddentrouble", @@ -127,7 +130,7 @@ const SystemContentList = (props) => { }, { "path": "/topnavbar00/hrefficiency/safetraining", - icon: 安全教育培训, + icon: 安全教育培训, "key": "/topnavbar00/hrefficiency/safetraining", "label": "安全教育培训" }, @@ -137,6 +140,12 @@ const SystemContentList = (props) => { "key": "/topnavbar00/hrefficiency/personnellocation", "label": "人员定位" }, + { + "path": "/topnavbar00/hrefficiency/specialoperationpermit", + icon: 特殊作业许可, + "key": "/topnavbar00/hrefficiency/specialoperationpermit", + "label": "特殊作业许可" + }, { "path": "/topnavbar00/hrefficiency/system", icon: 工时仪表盘, @@ -382,14 +391,18 @@ const SystemContentList = (props) => { else if (item.key === '/topnavbar00/hrefficiency/staffsheet' && typeof danger1 !== 'undefined') { iconSrc = danger1; } - // 安全教育培训激活态使用safeEducationLight - else if (item.key === '/topnavbar00/hrefficiency/safetraining' && typeof safeEducationLight !== 'undefined') { - iconSrc = safeEducationLight; + // 安全教育培训激活态使用bookLight + else if (item.key === '/topnavbar00/hrefficiency/safetraining' && typeof bookLight !== 'undefined') { + iconSrc = bookLight; } // 人员定位激活态使用personnelPosition2 else if (item.key === '/topnavbar00/hrefficiency/personnellocation' && typeof personnelPosition2 !== 'undefined') { iconSrc = personnelPosition2; } + // 特殊作业许可激活态使用licenseLight + else if (item.key === '/topnavbar00/hrefficiency/specialoperationpermit' && typeof licenseLight !== 'undefined') { + iconSrc = licenseLight; + } } icon = , + status: '正常', + color: '#52c41a' + }, + { + title: '技能合格率', + count: '23%', + icon: , + status: '待提升', + color: '#ff7875' + }, + { + title: '作业完成率', + count: '67%', + icon: , + status: '正常', + color: '#52c41a' + }, + { + title: '风险防控数', + count: 16, + icon: , + status: '较上月持平', + color: '#1890ff' + } +]; + +// 模拟数据 - 趋势分析图表 +const trendAnalysisData = { + title: { + text: '趋势分析', + left: 'center', + }, + tooltip: { + trigger: 'axis', + }, + legend: { + data: ['技能合格率', '作业完成率', '风险防控数'], + bottom: 0, + }, + grid: { + left: '3%', + right: '4%', + bottom: '15%', + containLabel: true, + }, + xAxis: { + type: 'category', + boundaryGap: false, + data: ['10-01', '10-02', '10-03', '10-04', '10-05', '10-06', '10-07'], + }, + yAxis: { + type: 'value', + max: 100, + }, + series: [ + { + name: '技能合格率', + type: 'line', + smooth: true, + showSymbol: false, + data: [25, 23, 28, 26, 30, 23, 25], + itemStyle: { color: '#ff7a75' }, + areaStyle: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [{ + offset: 0, color: 'rgba(255, 122, 117, 0.8)' + }, { + offset: 1, color: 'rgba(255, 122, 117, 0.1)' + }] + } + } + }, + { + name: '作业完成率', + type: 'line', + smooth: true, + showSymbol: false, + data: [65, 68, 70, 65, 62, 67, 69], + itemStyle: { color: '#9254de' }, + areaStyle: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [{ + offset: 0, color: 'rgba(146, 84, 222, 0.8)' + }, { + offset: 1, color: 'rgba(146, 84, 222, 0.1)' + }] + } + } + }, + { + name: '风险防控数', + type: 'line', + smooth: true, + showSymbol: false, + data: [15, 18, 16, 14, 17, 16, 19], + itemStyle: { color: '#40a9ff' }, + areaStyle: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [{ + offset: 0, color: 'rgba(64, 169, 255, 0.8)' + }, { + offset: 1, color: 'rgba(64, 169, 255, 0.1)' + }] + } + } + } + ], +}; + +// 模拟数据 - 作业类型分布图表 +const operationTypeData = { + title: { + text: '作业类型分布', + left: 'center', + }, + tooltip: { + trigger: 'item', + }, + legend: { + orient: 'vertical', + left: 'left', + data: ['动火作业', '高处作业', '有限空间作业', '临时用电', '断路作业'], + }, + series: [ + { + name: '作业类型', + type: 'pie', + radius: '60%', + data: [ + { + value: 35, + name: '动火作业', + itemStyle: { color: '#1890ff' } + }, + { + value: 25, + name: '高处作业', + itemStyle: { color: '#52c41a' } + }, + { + value: 20, + name: '有限空间作业', + itemStyle: { color: '#faad14' } + }, + { + value: 15, + name: '临时用电', + itemStyle: { color: '#f5222d' } + }, + { + value: 5, + name: '断路作业', + itemStyle: { color: '#722ed1' } + } + ], + emphasis: { + itemStyle: { + shadowBlur: 10, + shadowOffsetX: 0, + shadowColor: 'rgba(0, 0, 0, 0.5)', + }, + }, + }, + ], +}; + +// 模拟数据 - 作业列表数据 +const operationListData = [ + { + key: '1', + operationType: '动火作业', + operationNo: 'DH-20230906-002', + applicant: '张小龙', + location: '2号车间', + startTime: '2025-09-03 03:23:12', + warningDept: '生产一部', + warningType: '气体浓度超标', + riskLevel: '高风险', + status: '进行中', + }, + { + key: '2', + operationType: '高处作业', + operationNo: 'GC-20230906-002', + applicant: '李小龙', + location: '2号车间', + startTime: '2025-09-03 03:23:12', + warningDept: '生产一部', + warningType: '气体浓度超标', + riskLevel: '较高风险', + status: '未开始', + }, + { + key: '3', + operationType: '有限空间作业', + operationNo: 'YX-20230906-002', + applicant: '张小虎', + location: '2号车间', + startTime: '2025-09-03 03:23:12', + warningDept: '生产一部', + warningType: '气体浓度超标', + riskLevel: '中风险', + status: '未开始', + }, + { + key: '4', + operationType: '临时用电', + operationNo: 'LS-20230906-002', + applicant: '张小龙', + location: '2号车间', + startTime: '2025-09-03 03:23:12', + warningDept: '生产一部', + warningType: '气体浓度超标', + riskLevel: '低风险', + status: '进行中', + }, + { + key: '5', + operationType: '动火作业', + operationNo: 'DH-20230906-002', + applicant: '张小龙', + location: '2号车间', + startTime: '2025-09-03 03:23:12', + warningDept: '生产一部', + warningType: '气体浓度超标', + riskLevel: '高风险', + status: '进行中', + }, +]; + +// 状态标签渲染 +const renderStatusTag = (status) => { + switch (status) { + case '进行中': + return {status}; + case '未开始': + return {status}; + case '已完成': + return {status}; + case '已暂停': + return {status}; + default: + return {status}; + } +}; + +// 风险等级标签渲染 +const renderRiskLevelTag = (level) => { + switch (level) { + case '高风险': + return {level}; + case '较高风险': + return {level}; + case '中风险': + return {level}; + case '低风险': + return {level}; + default: + return {level}; + } +}; + +const SpecialOperationPermit = () => { + const [currentPage, setCurrentPage] = useState(1); + const [pageSize, setPageSize] = useState(10); + const [searchText, setSearchText] = useState(''); + const [filteredData, setFilteredData] = useState(operationListData); + + // 搜索处理 + const handleSearch = (value) => { + setSearchText(value); + const filtered = operationListData.filter(item => + item.operationNo.includes(value) || + item.applicant.includes(value) || + item.location.includes(value) + ); + setFilteredData(filtered); + setCurrentPage(1); + }; + + // 处理操作按钮 + const handleViewDetails = (record) => { + // 查看详情逻辑 + console.log('查看详情:', record); + }; + + const handleApprove = (record) => { + // 审批逻辑 + console.log('审批:', record); + }; + + return ( +
+ {/* 顶部统计卡片 */} + + {statsData.map((stat, index) => ( + + +
+
+ {React.cloneElement(stat.icon, { style: { color: stat.color } })} +
+
+
{stat.title}
+
{stat.count}
+
{stat.status}
+
+
+
+ + ))} +
+ + {/* 中间图表区域 */} + + {/* 监控预警 */} + + +
+
+
+ +
+
+
高风险气体超标
+
测试气体浓度超出安全标准值25.0%
+
5分钟前
+
+
+ +
+
+ +
+
+
高温作业防护缺失
+
作业人员未按规定佩戴防护装备
+
30分钟前
+
+
+ +
+
+ +
+
+
受限空间超时
+
作业人员在受限空间内停留超过规定时间
+
60分钟前
+
+
+ +
+
+ +
+
+
受限空间作业超时
+
受限空间作业已超规定时间30分钟
+
90分钟前
+
+
+
+
+ + + {/* 趋势分析图表 */} + + + + + + {/* 作业类型分布图表 */} + + + + + +
+ + {/* 作业列表区域 */} + + {/* 搜索和筛选 */} +
+ + } + allowClear + style={{ width: 300 }} + onChange={(e) => handleSearch(e.target.value)} + /> + + + + +
+ + {/* 作业列表表格 */} + `共 ${total} 条 ${range[0]}-${range[1]}` + }} + rowKey="key" + size="small" + className={styles.operationTable} + > + + + + + + + + renderRiskLevelTag(text)} + /> + renderStatusTag(text)} + /> + ( + + + + + )} + /> +
+
+
+ ); +}; + +export default SpecialOperationPermit; \ No newline at end of file diff --git a/src/pages/special_operation_permit/SpecialOperationPermit.less b/src/pages/special_operation_permit/SpecialOperationPermit.less new file mode 100644 index 0000000..bba7f2c --- /dev/null +++ b/src/pages/special_operation_permit/SpecialOperationPermit.less @@ -0,0 +1,207 @@ +/* 主容器样式 */ +.container { + padding: 16px; + background-color: #f0f2f5; +} + +/* 统计卡片样式 */ +.statsRow { + margin-bottom: 16px; +} + +.statCard { + background-color: #fff; + border-radius: 4px; + border: 1px solid #e8e8e8; + overflow: hidden; + transition: all 0.3s; + height: 100%; + + &:hover { + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + transform: translateY(-2px); + } +} + +.statContent { + display: flex; + align-items: center; + padding: 16px; +} + +.statIcon { + width: 48px; + height: 48px; + display: flex; + align-items: center; + justify-content: center; + background-color: #e6f7ff; + border-radius: 4px; + font-size: 24px; + margin-right: 16px; +} + +.statInfo { + flex: 1; +} + +.statTitle { + font-size: 14px; + color: #666; + margin-bottom: 4px; +} + +.statCount { + font-size: 24px; + font-weight: 500; + color: #333; + margin-bottom: 4px; +} + +.statStatus { + font-size: 12px; + font-weight: 500; +} + +/* 图表区域样式 */ +.chartRow { + margin-bottom: 16px; +} + +.chartCard { + margin-bottom: 16px; + height: 360px; + overflow: hidden; +} + +/* 监控预警样式 */ +.alarmList { + height: 100%; + overflow-y: auto; + padding: 8px 0; + + &::-webkit-scrollbar { + width: 4px; + } + + &::-webkit-scrollbar-thumb { + background: #d9d9d9; + border-radius: 2px; + } + + &::-webkit-scrollbar-track { + background: #f5f5f5; + } +} + +.alarmItem { + display: flex; + align-items: flex-start; + padding: 12px 16px; + margin-bottom: 8px; + background: #fafafa; + border-radius: 6px; + cursor: pointer; + transition: all 0.3s; + + &:hover { + background: #f0f0f0; + transform: translateX(4px); + } + + &:last-child { + margin-bottom: 0; + } +} + +.alarmIcon { + width: 32px; + height: 32px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + margin-right: 12px; + flex-shrink: 0; +} + +.alarmInfo { + flex: 1; + min-width: 0; +} + +.alarmTitle { + font-size: 14px; + font-weight: 500; + color: #333; + margin-bottom: 4px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.alarmDesc { + font-size: 12px; + color: #666; + margin-bottom: 4px; + line-height: 1.4; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; +} + +.alarmTime { + font-size: 11px; + color: #999; +} + +.chart { + height: 300px; +} + +/* 表格区域样式 */ +.tableCard { + background-color: #fff; + border-radius: 4px; +} + +.searchFilter { + margin-bottom: 16px; + padding-top: 16px; + display: flex; + align-items: center; + flex-wrap: wrap; +} + +.operationTable { + .ant-table-thead > tr > th { + background-color: #fafafa; + border-bottom: 1px solid #f0f0f0; + } + + .ant-table-tbody > tr > td { + border-bottom: 1px solid #f0f0f0; + } +} + +/* 响应式调整 */ +@media (max-width: 768px) { + .container { + padding: 8px; + } + + .searchFilter { + flex-direction: column; + align-items: stretch; + } + + .searchFilter > * { + margin-bottom: 8px !important; + } + + .chart { + height: 250px; + } +} \ No newline at end of file diff --git a/src/pages/topnavbar/TopNavBar.js b/src/pages/topnavbar/TopNavBar.js index 7dbad9a..008ed3c 100644 --- a/src/pages/topnavbar/TopNavBar.js +++ b/src/pages/topnavbar/TopNavBar.js @@ -63,6 +63,11 @@ const menuItem = [ key: '/topnavbar00/hrefficiency/safetraining', // icon: , }, + { + label: '特殊作业许可', + key: '/topnavbar00/hrefficiency/specialoperationpermit', + // icon: , + }, { label: '系统管理', key: '/topnavbar00/hrefficiency/system',