feat(): 大屏页面设计
parent
00e701be3b
commit
301269f407
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
|
|
@ -172,7 +172,7 @@ const DashboardLayout: React.FC = () => {
|
|||
}
|
||||
<Content className="app-content" >
|
||||
<div className='content-root'>
|
||||
<Suspense fallback={null}>
|
||||
<Suspense fallback={<>Loading</>}>
|
||||
{
|
||||
menu.length>0?<Outlet />:null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,30 +38,9 @@ export function CrudOpRender_icon({ command, edit, del, restore, add, view }) {
|
|||
)
|
||||
}
|
||||
|
||||
export function CrudOpRender_text({ command,picReview, edit,detail, dispatch,del, restore, add,similarAdd, view,zg, cjxgl,review,download,record }) {
|
||||
export function CrudOpRender_text({ command,modify,edit,del,view}) {
|
||||
return (
|
||||
<div style={{ display: 'inline' }}>
|
||||
{
|
||||
record ? (
|
||||
<Button style={{ marginRight: 4 }} type="link" size="small" onClick={command('record')} title="培训记录">培训记录</Button>
|
||||
) : null
|
||||
}
|
||||
{
|
||||
add ? (
|
||||
<Button style={{ marginRight: 4 }} type="link" size="small" onClick={command('add')} title="增加">增加</Button>
|
||||
) : null
|
||||
}
|
||||
|
||||
{
|
||||
detail ? (
|
||||
<Button style={{ marginRight: 4 }} type="link" size="small" onClick={command('view')} title="详情">详情</Button>
|
||||
) : null
|
||||
}
|
||||
{
|
||||
similarAdd ? (
|
||||
<Button style={{ marginRight: 4 }} type="link" size="small" onClick={command('similarAdd')} title="复制">复制</Button>
|
||||
) : null
|
||||
}
|
||||
{
|
||||
edit ? (
|
||||
<Button style={{ marginRight: 4 }} type="link" size="small" onClick={command('edit')} title="编辑">编辑</Button>
|
||||
|
|
@ -72,45 +51,6 @@ export function CrudOpRender_text({ command,picReview, edit,detail, dispatch,del
|
|||
<Button style={{ marginRight: 4 }} type="link" size="small" onClick={command('view')} title="查看">查看</Button>
|
||||
) : null
|
||||
}
|
||||
{
|
||||
cjxgl ? (
|
||||
<Button style={{ marginRight: 4 }} type="link" size="small" onClick={command('cjxgl')} title="采集项管理">采集项管理</Button>
|
||||
) : null
|
||||
}
|
||||
{
|
||||
review ? (
|
||||
<Button style={{ marginRight: 4 }} type="link" size="small" onClick={command('review')} title="预览">预览</Button>
|
||||
) : null
|
||||
}
|
||||
{
|
||||
picReview ? (
|
||||
<Button style={{ marginRight: 4 }} type="link" size="small" onClick={command('picReview')} title="预览">预览</Button>
|
||||
) : null
|
||||
}
|
||||
{
|
||||
zg ? (
|
||||
<Button style={{ marginRight: 4 }} type="link" size="small" onClick={command('edit')} title="整改">整改</Button>
|
||||
) : null
|
||||
}
|
||||
{
|
||||
download ? (
|
||||
<Button style={{ marginRight: 4 }} type="link" size="small" onClick={command('download')} title="下载">下载</Button>
|
||||
) : null
|
||||
}
|
||||
{
|
||||
restore ? (
|
||||
<Popconfirm title="确定要恢复吗?" onConfirm={command('restore')}>
|
||||
<Button style={{ marginRight: 4 }} type="link" size="small" title="恢复">恢复</Button>
|
||||
</Popconfirm>
|
||||
) : null
|
||||
}
|
||||
{
|
||||
dispatch ? (
|
||||
<Popconfirm title="确定要下发吗?" onConfirm={command('dispatch')}>
|
||||
<Button style={{ marginRight: 4 }} type="link" size="small" title="下发">下发</Button>
|
||||
</Popconfirm>
|
||||
) : null
|
||||
}
|
||||
{
|
||||
del ? (
|
||||
<Popconfirm title="确定要删除吗?" onConfirm={command('del')}>
|
||||
|
|
@ -118,7 +58,11 @@ export function CrudOpRender_text({ command,picReview, edit,detail, dispatch,del
|
|||
</Popconfirm>
|
||||
) : null
|
||||
}
|
||||
|
||||
{
|
||||
modify ? (
|
||||
<Button style={{ marginRight: 4 }} type="link" size="small" onClick={command('modify')} title="修改密码">修改密码</Button>
|
||||
) : null
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -246,7 +246,7 @@ export async function loadMenu(): Promise<MenuItem[]> {
|
|||
]
|
||||
},
|
||||
{
|
||||
id: id(), title: '系统管理', path: '/mgr/xtgl/yhxx', icon: 'sz',
|
||||
id: id(), title: '系统管理', redirect: '/mgr/xtgl/yhxx', icon: 'sz',
|
||||
children: [
|
||||
{
|
||||
id: id(), title: '用户信息', path: '/mgr/xtgl/yhxx',
|
||||
|
|
|
|||
|
|
@ -11,6 +11,11 @@ const apiurl = {
|
|||
router: service_xyt + '/getRouters',
|
||||
role: service_xyt + '/system/menu/list'
|
||||
},
|
||||
|
||||
home: {
|
||||
videoList: service_fxdd + "/gateValveCctvRel/list",
|
||||
videosrc: service_fxdd + "/attCctvBase/preview",
|
||||
},
|
||||
zmjk: {
|
||||
getList : service_xyt + '/attGateB/list',
|
||||
getInformation: service_xyt + '/attGateB/data',
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@ import BasicSituation from "./Gcyx/InformationSearch/BasicSituation";
|
|||
import RunSituation from "./Gcyx/InformationSearch/RunSituation";
|
||||
import StaticTable from "./Gcyx/InformationSearch/StaticTable";
|
||||
import OperateLog from "./Gcyx/InformationSearch/OperateLog";
|
||||
import Jcsj from './WatchData/Jcsj'
|
||||
import Jcsj from './WatchData/Jcsj';
|
||||
import PoliceRecord from './WatchData/PoliceMangant/PoliceRecord'
|
||||
import PoliceRuleConfig from './WatchData/PoliceMangant/PoliceRuleConfig'
|
||||
|
||||
|
||||
import UserInfo from './SystemMangant/UserInfo'
|
||||
const HomePage = lazy(() => import('./Home'))
|
||||
|
||||
|
||||
|
|
@ -55,6 +55,10 @@ const AppRouters: React.FC = () => {
|
|||
{ path: 'gcyx/xxcx/yxqk', element: <RunSituation /> },
|
||||
{ path: 'gcyx/xxcx/tjbb', element: <StaticTable /> },
|
||||
{ path: 'gcyx/xxcx/czrz', element: <OperateLog /> },
|
||||
|
||||
// 系统管理
|
||||
{ path: 'xtgl/yhxx', element: <UserInfo /> },
|
||||
|
||||
],
|
||||
},
|
||||
{ path: '/login', element: <LoginPage /> },
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
import React, { useEffect, useState,useMemo } from 'react'
|
||||
import { useNavigate } from 'react-router';
|
||||
import autofit from 'autofit.js'
|
||||
import Zmjk from "./zmjk"
|
||||
import './index.less'
|
||||
import ReactEcharts from 'echarts-for-react';
|
||||
import options from './options'
|
||||
import clsx from 'clsx';
|
||||
import { Select } from 'antd';
|
||||
import { httpget2,httppost2 } from '../../utils/request';
|
||||
import apiurl from '../../service/apiurl';
|
||||
|
||||
const MenuTitleCard = ({key,title}) => {
|
||||
return (
|
||||
|
|
@ -38,18 +44,82 @@ export default function Home() {
|
|||
},
|
||||
|
||||
]
|
||||
|
||||
const runData = [
|
||||
{
|
||||
name: '闸后流量(m³/s)',
|
||||
value: 4300,
|
||||
time:'2024-08-15 15:00:00'
|
||||
},
|
||||
{
|
||||
name: '闸前水位(m)',
|
||||
value: 9.82,
|
||||
time:'2024-08-15 15:00:00'
|
||||
},
|
||||
{
|
||||
name: '闸后流量(m)',
|
||||
value: 8.87,
|
||||
time:'2024-08-15 15:00:00'
|
||||
},
|
||||
{
|
||||
name: '雨量(mm)',
|
||||
value: 10.5,
|
||||
time:'2024-08-15 15:00:00'
|
||||
}
|
||||
]
|
||||
|
||||
const pxOptions = useMemo(() => {
|
||||
// if (staData) {
|
||||
// return options(staData)
|
||||
// } else {
|
||||
// return options({})
|
||||
// }
|
||||
return options({})
|
||||
}, [])
|
||||
//安全监测数据
|
||||
const [safeData, setSafeData] = useState(Array(5).fill(0).map((item, i) => ({ id: i, cd: "SY01", dm: '1#断面', kpa: 2749, time: '2024-08-15 15:00:00' })))
|
||||
//操作日志
|
||||
const [operateData, setOperateData] = useState(Array(5).fill(0).map((item, i) => ({ id: i, cd: '1#闸孔', content: "设定闸门开度为0.10m", name: '刘天明', kpa: 2749, time: '2024-08-15 15:00:00' })))
|
||||
//报警信息
|
||||
const [policeData, setPoliceData] = useState(Array(5).fill(0).map((item, i) => ({ id: i,zd:'闸前水位', watchvalue: "10.23",limit:0,max:10, time: '2024-08-15 15:00:00' })))
|
||||
const navigate = useNavigate();
|
||||
const jumpMenu = (item) => {
|
||||
navigate(item.key)
|
||||
}
|
||||
const [videoList, setVideoList] = useState([])
|
||||
const [videoArr, setvideoArr] = useState({})
|
||||
|
||||
|
||||
// 获取视频列表
|
||||
const getVideoList = async () => {
|
||||
try {
|
||||
const res = await httppost2(apiurl.home.videoList,{valveCode:"HP0024208020000063"})
|
||||
setVideoList(res.data.map(item => ({label:item.name,value:item.indexCode})))
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 获取视频流
|
||||
const getVideoSrc = async (current) => {
|
||||
const res = await httpget2(`${apiurl.home.videosrc}${current}`)
|
||||
if (res.code == 200 && res.data?.length !== 0) {
|
||||
setvideoArr({src:res.data})
|
||||
}else{
|
||||
setvideoArr({})
|
||||
}
|
||||
}
|
||||
|
||||
const [activeOne, setActiveOne] = useState(0)
|
||||
useEffect(() => {
|
||||
autofit.init({
|
||||
dh: 1080,
|
||||
dw: 1920,
|
||||
el:'#daping-body',
|
||||
resize: true
|
||||
})
|
||||
})
|
||||
getVideoList()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
|
|
@ -66,6 +136,138 @@ export default function Home() {
|
|||
<div className='content-box'>
|
||||
<Zmjk />
|
||||
</div>
|
||||
<div className='content-left'>
|
||||
{/* 工程简介 */}
|
||||
<div className='project-introduce'>
|
||||
<div className='project-title'>工程简介</div>
|
||||
<div className='project-content'>
|
||||
<img alt='' className='content-img' src={`${process.env.PUBLIC_URL}/assets/xyt/homeImg/shuizhi2.png`}></img>
|
||||
盐卡闸位于湖北省荆州市经济开发区,荆江大堤左岸桩 745+614 处,位于观音寺闸上游 5km 处。盐卡闸主要工程任务为引水灌溉,解决四湖中下区农
|
||||
业灌溉和洪湖生态保障不足的问题。利用盐卡泵站进水渠,反向从长江引水,引水灌溉设计流量55m³/s,水闸级别为 1 级,次要建筑物级别为 3 级。
|
||||
</div>
|
||||
</div>
|
||||
{/* 运行监测数据 */}
|
||||
<div className='runWatch'>
|
||||
<div className='project-title'>运行监测数据</div>
|
||||
<div className='project-content'>
|
||||
{runData.map((item,i) => (
|
||||
<div className={clsx({'run_list':true,active:activeOne == i})} key={item.name} onClick={() => setActiveOne(i)}>
|
||||
<span style={{width:94}}>{item.name}</span>
|
||||
<span>{item.value}</span>
|
||||
<span>{item.time}</span>
|
||||
</div>
|
||||
))}
|
||||
<div className='run_chart'>
|
||||
<ReactEcharts
|
||||
option={pxOptions || {}}
|
||||
style={{ width: "100%", height: '100%' }}
|
||||
notMerge={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* 安全监测数据 */}
|
||||
<div className='safeWatch'>
|
||||
<div className='project-introduce'>
|
||||
<div className='project-title'>安全监测数据</div>
|
||||
<div className='project-content'>
|
||||
<table style={{ width: '100%' }}>
|
||||
<thead>
|
||||
<tr style={{background:'#455a87',height:35,fontSize:14}}>
|
||||
<th>测点编号</th>
|
||||
<th>监测断面</th>
|
||||
<th>渗压(KPa)</th>
|
||||
<th style={{width:137}}>监测时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody >
|
||||
{safeData.map((item, i) => (
|
||||
<tr style={{borderBottom:'2px solid #536cc6',textAlign:'center'}} className={clsx({'odd_row':i%2})} key={i}>
|
||||
<td>{item.cd}</td>
|
||||
<td>{item.dm}</td>
|
||||
<td>{item.kpa}</td>
|
||||
<td style={{width:137}}>{item.time}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='content-right'>
|
||||
{/* 操作日志 */}
|
||||
<div className='operate-log'>
|
||||
<div className='project-title'>操作日志</div>
|
||||
<div className='project-content'>
|
||||
<table style={{ width: '100%' }}>
|
||||
<thead>
|
||||
<tr style={{background:'#455a87',height:35,fontSize:14}}>
|
||||
<th>闸孔编号</th>
|
||||
<th>操作内容</th>
|
||||
<th>操作人员</th>
|
||||
<th style={{width:137}}>操作时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody style={{height:170}}>
|
||||
{operateData.map((item, i) => (
|
||||
<tr style={{borderBottom:'2px solid #536cc6',textAlign:'center'}} className={clsx({'odd_row':i%2})} key={i}>
|
||||
<td>{item.cd}</td>
|
||||
<td>{item.content}</td>
|
||||
<td>{item.name}</td>
|
||||
<td style={{width:137}}>{item.time}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{/* 报警信息 */}
|
||||
<div className='operate-log'>
|
||||
<div className='project-title'>报警信息</div>
|
||||
<div className='project-content'>
|
||||
<table style={{ width: '100%' }}>
|
||||
<thead>
|
||||
<tr style={{background:'#455a87',height:35,fontSize:14}}>
|
||||
<th>监测点</th>
|
||||
<th>监测值</th>
|
||||
<th style={{width:58}}>阈值下限</th>
|
||||
<th style={{width:60}}>阈值上限</th>
|
||||
<th style={{width:129}}>报警时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody style={{height:170,overflow:policeData.length > 6 ? 'scroll':'hidden'}} >
|
||||
{policeData.map((item, i) => (
|
||||
<tr style={{borderBottom:'2px solid #536cc6',textAlign:'center'}} className={clsx({'odd_row':i%2})} key={i}>
|
||||
<td style={{width:58}}>{item.zd}</td>
|
||||
<td>{item.watchvalue}</td>
|
||||
<td style={{width:58}}>{item.limit}</td>
|
||||
<td style={{width:58}}>{item.max}</td>
|
||||
<td style={{width:129}}>{item.time}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{/* 视频监控 */}
|
||||
<div className='operate-log'>
|
||||
<div className='project-title'>
|
||||
<Select
|
||||
placeholder="请选择视频"
|
||||
options={videoList}
|
||||
allowClear
|
||||
/>
|
||||
视频监控
|
||||
</div>
|
||||
<div className='project-content'>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,4 +74,103 @@
|
|||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.content-left{
|
||||
position: absolute;
|
||||
top: 120px;
|
||||
left:20px;
|
||||
.project-introduce,.runWatch,.safeWatch{
|
||||
width: 380px;
|
||||
.project-title{
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
background:url(../../assets/ykzImg/left.png) no-repeat center;
|
||||
background-size: 100% 100%;
|
||||
color: #fff;
|
||||
letter-spacing: 5px;
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
font-weight: 800;
|
||||
padding: 5px 0 0 26px;
|
||||
font-style:italic
|
||||
}
|
||||
.project-content{
|
||||
width: 100%;
|
||||
margin-top: 5px;
|
||||
background: rgba(67, 109, 165, 0.49);
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
color: #fff;
|
||||
.content-img{
|
||||
width: 150px;
|
||||
height: 107px;
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
.runWatch{
|
||||
.run_list{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 3px 5px;
|
||||
background: linear-gradient(to bottom, #32528d, #2e6ec1);
|
||||
cursor: pointer;
|
||||
}
|
||||
.active{
|
||||
color: #95f204;
|
||||
}
|
||||
.run_chart{
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.content-right{
|
||||
position: absolute;
|
||||
top: 120px;
|
||||
right:20px;
|
||||
.operate-log{
|
||||
width: 380px;
|
||||
.project-title{
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
background:url(../../assets/ykzImg/right.png) no-repeat center;
|
||||
background-size: 100% 100%;
|
||||
color: #fff;
|
||||
letter-spacing: 5px;
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
font-weight: 800;
|
||||
padding: 5px 26px 0 0;
|
||||
font-style:italic;
|
||||
text-align: right;
|
||||
}
|
||||
.project-content{
|
||||
width: 100%;
|
||||
margin-top: 5px;
|
||||
background: rgba(67, 109, 165, 0.49);
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
color: #fff;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
.odd_row{
|
||||
background: #46678b;
|
||||
}
|
||||
table tbody {
|
||||
display:block;
|
||||
height:100px;
|
||||
overflow-y:scroll;
|
||||
}
|
||||
|
||||
table thead, tbody tr {
|
||||
display:table;
|
||||
width:100%;
|
||||
table-layout:fixed;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
export default function options(data = {}) {
|
||||
return {
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
},
|
||||
grid: {
|
||||
top:20,
|
||||
left: 60,
|
||||
bottom: 20,
|
||||
right:10
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"],
|
||||
boundaryGap: false,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: "#d9d9d9",
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: "#d9d9d9",
|
||||
},
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
color: "#fff",
|
||||
formatter: '{value} m³/s'
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [150, 230, 224, 218, 135, 147, 260],
|
||||
type: "line",
|
||||
name: '闸前水位',
|
||||
lineStyle: {
|
||||
color: '#5b8ff9'
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#5b8ff9',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
position: relative;
|
||||
width: 1080px;
|
||||
height: 640px;
|
||||
transform: scale(1.3,1.2);
|
||||
transform: scale(1.2,1.2);
|
||||
|
||||
}
|
||||
.sg_zmjk_right{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,178 @@
|
|||
import React,{useEffect,useState,useMemo,useRef} from 'react';
|
||||
import { Form, Button, Input, Row,Upload, Col, Table, DatePicker, InputNumber,message,Image,Modal,Typography ,Popconfirm } from 'antd';
|
||||
import { DeleteOutlined,FileWordOutlined,FilePdfOutlined,FileZipOutlined,FileExcelOutlined } from '@ant-design/icons';
|
||||
import { formItemLayout, btnItemLayout } from '../../../components/crud/FormLayoutProps';
|
||||
|
||||
import apiurl from '../../../service/apiurl';
|
||||
import FileUpload from '../../../components/fileUpload';
|
||||
import NormalSelect from '../../../components/Form/NormalSelect';
|
||||
|
||||
import "./index.less"
|
||||
import moment from 'moment';
|
||||
const { RangePicker } = DatePicker
|
||||
const url = "http://223.75.53.141:9102/test.by-lyf.tmp"
|
||||
|
||||
const ModalForm = ({ mode, record, onEdit, onSave, onSimilarSave }) => {
|
||||
const types = [
|
||||
{
|
||||
label: "设备维修",
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
label: "设备更换",
|
||||
value: 1
|
||||
},{
|
||||
label: "结构加固",
|
||||
value: 2
|
||||
},
|
||||
]
|
||||
const [form] = Form.useForm();
|
||||
const [fileIds, setFileIds] = useState()
|
||||
const onfinish = (values) => {
|
||||
values.eventsDate = values.eventsDate?moment(values.eventsDate).format("YYYY-MM-DD 00:00:00"):''
|
||||
if (mode === 'edit') {
|
||||
values.files = fileIds;
|
||||
values.id = record.id;
|
||||
onEdit(apiurl.rcgl.gcdsj.edit,values)
|
||||
}
|
||||
if (mode === 'save') {
|
||||
values.files = fileIds
|
||||
onSave(apiurl.rcgl.gcdsj.save,values)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form
|
||||
form={form}
|
||||
{...formItemLayout}
|
||||
onFinish={onfinish}
|
||||
initialValues={record}
|
||||
>
|
||||
<Row>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="项目名称"
|
||||
name="name"
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
<Input disabled={mode==='view'} style={{width:'100%'}} allowClear />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="方案名称"
|
||||
name="name"
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
<Input disabled={mode==='view'} style={{width:'100%'}} allowClear />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
|
||||
</Row>
|
||||
<Row>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="项目地点"
|
||||
name="adress"
|
||||
>
|
||||
<Input disabled={mode==='view'} style={{width:'100%'}} allowClear />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="项目负责人"
|
||||
name="name"
|
||||
>
|
||||
<Input disabled={mode==='view'} style={{width:'100%'}} allowClear />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="维护类型"
|
||||
name="type"
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
<NormalSelect
|
||||
allowClear
|
||||
disabled={mode==='view'}
|
||||
style={{ width: "100%" }}
|
||||
options={types}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="计划维护时间"
|
||||
name="eventsDate"
|
||||
getValueFromEvent={(e,dateString) => dateString}
|
||||
getValueProps={(value) => {
|
||||
return {
|
||||
value: value ? [value[0]&&moment(value[0]),value[1]&&moment(value[1])] : undefined
|
||||
};
|
||||
}}
|
||||
>
|
||||
<RangePicker disabled={mode==='view'} format={'YYYY-MM-DD'} style={{width:'100%'}} allowClear />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row>
|
||||
<Col span={24}>
|
||||
<Form.Item
|
||||
label="维护内容"
|
||||
name="eventsDesc"
|
||||
labelCol={{ span: 3 }}
|
||||
wrapperCol={{ span: 19 }}
|
||||
>
|
||||
<Input.TextArea disabled={mode==='view'} style={{width:'100%',minHeight:'100px'}} allowClear />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="费用预估(元)"
|
||||
name="eventsDesc"
|
||||
>
|
||||
<Input disabled={mode==='view'} style={{width:'100%'}} allowClear />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row>
|
||||
<Col span={24}>
|
||||
<Form.Item
|
||||
label="附件"
|
||||
name="fieldId"
|
||||
labelCol={{ span: 3 }}
|
||||
wrapperCol={{ span: 19 }}
|
||||
>
|
||||
<FileUpload
|
||||
mode={mode}
|
||||
files={record?.files}
|
||||
setFileIds={setFileIds}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
{
|
||||
mode==='view'?null:(
|
||||
<>
|
||||
<Form.Item {...btnItemLayout}>
|
||||
<Button type="primary" htmlType="submit">
|
||||
{mode === 'save' ? '提交' : '修改'}
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</>
|
||||
)
|
||||
}
|
||||
</Form>
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default ModalForm;
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
import React, { Fragment, useRef, useMemo,useEffect,useState } from 'react';
|
||||
import BasicCrudModal from '../../../components/crud/BasicCrudModal';
|
||||
import { Table, Card, Modal, Form, Input, Button, Row,Col, Timeline, message, Tabs,Image } from 'antd';
|
||||
import ToolBar from './toolbar';
|
||||
import {btnItemLayout } from '../../../components/crud/FormLayoutProps';
|
||||
import ModalForm from './form';
|
||||
import apiurl from '../../../service/apiurl';
|
||||
import usePageTable from '../../../components/crud/usePageTable2';
|
||||
import { createCrudService } from '../../../components/crud/_';
|
||||
import {CrudOpRender_text} from '../../../components/crud/CrudOpRender';
|
||||
|
||||
const url = "http://223.75.53.141:9102/test.by-lyf.tmp"
|
||||
const Page = () => {
|
||||
const types = {
|
||||
0: "管理员",
|
||||
1: '普通用户',
|
||||
}
|
||||
const [form] = Form.useForm();
|
||||
const refModal = useRef();
|
||||
const [searchVal, setSearchVal] = useState(false)
|
||||
const columns = [
|
||||
{ title: '序号', key: 'inx', dataIndex: 'inx', width: 60, align:"center" },
|
||||
{ title: '登录账号', key: 'name', dataIndex: 'name', width: 150},
|
||||
{ title: '姓名', key: 'adress', dataIndex: 'adress', width: 150},
|
||||
{ title: '联系电话', key: 'adress', dataIndex: 'adress', width: 150},
|
||||
{ title: '职务', key: 'adress', dataIndex: 'adress', width: 150},
|
||||
{ title: '职责', key: 'adress', dataIndex: 'adress', width: 200},
|
||||
{
|
||||
title: '角色', key: 'type', dataIndex: 'type', width: 140,
|
||||
render: (value) => <span>{types[value]}</span>,
|
||||
},
|
||||
{
|
||||
title: '创建时间', key: 'eventsDate', dataIndex: 'eventsDate', width: 140,
|
||||
},
|
||||
{
|
||||
title: '操作', key: 'operation', width: 200, fixed: 'right',align: 'center',
|
||||
render: (value, row, index) => (
|
||||
<CrudOpRender_text
|
||||
edit={ true }
|
||||
del={ true }
|
||||
view={ true }
|
||||
modify={true}
|
||||
command={(cmd) => () => command(cmd)(row)} />)
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
const width = useMemo(() => columns.reduce((total, cur) => total + (cur.width), 0), [columns]);
|
||||
|
||||
const [rowRecord, setRowRecord] = useState({})
|
||||
const [modifyOpen, setModifyOpen] = useState(false)
|
||||
const command = (type) => (params) => {
|
||||
if (type === 'save') {
|
||||
refModal.current.showSave();
|
||||
} else if (type === 'edit') {
|
||||
refModal.current.showEdit({ ...params });
|
||||
} else if (type === 'view') {
|
||||
refModal.current.showView(params);
|
||||
} else if (type === 'del') {
|
||||
refModal.current.onDeleteGet(apiurl.rcgl.gcdsj.delete + `/${params.id}`);
|
||||
} else if (type === 'modify') {
|
||||
setModifyOpen(true)
|
||||
setRowRecord(params)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.sbwh.whfabz.page).find_noCode);
|
||||
|
||||
/**
|
||||
* @description 处理成功的回调
|
||||
*/
|
||||
const successCallback = () => {
|
||||
refresh()
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
const params = {
|
||||
search: {
|
||||
...searchVal,
|
||||
}
|
||||
};
|
||||
search(params)
|
||||
}, [searchVal])
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='content-root clearFloat xybm' style={{paddingRight:"0",paddingBottom:"0"}}>
|
||||
<div className='lf CrudAdcdTreeTableBox' style={{width:"100%",overflowY:"auto"}}>
|
||||
<Card className='nonebox'>
|
||||
<ToolBar
|
||||
setSearchVal={setSearchVal}
|
||||
onSave={command('save')}
|
||||
/>
|
||||
</Card>
|
||||
<div className="ant-card-body" style={{ padding: "20px 0 0 0" }}>
|
||||
<Table columns={columns} rowKey="inx" {...tableProps} scroll={{ x: width , y: "calc( 100vh - 400px )"}}/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<BasicCrudModal
|
||||
width={1000}
|
||||
ref={refModal}
|
||||
title="维护方案"
|
||||
component={ModalForm}
|
||||
onCrudSuccess={successCallback}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Modal
|
||||
open={modifyOpen}
|
||||
width={500}
|
||||
title='修改密码'
|
||||
onCancel={() => setModifyOpen(false)}
|
||||
destroyOnClose
|
||||
footer={null}
|
||||
>
|
||||
<Form
|
||||
form={form}
|
||||
onFinish={()=>{}}
|
||||
>
|
||||
<Row>
|
||||
<Col span={24}>
|
||||
<Form.Item
|
||||
label="新密码"
|
||||
name='password'
|
||||
labelCol={{style:{marginLeft:'6%'}}}
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Form.Item
|
||||
label="确认新密码"
|
||||
name="newPassword"
|
||||
rules={[{ required: true }]}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col span={24}>
|
||||
<Form.Item {...btnItemLayout}>
|
||||
<Button type="primary" htmlType="submit">
|
||||
保存
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Page;
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
import React, { useEffect,useState } from 'react';
|
||||
import { Form, Input, Button, DatePicker } from 'antd';
|
||||
import NormalSelect from '../../../components/Form/NormalSelect';
|
||||
|
||||
import moment from 'moment';
|
||||
const { RangePicker } = DatePicker;
|
||||
const ToolBar = ({ setSearchVal, onSave, storeData, role }) => {
|
||||
|
||||
const types = [
|
||||
{
|
||||
label: "管理员",
|
||||
value: 0
|
||||
},
|
||||
{
|
||||
label: "普通用户",
|
||||
value: 1
|
||||
}
|
||||
]
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const onFinish = (values) => {
|
||||
let dateSo;
|
||||
if (values.tm) {
|
||||
dateSo = {
|
||||
start: moment(values.tm[0]).format('YYYY-MM-DD HH:mm:ss'),
|
||||
end: moment(values.tm[1]).format('YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
}
|
||||
delete values.tm
|
||||
setSearchVal({...values, dateSo});
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{display:'flex',justifyContent:'space-between'}}>
|
||||
<Form form={form} className='toolbarBox' layout="inline" onFinish={onFinish}>
|
||||
<Form.Item label="姓名" name="username">
|
||||
<Input allowClear style={{width:'150px'}}/>
|
||||
</Form.Item>
|
||||
<Form.Item label="联系电话" name="phone">
|
||||
<Input allowClear style={{width:'150px'}}/>
|
||||
</Form.Item>
|
||||
<Form.Item label="角色" name="role">
|
||||
<NormalSelect allowClear style={{ width: '150px' }} options={types} />
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Button type="primary" htmlType="submit">查询</Button>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
<Button onClick={() => form.resetFields()}>重置</Button>
|
||||
</Form.Item>
|
||||
{
|
||||
(onSave) ?
|
||||
<Form.Item>
|
||||
<Button onClick={onSave}>新增</Button>
|
||||
</Form.Item>
|
||||
:null
|
||||
}
|
||||
</Form>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default ToolBar;
|
||||
|
|
@ -1,14 +1,16 @@
|
|||
import React, { Fragment, useRef, useMemo,useEffect,useState } from 'react';
|
||||
import { Table, Card, Modal, Form, Input, Button, Row,Col, Timeline, message, Tabs,Image } from 'antd';
|
||||
import React, { Fragment, useRef, useMemo, useEffect, useState } from 'react';
|
||||
import { Table, Card, Modal, Form, Input, Button, Row, Col, Timeline, message, Tabs, Image } from 'antd';
|
||||
import ToolBar from './toolbar';
|
||||
import apiurl from '../../../service/apiurl';
|
||||
import ReactEcharts from 'echarts-for-react';
|
||||
import options from './options'
|
||||
import usePageTable from '../../../components/crud/usePageTable2';
|
||||
import { createCrudService } from '../../../components/crud/_';
|
||||
import { httppost5 } from '../../../utils/request';
|
||||
import { exportFile } from '../../../utils/tools.js';
|
||||
import './index.less'
|
||||
|
||||
const RealCard = ({item}) => {
|
||||
const RealCard = ({ item }) => {
|
||||
return (
|
||||
<div className='card-container' key={item.label}>
|
||||
<div className='item-one'>{item.label}</div>
|
||||
|
|
@ -21,54 +23,61 @@ const Page = () => {
|
|||
const types = {
|
||||
0: "闸后流量",
|
||||
1: '闸前水位',
|
||||
2:'闸后水位',
|
||||
3:'雨量',
|
||||
2: '闸后水位',
|
||||
3: '雨量',
|
||||
}
|
||||
|
||||
|
||||
const pxOptions = useMemo(() => {
|
||||
// if (staData) {
|
||||
// return options(staData)
|
||||
// } else {
|
||||
// return options({})
|
||||
// }
|
||||
return options({})
|
||||
}, [])
|
||||
const nameList = [
|
||||
{
|
||||
label: "闸后流量(m³/s)",
|
||||
value:300
|
||||
value: 300
|
||||
},
|
||||
{
|
||||
label: "闸前水位(m)",
|
||||
value:300
|
||||
value: 300
|
||||
},
|
||||
{
|
||||
label: "闸后水位(m)",
|
||||
value:300
|
||||
value: 300
|
||||
},
|
||||
{
|
||||
label: "雨量(mm)",
|
||||
value:300
|
||||
value: 300
|
||||
}
|
||||
]
|
||||
const [searchVal, setSearchVal] = useState(false)
|
||||
const columns = [
|
||||
{ title: '序号', key: 'inx', dataIndex: 'inx', width: 60, align:"center" },
|
||||
{ title: '序号', key: 'inx', dataIndex: 'inx', width: 60, align: "center" },
|
||||
{
|
||||
title: '监测项目', key: 'name', dataIndex: 'name', width: 150,
|
||||
render: (v) => <span>{types[v]}</span>
|
||||
},
|
||||
{ title: '监测值', key: 'adress', dataIndex: 'adress', width: 150},
|
||||
},
|
||||
{ title: '监测值', key: 'adress', dataIndex: 'adress', width: 150 },
|
||||
{
|
||||
title: '监测时间', key: 'eventsDate', dataIndex: 'eventsDate', width: 140,
|
||||
},
|
||||
|
||||
|
||||
];
|
||||
|
||||
|
||||
|
||||
const width = useMemo(() => columns.reduce((total, cur) => total + (cur.width), 0), [columns]);
|
||||
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.sbwh.whfabz.page).find_noCode);
|
||||
|
||||
|
||||
const exportExcel = () => {
|
||||
let params = {
|
||||
...searchVal,
|
||||
}
|
||||
httppost5(apiurl.pxjh.export, params).then(res => {
|
||||
exportFile(`统计报表.xlsx`,res.data)
|
||||
})
|
||||
exportFile(`统计报表.xlsx`, res.data)
|
||||
})
|
||||
}
|
||||
useEffect(() => {
|
||||
const params = {
|
||||
|
|
@ -78,11 +87,11 @@ const Page = () => {
|
|||
};
|
||||
search(params)
|
||||
}, [searchVal])
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='content-root clearFloat xybm' style={{paddingBottom:"0"}}>
|
||||
<div className='content-root clearFloat xybm' style={{ paddingBottom: "0" }}>
|
||||
<div className='lf CrudAdcdTreeTableBox' style={{ width: "100%", overflowY: "auto" }}>
|
||||
<div className='real-data'>
|
||||
<div className='real-title'>
|
||||
|
|
@ -95,7 +104,7 @@ const Page = () => {
|
|||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className='real-data' style={{marginTop:20}}>
|
||||
<div className='real-data' style={{ marginTop: 20 }}>
|
||||
<div className='real-title'>
|
||||
<div className='icon_style'></div>
|
||||
<div className='font_style'>监测数据</div>
|
||||
|
|
@ -107,12 +116,16 @@ const Page = () => {
|
|||
exportFile1={exportExcel}
|
||||
/>
|
||||
</Card>
|
||||
<div className="ant-card-body" style={{ padding: "20px 0 0 0",display:'flex',columnGap:10 }}>
|
||||
<div className="ant-card-body" style={{ padding: "20px 0 0 0", display: 'flex', columnGap: 10 }}>
|
||||
<div style={{ width: 800 }}>
|
||||
<Table columns={columns} rowKey="inx" {...tableProps} scroll={{ x: width , y: "calc( 100vh - 400px )"}}/>
|
||||
<Table columns={columns} rowKey="inx" {...tableProps} scroll={{ x: width, y: "calc( 100vh - 400px )" }} />
|
||||
</div>
|
||||
<div style={{ flex: 1 }}>
|
||||
|
||||
<div style={{ flex: 1,height:"calc( 100vh - 400px )" }} >
|
||||
<ReactEcharts
|
||||
option={pxOptions || {}}
|
||||
style={{ width: "100%", height: '100%' }}
|
||||
notMerge={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
export default function options(data = {}) {
|
||||
return {
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
},
|
||||
grid: {
|
||||
top: 10,
|
||||
bottom:135,
|
||||
right:30
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"],
|
||||
boundaryGap: false,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: "#d9d9d9",
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
color: "#7a869a",
|
||||
},
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: "#d9d9d9",
|
||||
},
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
color: "#7a869a",
|
||||
formatter: '{value} m³/s'
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [150, 230, 224, 218, 135, 147, 260],
|
||||
type: "line",
|
||||
name: '闸前水位',
|
||||
lineStyle: {
|
||||
color: '#5b8ff9'
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#5b8ff9',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue