Compare commits
6 Commits
36475743c9
...
7cfb666f82
| Author | SHA1 | Date |
|---|---|---|
|
|
7cfb666f82 | |
|
|
60d3bad25f | |
|
|
4ac5f70080 | |
|
|
83d69416e1 | |
|
|
194b0dbff1 | |
|
|
4f64335773 |
|
|
@ -164,13 +164,16 @@ const Maintenance = ({ year }) => {
|
||||||
|
|
||||||
chartInstance.current.setOption(option);
|
chartInstance.current.setOption(option);
|
||||||
|
|
||||||
const handleResize = () => {
|
const resizeObserver = new ResizeObserver(() => {
|
||||||
chartInstance.current?.resize();
|
chartInstance.current && chartInstance.current.resize();
|
||||||
};
|
});
|
||||||
window.addEventListener('resize', handleResize);
|
|
||||||
|
if (chartRef.current) {
|
||||||
|
resizeObserver.observe(chartRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('resize', handleResize);
|
resizeObserver.disconnect();
|
||||||
};
|
};
|
||||||
}, [activeIndex, selectedPieItem, startAngle, chartData]);
|
}, [activeIndex, selectedPieItem, startAngle, chartData]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import React, { useEffect, useRef,useState } from 'react';
|
import React, { useEffect, useRef,useState } from 'react';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
import * as echarts from 'echarts';
|
import * as echarts from 'echarts';
|
||||||
import arrowIcon from '@/assets/images/card/arrow.png';
|
import arrowIcon from '@/assets/images/card/arrow.png';
|
||||||
import glfwBg from '@/assets/images/business/glfw.png';
|
import glfwBg from '@/assets/images/business/glfw.png';
|
||||||
|
|
@ -9,6 +10,7 @@ import { httpget } from '@/utils/request';
|
||||||
import './index.less';
|
import './index.less';
|
||||||
|
|
||||||
const ReservoirDemarcation = () => {
|
const ReservoirDemarcation = () => {
|
||||||
|
const isFullScreen = useSelector(s => s.runtime.isFullScreen);
|
||||||
const chartRef = useRef(null);
|
const chartRef = useRef(null);
|
||||||
const chartInstance = useRef(null);
|
const chartInstance = useRef(null);
|
||||||
const [info, setInfo] = useState({
|
const [info, setInfo] = useState({
|
||||||
|
|
@ -49,8 +51,8 @@ const ReservoirDemarcation = () => {
|
||||||
min: 0,
|
min: 0,
|
||||||
max: maxVal,
|
max: maxVal,
|
||||||
splitNumber: 40,
|
splitNumber: 40,
|
||||||
radius: '125%',
|
radius: isFullScreen ? '90%' : '125%',
|
||||||
center: ['50%', '65%'],
|
center: isFullScreen ? ['50%', '55%'] : ['50%', '65%'],
|
||||||
axisLine: {
|
axisLine: {
|
||||||
show: true,
|
show: true,
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
|
|
@ -106,16 +108,18 @@ const ReservoirDemarcation = () => {
|
||||||
|
|
||||||
chartInstance.current.setOption(option);
|
chartInstance.current.setOption(option);
|
||||||
|
|
||||||
const handleResize = () => {
|
const resizeObserver = new ResizeObserver(() => {
|
||||||
chartInstance.current && chartInstance.current.resize();
|
chartInstance.current && chartInstance.current.resize();
|
||||||
};
|
});
|
||||||
|
|
||||||
window.addEventListener('resize', handleResize);
|
if (chartRef.current) {
|
||||||
|
resizeObserver.observe(chartRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('resize', handleResize);
|
resizeObserver.disconnect();
|
||||||
};
|
};
|
||||||
}, [info]);
|
}, [info, isFullScreen]);
|
||||||
|
|
||||||
// Clean up chart instance on unmount
|
// Clean up chart instance on unmount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.location-text {
|
.location-text {
|
||||||
font-size: 14px;
|
font-size: 16px;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -98,14 +98,16 @@ const SafetyHazard = ({ year }) => {
|
||||||
|
|
||||||
chartInstance.current.setOption(option);
|
chartInstance.current.setOption(option);
|
||||||
|
|
||||||
const handleResize = () => {
|
const resizeObserver = new ResizeObserver(() => {
|
||||||
chartInstance.current && chartInstance.current.resize();
|
chartInstance.current && chartInstance.current.resize();
|
||||||
};
|
});
|
||||||
|
|
||||||
window.addEventListener('resize', handleResize);
|
if (chartRef.current) {
|
||||||
|
resizeObserver.observe(chartRef.current);
|
||||||
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('resize', handleResize);
|
resizeObserver.disconnect();
|
||||||
};
|
};
|
||||||
}, [info]);
|
}, [info]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: rgba(255, 255, 255, 0.8);
|
color: rgba(255, 255, 255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
import { Table } from 'antd';
|
import { Table } from 'antd';
|
||||||
import CommonModal from '@/views/Home/components/UI/CommonModal';
|
import CommonModal from '@/views/Home/components/UI/CommonModal';
|
||||||
import arrowIcon from '@/assets/images/card/arrow.png';
|
import arrowIcon from '@/assets/images/card/arrow.png';
|
||||||
|
|
@ -13,6 +14,7 @@ import VideoList from '../ModalComponents/VideoList'
|
||||||
import UAVModal from '../ModalComponents/UAVModal';
|
import UAVModal from '../ModalComponents/UAVModal';
|
||||||
|
|
||||||
const AllWeatherControl = () => {
|
const AllWeatherControl = () => {
|
||||||
|
const isFullScreen = useSelector(s => s.runtime.isFullScreen);
|
||||||
const [reservoirItem, setReservoirItem] = useState({})
|
const [reservoirItem, setReservoirItem] = useState({})
|
||||||
const [rainList, setRainList] = useState([])
|
const [rainList, setRainList] = useState([])
|
||||||
const [detailVisible, setDetailVisible] = useState(false)
|
const [detailVisible, setDetailVisible] = useState(false)
|
||||||
|
|
@ -102,7 +104,7 @@ const AllWeatherControl = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="all-weather-control">
|
<div className={`all-weather-control ${isFullScreen ? 'full-screen' : ''}`}>
|
||||||
{/* 雨情 Section */}
|
{/* 雨情 Section */}
|
||||||
<div className="section rain-section">
|
<div className="section rain-section">
|
||||||
<div className="section-header">
|
<div className="section-header">
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import React,{useState,useEffect} from 'react';
|
import React,{useState,useEffect} from 'react';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
import smallCard from '@/assets/images/card/smallCard.png';
|
import smallCard from '@/assets/images/card/smallCard.png';
|
||||||
import apiurl from '@/service/apiurl';
|
import apiurl from '@/service/apiurl';
|
||||||
import { httpget } from '@/utils/request';
|
import { httpget } from '@/utils/request';
|
||||||
|
|
@ -6,6 +7,7 @@ import PdfView from '@/views/Home/components/UI/PdfView';
|
||||||
import './index.less';
|
import './index.less';
|
||||||
|
|
||||||
const ManagementCycle = () => {
|
const ManagementCycle = () => {
|
||||||
|
const isFullScreen = useSelector(s => s.runtime.isFullScreen);
|
||||||
const [info, setInfo] = useState({})
|
const [info, setInfo] = useState({})
|
||||||
const [pdfVisible, setPdfVisible] = useState(false);
|
const [pdfVisible, setPdfVisible] = useState(false);
|
||||||
const [pdfConfig, setPdfConfig] = useState({ title: '', url: '', fileId: '' });
|
const [pdfConfig, setPdfConfig] = useState({ title: '', url: '', fileId: '' });
|
||||||
|
|
@ -63,7 +65,7 @@ const ManagementCycle = () => {
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="management-cycle">
|
<div className={`management-cycle ${isFullScreen ? 'full-screen' : ''}`}>
|
||||||
<div className="card-grid">
|
<div className="card-grid">
|
||||||
{data.map((item, index) => (
|
{data.map((item, index) => (
|
||||||
<div
|
<div
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
import React,{useMemo} from 'react';
|
import React,{useMemo} from 'react';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
import arrowIcon from '@/assets/images/card/arrow.png';
|
import arrowIcon from '@/assets/images/card/arrow.png';
|
||||||
import qysIcon from '@/assets/images/business/qys.png';
|
import qysIcon from '@/assets/images/business/qys.png';
|
||||||
import textBg from '@/assets/images/card/textbg.png';
|
import textBg from '@/assets/images/card/textbg.png';
|
||||||
import './index.less';
|
import './index.less';
|
||||||
|
|
||||||
const MonitoringElements = ({ data }) => {
|
const MonitoringElements = ({ data }) => {
|
||||||
|
const isFullScreen = useSelector(s => s.runtime.isFullScreen);
|
||||||
const reservoirInfo = [
|
const reservoirInfo = [
|
||||||
{ label: '总库容(万m³):', value: '', highlight: false,type:1 },
|
{ label: '总库容(万m³):', value: '', highlight: false,type:1 },
|
||||||
{ label: '承雨面积(km²):', value: '', highlight: true,type:2 },
|
{ label: '承雨面积(km²):', value: '', highlight: true,type:2 },
|
||||||
|
|
@ -42,7 +44,7 @@ const MonitoringElements = ({ data }) => {
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="monitoring-elements">
|
<div className={`monitoring-elements ${isFullScreen ? 'full-screen' : ''}`}>
|
||||||
{/* Section 1: 水库信息 */}
|
{/* Section 1: 水库信息 */}
|
||||||
<div className="section">
|
<div className="section">
|
||||||
<div className="section-title">
|
<div className="section-title">
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import React,{useState,useEffect, useMemo} from 'react';
|
import React,{useState,useEffect, useMemo} from 'react';
|
||||||
|
import { useSelector } from 'react-redux';
|
||||||
import { UserOutlined } from '@ant-design/icons';
|
import { UserOutlined } from '@ant-design/icons';
|
||||||
import arrowIcon from '@/assets/images/card/arrow.png';
|
import arrowIcon from '@/assets/images/card/arrow.png';
|
||||||
import textBg from '@/assets/images/card/textbg.png';
|
import textBg from '@/assets/images/card/textbg.png';
|
||||||
|
|
@ -6,6 +7,7 @@ import moment from 'moment';
|
||||||
import './index.less';
|
import './index.less';
|
||||||
|
|
||||||
const SupervisionCoverage = ({ data }) => {
|
const SupervisionCoverage = ({ data }) => {
|
||||||
|
const isFullScreen = useSelector(s => s.runtime.isFullScreen);
|
||||||
const responsibles = [
|
const responsibles = [
|
||||||
{ label: '地方政府责任人:', value: '-', type: 'gov' },
|
{ label: '地方政府责任人:', value: '-', type: 'gov' },
|
||||||
{ label: '主管部门责任人:', value: '-', type: 'dept' },
|
{ label: '主管部门责任人:', value: '-', type: 'dept' },
|
||||||
|
|
@ -43,7 +45,7 @@ const SupervisionCoverage = ({ data }) => {
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="supervision-coverage">
|
<div className={`supervision-coverage ${isFullScreen ? 'full-screen' : ''}`}>
|
||||||
{/* Section 1: 责任人信息 */}
|
{/* Section 1: 责任人信息 */}
|
||||||
<div className="section">
|
<div className="section">
|
||||||
<div className="section-title">
|
<div className="section-title">
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
.siquan-view {
|
.siquan-view {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 0;
|
height: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@import "../common.less";
|
@import "../common.less";
|
||||||
|
|
|
||||||
|
|
@ -83,15 +83,25 @@ const FloodPreview = ({setPlanData}) => {
|
||||||
options={options}
|
options={options}
|
||||||
value={planId}
|
value={planId}
|
||||||
allowClear={false}
|
allowClear={false}
|
||||||
onChange={(e)=>setPlanId(e)}
|
onChange={(e)=>{
|
||||||
|
setPlanId(e)
|
||||||
|
setRadio(1)
|
||||||
|
setPlanData(null)
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='flood-preview-section-radio'>
|
<div className='flood-preview-section-radio' onClick={()=>{
|
||||||
<Radio checked={radio===2} onClick={()=>setRadio(2)}/>
|
setRadio(2)
|
||||||
|
setPlanData(null)
|
||||||
|
}}>
|
||||||
|
<Radio checked={radio===2}/>
|
||||||
24小时降雨400mm(50年一遇)
|
24小时降雨400mm(50年一遇)
|
||||||
</div>
|
</div>
|
||||||
<div className='flood-preview-section-radio'>
|
<div className='flood-preview-section-radio' onClick={()=>{
|
||||||
<Radio checked={radio===3} onClick={()=>setRadio(3)}/>
|
setRadio(3)
|
||||||
|
setPlanData(null)
|
||||||
|
}}>
|
||||||
|
<Radio checked={radio===3}/>
|
||||||
24小时降雨500mm(100年一遇)
|
24小时降雨500mm(100年一遇)
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
.flood-preview-section{
|
.flood-preview-section{
|
||||||
background: red;
|
height: 100%;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
.section-title {
|
.section-title {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 5px;
|
||||||
|
|
||||||
.arrow-icon {
|
.arrow-icon {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
|
|
||||||
.forecast-section-countBox {
|
.forecast-section-countBox {
|
||||||
width: 33%;
|
width: 33%;
|
||||||
height: 65px;
|
height: 60px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
@ -82,7 +82,7 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 20px;
|
margin-top: 5px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
}
|
}
|
||||||
.uav-button {
|
.uav-button {
|
||||||
|
|
|
||||||
|
|
@ -19,18 +19,18 @@ const Page = ({data=[]}) => {
|
||||||
},
|
},
|
||||||
grid: [
|
grid: [
|
||||||
{
|
{
|
||||||
top: '20%',
|
top: '25%',
|
||||||
left: '12%',
|
left: '12%',
|
||||||
right: '10%',
|
right: '10%',
|
||||||
width: '80%',
|
width: '80%',
|
||||||
height: '32%'
|
height: '25%'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
bottom: '5%',
|
bottom: '8%',
|
||||||
left: '12%',
|
left: '12%',
|
||||||
right: '10%',
|
right: '10%',
|
||||||
width: '80%',
|
width: '80%',
|
||||||
height: '32%'
|
height: '30%'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
legend: {
|
legend: {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
.forecast-section{
|
.forecast-section{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
.forecast-section-time{
|
.forecast-section-time{
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
|
|
@ -16,7 +17,7 @@
|
||||||
|
|
||||||
.forecast-section-countBox {
|
.forecast-section-countBox {
|
||||||
width: 25%;
|
width: 25%;
|
||||||
height: 65px;
|
height: 60px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
@ -61,7 +62,7 @@
|
||||||
|
|
||||||
.echarts-for-react {
|
.echarts-for-react {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 400px!important;
|
height: 330px!important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -7,7 +7,10 @@
|
||||||
|
|
||||||
.left {
|
.left {
|
||||||
.card-1 { flex: 5; }
|
.card-1 { flex: 5; }
|
||||||
.card-2 { flex: 3; }
|
.card-2 {
|
||||||
|
flex: 4;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.right {
|
.right {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,133 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Descriptions, Image } from 'antd';
|
||||||
|
import { DownloadOutlined, EyeOutlined } from '@ant-design/icons';
|
||||||
|
import CommonModal from '@/views/Home/components/UI/CommonModal';
|
||||||
|
import PdfView from '@/views/Home/components/UI/PdfView';
|
||||||
|
import { download } from '@/utils/tools';
|
||||||
|
import './TrainingModal.less';
|
||||||
|
|
||||||
|
const TrainingModal = ({ visible, onClose, data }) => {
|
||||||
|
const typeInfo = {
|
||||||
|
1:"水利",
|
||||||
|
2:"岗前培训",
|
||||||
|
3:"在岗培训",
|
||||||
|
4:"政治学习教育",
|
||||||
|
5:"其他",
|
||||||
|
}
|
||||||
|
const [pdfInfo, setPdfInfo] = useState({ visible: false, title: '', fileId: '' });
|
||||||
|
const [previewImage, setPreviewImage] = useState('');
|
||||||
|
const [previewVisible, setPreviewVisible] = useState(false);
|
||||||
|
|
||||||
|
if (!data) return null;
|
||||||
|
|
||||||
|
const commonLabelStyle = {
|
||||||
|
width: '150px',
|
||||||
|
textAlign: 'right',
|
||||||
|
};
|
||||||
|
|
||||||
|
const descriptionStyle = {
|
||||||
|
marginBottom: '20px',
|
||||||
|
};
|
||||||
|
|
||||||
|
const getDescriptionsProps = (title) => ({
|
||||||
|
title: <span style={{ color: '#1890ff', fontSize: '16px', fontWeight: 'bold', borderLeft: '4px solid #1890ff', paddingLeft: '10px' }}>{title}</span>,
|
||||||
|
column: 2,
|
||||||
|
bordered: true,
|
||||||
|
size: 'small',
|
||||||
|
className: 'engineering-descriptions',
|
||||||
|
labelStyle: commonLabelStyle,
|
||||||
|
style: descriptionStyle,
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleFilePreview = (file) => {
|
||||||
|
const extension = file.fileName.split('.').pop().toLowerCase();
|
||||||
|
const downloadUrl = `/gunshiApp/ss/personnelPlan/file/download/${file.fileId}`;
|
||||||
|
|
||||||
|
if (['jpg', 'jpeg', 'png', 'gif', 'bmp'].includes(extension)) {
|
||||||
|
setPreviewImage(downloadUrl);
|
||||||
|
setPreviewVisible(true);
|
||||||
|
} else if (extension === 'pdf') {
|
||||||
|
setPdfInfo({
|
||||||
|
visible: true,
|
||||||
|
title: file.fileName,
|
||||||
|
fileId: file.fileId
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
download(downloadUrl);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getTrainingType = (type) => {
|
||||||
|
const typeName = typeInfo[type]
|
||||||
|
return typeName;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CommonModal
|
||||||
|
visible={visible}
|
||||||
|
onClose={onClose}
|
||||||
|
title={data.content || "培训详情"}
|
||||||
|
width={1000}
|
||||||
|
>
|
||||||
|
<div className="training-modal-content" style={{ padding: '20px', height: '600px', overflowY: 'auto' }}>
|
||||||
|
<Descriptions {...getDescriptionsProps('基本信息')}>
|
||||||
|
<Descriptions.Item label="培训计划">{data.name || '-'}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="培训分类">{getTrainingType(data.type) || '-'}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="培训日期">{data.stm || '-'}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="标题名称">{data.name || '-'}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="培训时段">{data.stm && data.etm ? `${data.stm} 至 ${data.etm}` : '-'}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="培训时长(小时)">{data.num || '-'}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="培训地点">{data.addr || '-'}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="主办单位">{data.unit || '-'}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="培训内容" span={2}>{data.content || '-'}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="培训范围" span={2}>{data.scope || '-'}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="参训人员">{data.trainees || '-'}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="参训人数">{data.numPeople || '-'}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="填报人">{data.applicant || '-'}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="登记日期">{data.regDate || '-'}</Descriptions.Item>
|
||||||
|
</Descriptions>
|
||||||
|
|
||||||
|
<Descriptions {...getDescriptionsProps('其他信息')} column={1}>
|
||||||
|
<Descriptions.Item label="附件">
|
||||||
|
<div className="file-list" style={{ display: 'flex', flexWrap: 'wrap', gap: '10px' }}>
|
||||||
|
{data.files && data.files.length > 0 ? data.files.map((file, index) => (
|
||||||
|
<div key={index} className="file-item" style={{ width: '240px', padding: '8px', borderRadius: '4px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||||
|
<span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', marginRight: '5px', flex: 1 }} title={file.fileName}>{file.fileName}</span>
|
||||||
|
<div style={{ flexShrink: 0 }}>
|
||||||
|
<EyeOutlined onClick={() => handleFilePreview(file)} style={{ cursor: 'pointer', marginRight: '8px', color: '#1890ff', fontSize: '16px' }} title="预览" />
|
||||||
|
<DownloadOutlined onClick={() => download(`/gunshiApp/ss/personnelPlan/file/download/${file.fileId}`)} style={{ cursor: 'pointer', color: '#1890ff', fontSize: '16px' }} title="下载" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)) : <span style={{ color: '#rgba(255,255,255,0.5)' }}>无附件</span>}
|
||||||
|
</div>
|
||||||
|
</Descriptions.Item>
|
||||||
|
</Descriptions>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* PDF Viewer */}
|
||||||
|
{pdfInfo.visible && (
|
||||||
|
<PdfView
|
||||||
|
visible={pdfInfo.visible}
|
||||||
|
onClose={() => setPdfInfo({ ...pdfInfo, visible: false })}
|
||||||
|
title={pdfInfo.title}
|
||||||
|
fileId={pdfInfo.fileId}
|
||||||
|
url="/gunshiApp/ss/personnelPlan/file/download/"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<div style={{ display: 'none' }}>
|
||||||
|
<Image
|
||||||
|
src={previewImage}
|
||||||
|
preview={{
|
||||||
|
visible: previewVisible,
|
||||||
|
src: previewImage,
|
||||||
|
onVisibleChange: (value) => {
|
||||||
|
setPreviewVisible(value);
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</CommonModal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TrainingModal;
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
.training-modal-content {
|
||||||
|
.engineering-descriptions {
|
||||||
|
table {
|
||||||
|
table-layout: fixed !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-descriptions-view {
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid rgba(0, 160, 233, 0.3);
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-descriptions-row {
|
||||||
|
border-bottom: 1px solid rgba(0, 160, 233, 0.3);
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > th, & > td {
|
||||||
|
border-right: 1px solid rgba(0, 160, 233, 0.3);
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-descriptions-item-label {
|
||||||
|
background-color: rgba(0, 160, 233, 0.1) !important;
|
||||||
|
color: #fff !important;
|
||||||
|
font-weight: normal;
|
||||||
|
padding: 12px 16px !important;
|
||||||
|
border-color: rgba(0, 160, 233, 0.3) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-descriptions-item-content {
|
||||||
|
color: #fff !important;
|
||||||
|
padding: 12px 16px !important;
|
||||||
|
border-color: rgba(0, 160, 233, 0.3) !important;
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-item {
|
||||||
|
background: rgba(0, 160, 233, 0.1);
|
||||||
|
border: 1px solid rgba(0, 160, 233, 0.3) !important;
|
||||||
|
color: #fff;
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(0, 160, 233, 0.2);
|
||||||
|
box-shadow: 0 0 5px rgba(0, 160, 233, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,14 +1,12 @@
|
||||||
import React, { useState,useEffect } from 'react';
|
import React, { useState,useEffect } from 'react';
|
||||||
import { Image } from 'antd';
|
|
||||||
import arrowIcon from '@/assets/images/card/arrow.png';
|
import arrowIcon from '@/assets/images/card/arrow.png';
|
||||||
import selectedBg from '@/assets/images/modal/selected.png';
|
import selectedBg from '@/assets/images/modal/selected.png';
|
||||||
import resperson from '@/assets/images/card/resperson.png';
|
import resperson from '@/assets/images/card/resperson.png';
|
||||||
import smallCard from '@/assets/images/card/smallCard.png';
|
import smallCard from '@/assets/images/card/smallCard.png';
|
||||||
import qys from '@/assets/images/business/qys.png';
|
import qys from '@/assets/images/business/qys.png';
|
||||||
import PdfView from '@/views/Home/components/UI/PdfView';
|
|
||||||
import apiurl from '@/service/apiurl';
|
import apiurl from '@/service/apiurl';
|
||||||
import { httpget } from '@/utils/request';
|
import { httpget } from '@/utils/request';
|
||||||
import { download } from '@/utils/tools';
|
import TrainingModal from './components/TrainingModal';
|
||||||
import './index.less';
|
import './index.less';
|
||||||
|
|
||||||
const ImplementResponsibility = () => {
|
const ImplementResponsibility = () => {
|
||||||
|
|
@ -20,12 +18,10 @@ const ImplementResponsibility = () => {
|
||||||
5:"技术责任人",
|
5:"技术责任人",
|
||||||
}
|
}
|
||||||
const [activeTab, setActiveTab] = useState('dam'); // 'dam' or 'flood'
|
const [activeTab, setActiveTab] = useState('dam'); // 'dam' or 'flood'
|
||||||
const [pdfInfo, setPdfInfo] = useState({ visible: false, title: '', fileId: '' });
|
|
||||||
const [imagePreview, setImagePreview] = useState({ visible: false, src: '' });
|
|
||||||
const [respData, setRespData] = useState([])
|
const [respData, setRespData] = useState([])
|
||||||
const [floodData, setFloodData] = useState([])
|
const [floodData, setFloodData] = useState([])
|
||||||
const [trainData, setTrainData] = useState({})
|
const [trainData, setTrainData] = useState({})
|
||||||
const [trainFileData, setTrainFileData] = useState({})
|
const [trainingModalVisible, setTrainingModalVisible] = useState(false);
|
||||||
|
|
||||||
// 获取大坝安全责任人
|
// 获取大坝安全责任人
|
||||||
const getRespData = async () => {
|
const getRespData = async () => {
|
||||||
|
|
@ -58,7 +54,6 @@ const ImplementResponsibility = () => {
|
||||||
const { code, data } = await httpget(apiurl.sz.zrz.train)
|
const { code, data } = await httpget(apiurl.sz.zrz.train)
|
||||||
if (code == 200) {
|
if (code == 200) {
|
||||||
setTrainData(data)
|
setTrainData(data)
|
||||||
setTrainFileData(data?.latestPersonnelPlan?.files[0])
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
|
@ -73,28 +68,8 @@ const ImplementResponsibility = () => {
|
||||||
];
|
];
|
||||||
|
|
||||||
const handleTrainingClick = () => {
|
const handleTrainingClick = () => {
|
||||||
if (!trainFileData || !trainFileData.fileName) return;
|
if (!latestPersonnelPlan) return;
|
||||||
|
setTrainingModalVisible(true);
|
||||||
const fileName = trainFileData.fileName;
|
|
||||||
const fileId = trainFileData.fileId;
|
|
||||||
const extension = fileName.split('.').pop().toLowerCase();
|
|
||||||
const downloadUrl = `/gunshiApp/ss/personnelPlan/file/download/${fileId}`;
|
|
||||||
|
|
||||||
if (['jpg', 'jpeg', 'png', 'gif', 'bmp'].includes(extension)) {
|
|
||||||
setImagePreview({
|
|
||||||
visible: true,
|
|
||||||
src: downloadUrl
|
|
||||||
});
|
|
||||||
} else if (extension === 'pdf') {
|
|
||||||
setPdfInfo({
|
|
||||||
visible: true,
|
|
||||||
title: fileName,
|
|
||||||
fileId: fileId
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
download(downloadUrl)
|
|
||||||
// window.location.href = downloadUrl;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const currentPersonList = activeTab === 'dam' ? respData : floodData;
|
const currentPersonList = activeTab === 'dam' ? respData : floodData;
|
||||||
|
|
@ -175,36 +150,21 @@ const ImplementResponsibility = () => {
|
||||||
<div
|
<div
|
||||||
className="value-box"
|
className="value-box"
|
||||||
onClick={handleTrainingClick}
|
onClick={handleTrainingClick}
|
||||||
title={trainFileData.fileName?.replace(/\.[^/.]+$/, '')}
|
title={latestPersonnelPlan?.content}
|
||||||
|
style={{ cursor: 'pointer' }}
|
||||||
>
|
>
|
||||||
{trainFileData.fileName?.replace(/\.[^/.]+$/, '')}
|
{latestPersonnelPlan?.content || "暂无培训内容"}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* PDF Viewer */}
|
{/* Training Detail Modal */}
|
||||||
{pdfInfo.visible && (
|
{trainingModalVisible && (
|
||||||
<PdfView
|
<TrainingModal
|
||||||
visible={pdfInfo.visible}
|
visible={trainingModalVisible}
|
||||||
onClose={() => setPdfInfo({ ...pdfInfo, visible: false })}
|
onClose={() => setTrainingModalVisible(false)}
|
||||||
title={pdfInfo.title}
|
data={latestPersonnelPlan}
|
||||||
fileId={pdfInfo.fileId}
|
|
||||||
url="/gunshiApp/ss/personnelPlan/file/download/"
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Image Preview */}
|
|
||||||
<div style={{ display: 'none' }}>
|
|
||||||
<Image
|
|
||||||
src={imagePreview.src}
|
|
||||||
preview={{
|
|
||||||
visible: imagePreview.visible,
|
|
||||||
src: imagePreview.src,
|
|
||||||
onVisibleChange: (value) => {
|
|
||||||
setImagePreview({ ...imagePreview, visible: value });
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ import React, { useState,useEffect } from 'react';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import arrowIcon from '@/assets/images/card/arrow.png';
|
import arrowIcon from '@/assets/images/card/arrow.png';
|
||||||
import smallCard from '@/assets/images/card/smallCard.png';
|
import smallCard from '@/assets/images/card/smallCard.png';
|
||||||
import homeImg from '@/assets/images/home.png'; // Placeholder for gallery
|
|
||||||
import jingfeiIcon from '@/assets/images/card/jingfei.png';
|
import jingfeiIcon from '@/assets/images/card/jingfei.png';
|
||||||
import lightBg from '@/assets/images/card/light.png';
|
import lightBg from '@/assets/images/card/light.png';
|
||||||
import GalleryModal from './GalleryModal';
|
import GalleryModal from './GalleryModal';
|
||||||
|
|
@ -10,7 +9,7 @@ import MaterialModal from './MaterialModal';
|
||||||
import YearSelect from '@/views/Home/components/UI/YearSelect';
|
import YearSelect from '@/views/Home/components/UI/YearSelect';
|
||||||
import apiurl from '@/service/apiurl';
|
import apiurl from '@/service/apiurl';
|
||||||
import { httpget } from '@/utils/request';
|
import { httpget } from '@/utils/request';
|
||||||
import { config } from '@/config';
|
import { config } from '@/config/index';
|
||||||
import './index.less';
|
import './index.less';
|
||||||
|
|
||||||
const SoundMechanism = () => {
|
const SoundMechanism = () => {
|
||||||
|
|
@ -19,19 +18,9 @@ const SoundMechanism = () => {
|
||||||
const [materialVisible, setMaterialVisible] = useState(false);
|
const [materialVisible, setMaterialVisible] = useState(false);
|
||||||
const [modalTitle, setModalTitle] = useState('');
|
const [modalTitle, setModalTitle] = useState('');
|
||||||
const [galleryData, setGalleryData] = useState([]);
|
const [galleryData, setGalleryData] = useState([]);
|
||||||
|
|
||||||
|
|
||||||
const [manageInfo, setManageInfo] = useState({}) //管理设施
|
const [manageInfo, setManageInfo] = useState({}) //管理设施
|
||||||
const [budgetInfo, setBudgetInfo] = useState({}) //经费
|
const [budgetInfo, setBudgetInfo] = useState({}) //经费
|
||||||
// Mock data for gallery
|
|
||||||
const houseImages = [
|
|
||||||
{ name: '管理用房.jpg', url: homeImg },
|
|
||||||
{ name: '监控室.jpg', url: homeImg },
|
|
||||||
{ name: '水库全景.jpg', url: homeImg },
|
|
||||||
{ name: '会议室.jpg', url: homeImg },
|
|
||||||
{ name: '值班室.jpg', url: homeImg },
|
|
||||||
{ name: '物资仓库.jpg', url: homeImg },
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -56,8 +45,6 @@ const SoundMechanism = () => {
|
||||||
setModalVisible(true);
|
setModalVisible(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Funding Data (Mocked as per UI)
|
|
||||||
const fundingData = [
|
const fundingData = [
|
||||||
{ label: '年度收入预算', value: budgetInfo?.annualExpenditureBudget ?? '-', unit: '万元' },
|
{ label: '年度收入预算', value: budgetInfo?.annualExpenditureBudget ?? '-', unit: '万元' },
|
||||||
{ label: '年度支出预算', value: budgetInfo?.annualIncomeBudget ?? '-', unit: '万元' },
|
{ label: '年度支出预算', value: budgetInfo?.annualIncomeBudget ?? '-', unit: '万元' },
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue