Compare commits
8 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
421fa904ce | |
|
|
f2adce43ff | |
|
|
71bca6f4b9 | |
|
|
e986bbc5d5 | |
|
|
b3c0cef3e2 | |
|
|
e767f8648a | |
|
|
09ee59d002 | |
|
|
5672506c58 |
|
|
@ -1,3 +1,3 @@
|
|||
GENERATE_SOURCEMAP=true
|
||||
PUBLIC_URL=/tsg
|
||||
REACT_APP_API_URL=http://local.gunshiiot.com:18083
|
||||
REACT_APP_API_URL=http://223.75.53.141:83
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
GENERATE_SOURCEMAP=false
|
||||
PUBLIC_URL=/tsg
|
||||
REACT_APP_API_URL=http://local.gunshiiot.com:18083
|
||||
REACT_APP_API_URL=http://223.75.53.141:83
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ yarn-debug.log*
|
|||
yarn-error.log*
|
||||
yarn.lock
|
||||
build.7z
|
||||
build1.zip
|
||||
|
||||
#ai
|
||||
.serena/
|
||||
|
|
|
|||
|
|
@ -13,56 +13,124 @@ import { currentBreadcrumbs } from '../../models/auth/_';
|
|||
import {page} from '../../service/warn';
|
||||
import { qryBasicWatershedDetailApi } from "../../service/preplan";
|
||||
import moment from "moment"
|
||||
import { httppost2 } from '../../utils/request';
|
||||
import { httppostAuth } from '../../utils/request';
|
||||
import apiurl from '../../service/apiurl';
|
||||
|
||||
const { Header, Content, Sider } = Layout;
|
||||
const meunObj:any = {
|
||||
'home':'基本情况',
|
||||
'fxzb':'防汛准备',
|
||||
'sxfd':'思想发动',
|
||||
'fxkhgzh':'防汛抗旱工作会',
|
||||
'fbzrh':'防办主任会',
|
||||
'fxpxb':'防汛培训班',
|
||||
'fxtj':'防汛图件',
|
||||
'zzjg':'组织机构',
|
||||
'zq':'政区',
|
||||
'gc':'工程',
|
||||
'gczx':'工程整修',
|
||||
'home':'水库一张图',
|
||||
'sq':'四全',
|
||||
'qfg':'全覆盖',
|
||||
'zcdjxx':'注册登记信息',
|
||||
'qys':'全要素',
|
||||
'kqys':'库区要素',
|
||||
'gcys':'工程要素',
|
||||
'xyys': '下游要素',
|
||||
'qth':"全天候",
|
||||
'sksq':"水库水情",
|
||||
'hdsq': "河道水情",
|
||||
'ssyq':'实时水情',
|
||||
'trsq':'土壤墒情',
|
||||
'skyh':'水库溢洪',
|
||||
'spjk':'视频监控',
|
||||
'ytygc':'已投运工程',
|
||||
'zjgc':'在建工程',
|
||||
'hdqz':'河道清障',
|
||||
'yaxb':'预案修编',
|
||||
'zqya':'政区预案',
|
||||
'ytygcya':'已投运工程预案',
|
||||
'zjgcya':'在建工程预案',
|
||||
'hsddya':'洪水调度方案',
|
||||
'qxdw':'抢险队伍',
|
||||
'qxwl':'抢险物料',
|
||||
'jczw':'检测站网',
|
||||
'yqz':'雨情站',
|
||||
'sqz':'水情站',
|
||||
'zbb':'值班表',
|
||||
'txl':'通讯录',
|
||||
'ysgzq':'雨水工灾情',
|
||||
'ssyq':'实时雨情',
|
||||
'sssq':'实时水情',
|
||||
'ssgq':'实时工情',
|
||||
'yxqk':'运行情况',
|
||||
'gcxq':'工程险情',
|
||||
'dbaq':'大坝安全监测数据',
|
||||
'sszq':'实时灾情',
|
||||
'fxdd':'防汛调度',
|
||||
'dqxsfx':'当前形势分析',
|
||||
'qzq':'全周期',
|
||||
'gcdsj':'工程大事记',
|
||||
'qzqda':'全周期档案',
|
||||
'sz':'四制',
|
||||
'gltx':'管理体系',
|
||||
'zzjgck':'组织机构查看',
|
||||
'zrrgl': '责任人管理',
|
||||
'pxgl':'培训管理',
|
||||
'pxjhgl':'培训计划管理',
|
||||
'pxjlgl':'培训记录管理',
|
||||
'szzf':'水政执法',
|
||||
'ajdj':'案件登记',
|
||||
'ajtj':'案件统计',
|
||||
'clyj':'处理依据',
|
||||
'jdkh':'监督考核',
|
||||
'khtj':'考核统计',
|
||||
'khrwgl':'考核任务管理',
|
||||
'khwtzg':'考核问题整改',
|
||||
'khzbgl':'考核指标管理',
|
||||
'khmbgl':'考核模版管理',
|
||||
'zdgl':'制度管理',
|
||||
'flfg':'法律法规',
|
||||
'zsk':'知识库',
|
||||
'ddfa':'调度方案库',
|
||||
'ywgz':'业务规则库',
|
||||
'gcaq':'工程安全知识库',
|
||||
'sy':'四预',
|
||||
'fhxzfx': '防洪形式',
|
||||
'tqyb': '天气预报',
|
||||
'hsyb':'洪水预报',
|
||||
'skhs':'水库洪水',
|
||||
'hdhs':'河道洪水',
|
||||
'ddjc':'调度决策',
|
||||
'yjxy':'应急响应',
|
||||
'ddzl':'调度指令',
|
||||
'videoSurveillance':'视频监控',
|
||||
'fxdp':'防汛大屏',
|
||||
'hyybjs':'洪水预报计算',
|
||||
'ybfagl':'预报方案管理',
|
||||
'csgl': '参数管理',
|
||||
'hsyj':'洪水预警',
|
||||
'yjxx':'预警信息',
|
||||
'gzpz': '规则配置',
|
||||
'hsyy':'洪水预演',
|
||||
'fxya':'防汛预案',
|
||||
'ddgc':'调度规程',
|
||||
'qxdw':'抢险队伍',
|
||||
'qxwl': '抢险物料',
|
||||
'sg':"四管",
|
||||
'xcxj':"巡查巡检",
|
||||
'xcrw':"巡查任务",
|
||||
'xjwtcl':"巡查问题处理",
|
||||
'xjxpz':"巡检项配置",
|
||||
'aqgl':"安全管理",
|
||||
'fxgkqd':"风险管控清单",
|
||||
'aqyhpc':"安全隐患排查",
|
||||
'aqjcgl':"安全检查管理",
|
||||
'aqsgdj':"安全事故登记",
|
||||
'aqjdtz':"安全鉴定台帐",
|
||||
'cxjgtz':"除险加固台帐",
|
||||
'byfz':"白蚁防治",
|
||||
'bypc':"白蚁监测",
|
||||
'byxc':"防治宣传",
|
||||
'zmjk':"闸门监控",
|
||||
'wxyh':"维修养护",
|
||||
'zbgl':"值班管理",
|
||||
'zbb':'值班表',
|
||||
'zbrz':'值班日志',
|
||||
'btbb':'报表管理',
|
||||
'sdjyrbb':'时段降雨日报表',
|
||||
'rjylnbb':'日降雨量年报表',
|
||||
'sdswbb':'时段水位日报表',
|
||||
'rjswbb':'日均水位年报表',
|
||||
'dbaq':'告警管理',
|
||||
'aigj':'AI告警',
|
||||
'gbyj':'广播预警',
|
||||
'gcaqjc':'工程安全监测',
|
||||
'bzt':'布置图',
|
||||
'gcaqfx':'工程安全分析',
|
||||
'jrx':'浸润线',
|
||||
'gcaqyj':'工程安全预警',
|
||||
'yhyj':'隐患预警',
|
||||
'yjgzpz':'预警规则配置',
|
||||
'sjtjcx':'数据统计查询',
|
||||
'sjlr':'人工监测数据录入',
|
||||
'czcx':'测值查询',
|
||||
'syjx':'渗压监测',
|
||||
'sljx':'渗流监测',
|
||||
'wyjx':'位移监测',
|
||||
'ndsytjb':'年度渗压统计表',
|
||||
'ndsltjb':'年度渗流统计表',
|
||||
'ndwytjb':'年度位移统计表',
|
||||
'szydd':'水资源调度',
|
||||
'gsnlfx':'供水能力分析',
|
||||
'diaodu':'调度记录',
|
||||
'gstjfx':'供水统计分析',
|
||||
'dxnjyzl':'典型年降雨资料',
|
||||
'skzfzl': '水库蒸发资料',
|
||||
'sys':'系统管理',
|
||||
'user':'用户管理',
|
||||
'department':'部门管理',
|
||||
'role':'角色管理',
|
||||
'menuM':'菜单管理',
|
||||
'loginLog':'登录日志',
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -113,31 +181,25 @@ const DashboardLayout: React.FC = () => {
|
|||
|
||||
|
||||
// 这个方法是统计菜单点击情况的
|
||||
// useEffect(()=>{
|
||||
// (async()=>{
|
||||
// const list = location.pathname.split('/')
|
||||
// let menu1:any = meunObj?.[list[2]]
|
||||
// let menu2:any = meunObj?.[list[3]]
|
||||
// let menu3:any = meunObj?.[list[4]]
|
||||
// if(menu1==='基本情况'){
|
||||
// menu2 = '基本情况'
|
||||
// }
|
||||
// if(menu1==='视频监控'){
|
||||
// menu2 = '视频监控'
|
||||
// }
|
||||
// if(menu1==='防汛大屏'){
|
||||
// menu2 = '防汛大屏'
|
||||
// }
|
||||
useEffect(()=>{
|
||||
(async()=>{
|
||||
const list = location.pathname.split('/')
|
||||
let menu1:any = meunObj?.[list[2]] //一级菜单
|
||||
let menu2:any = meunObj?.[list[3]] //二级菜单
|
||||
let menu3:any = meunObj?.[list[4]] //三级菜单
|
||||
if(menu1==='水库一张图'){
|
||||
menu2 = '水库一张图'
|
||||
}
|
||||
|
||||
// const res = await httppost2(apiurl.setMenu,{
|
||||
// createId:localStorage.getItem('userId'),
|
||||
// loginType:0,
|
||||
// menu1:menu1,
|
||||
// menu2:menu2,
|
||||
// menu3:menu3
|
||||
// })
|
||||
// })()
|
||||
// },[location.pathname])
|
||||
const res = await httppostAuth(apiurl.setMenu,{
|
||||
createId:localStorage.getItem('userId'),
|
||||
loginType:0,
|
||||
menu1:menu1,
|
||||
menu2:menu2,
|
||||
menu3:menu3
|
||||
})
|
||||
})()
|
||||
},[location.pathname])
|
||||
|
||||
const menuIndexes = useMemo(() => findMenu(menu, pathname), [menu, pathname]);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { FC, useEffect, useRef, useState } from 'react'
|
|||
// import styles from './index.module.less'
|
||||
import { message, Spin } from "antd";
|
||||
import EZUIKit from 'ezuikit-js';
|
||||
import moment from 'moment';
|
||||
|
||||
/**
|
||||
* 海康视频H5插件视频播放
|
||||
|
|
@ -23,10 +24,16 @@ const HFivePlayer = ({ wsUrl, playerID, size }) => {
|
|||
|
||||
|
||||
const initVideo = () => {
|
||||
const hasReplayRange = wsUrl?.beginTime && wsUrl?.endTime && wsUrl?.indexCode;
|
||||
const beginStr = hasReplayRange ? moment(wsUrl.beginTime).format('YYYYMMDDHHmmss') : '';
|
||||
const endStr = hasReplayRange ? moment(wsUrl.endTime).format('YYYYMMDDHHmmss') : '';
|
||||
const ezUrl = hasReplayRange
|
||||
? `ezopen://open.ys7.com/${wsUrl.indexCode}/1.rec?begin=${beginStr}&end=${endStr}`
|
||||
: `ezopen://open.ys7.com/${wsUrl.indexCode}/1.live`;
|
||||
playerYsy.current = new EZUIKit.EZUIKitPlayer({
|
||||
id: 'player' + playerID, // 视频容器ID
|
||||
accessToken: wsUrl.src,
|
||||
url: `ezopen://open.ys7.com/${wsUrl.indexCode}/1.live`,
|
||||
url: ezUrl,
|
||||
// plugin: ["talk"], // 加载插件,talk-对讲
|
||||
width: parentRef.current?.offsetWidth,
|
||||
height: parentRef.current?.offsetHeight,
|
||||
|
|
@ -133,6 +140,13 @@ const HFivePlayer = ({ wsUrl, playerID, size }) => {
|
|||
if (wsUrl?.src) {
|
||||
setIsLoading(true) //开始加载
|
||||
let preUrl = wsUrl?.src // 播放地址
|
||||
// 支持回放时间范围(海康取流地址若后端支持时间参数则追加)
|
||||
if (wsUrl?.beginTime && wsUrl?.endTime) {
|
||||
const begin = moment(wsUrl.beginTime).subtract(1,'hours').format('YYYY-MM-DD HH:mm:ss');
|
||||
const end = moment(wsUrl.endTime).format('YYYY-MM-DD HH:mm:ss');
|
||||
const sep = preUrl.includes('?') ? '&' : '?';
|
||||
preUrl = `${preUrl}${sep}beginTime=${begin}&endTime=${end}`;
|
||||
}
|
||||
console.log(preUrl);
|
||||
const param = {
|
||||
playURL: preUrl,
|
||||
|
|
|
|||
|
|
@ -49,6 +49,15 @@ const apiurl = {
|
|||
view:baseFileView
|
||||
},
|
||||
systemM: {
|
||||
action: {
|
||||
todayData: service_fxdd + "/userLoginLog/todayCount",
|
||||
activeCount: service_fxdd + "/userLoginLog/userCount",
|
||||
userCount: service_fxdd + "/userLoginLog/visitCount",
|
||||
hotData:service_fxdd + "/visitMenuLog/count"
|
||||
},
|
||||
yhxwrz:{
|
||||
page:service_fxdd + "/visitMenuLog/page",
|
||||
},
|
||||
userM: {
|
||||
updatePassword:service_xyt + '/system/user/profile/updatePwd'
|
||||
}
|
||||
|
|
@ -226,6 +235,17 @@ const apiurl = {
|
|||
|
||||
},
|
||||
|
||||
sy: {
|
||||
yjxx: {
|
||||
page: service_fxdd + "/warningRule/info/page",
|
||||
},
|
||||
yjxxpz: {
|
||||
page: service_fxdd + "/warningRule/page",
|
||||
edit: service_fxdd + '/warningRule/update',
|
||||
save: service_fxdd + '/warningRule/insert',
|
||||
delete: service_fxdd + "/warningRule/del/",
|
||||
}
|
||||
},
|
||||
// 防汛准备
|
||||
fxzb1: {
|
||||
ddgc: {
|
||||
|
|
@ -539,9 +559,12 @@ const apiurl = {
|
|||
},
|
||||
zfzl: {
|
||||
list: service_fxdd + "/gateValveReal/list",
|
||||
list1: service_fxdd + "/gate/list",
|
||||
historypage: service_fxdd + '/gateValveReal/log/page',
|
||||
historypage1: service_fxdd + '/gate/page/history',
|
||||
historyList: service_fxdd + '/gateValveReal/log/loglist',
|
||||
historyPageExport: service_fxdd + '/gateValveReal/log/exp',
|
||||
historyPageExport1: service_fxdd + '/gate/exp',
|
||||
swInfo:service_fxdd + '/reservoir/water/waterInfo',
|
||||
krlist: service_fxdd + "/reservoir/water/data",
|
||||
info: service_fxdd + "/attGateValve/detail",
|
||||
|
|
@ -570,6 +593,7 @@ const apiurl = {
|
|||
spjk1: {
|
||||
aiWarn: {
|
||||
page: service_fxdd + "/stImgWarnR/page",
|
||||
page1: service_fxdd + "/iscaiEvent/page",
|
||||
list: service_fxdd + "/attCctvBase/list",
|
||||
controler:service_fxdd + "/attCctvBase/control"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ function request(url, options,type) {
|
|||
const opt = { ...options };
|
||||
opt.headers = opt.headers || {};
|
||||
opt.headers.Accept = 'application/json';
|
||||
// opt.headers.Authorization = "Bearer" + ' ' + localStorage.getItem('access_token');
|
||||
// opt.credentials = opt.credentials || 'include';
|
||||
|
||||
return fetch(url, opt)
|
||||
|
|
@ -398,6 +399,21 @@ export function httppost2(url, data = {}) {
|
|||
return send(url, options);
|
||||
}
|
||||
|
||||
export function httppostAuth(url, data = {}) {
|
||||
const options = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'adcd': localStorage.getItem('ADCD6'),
|
||||
"gs-token": localStorage.getItem('access_token'),
|
||||
"Authorization":"Bearer" + ' ' + localStorage.getItem('access_token')
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
};
|
||||
|
||||
return send(url, options);
|
||||
}
|
||||
|
||||
export function httppost5(url, data = {}) {
|
||||
const options = {
|
||||
method: 'POST',
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ import Fxya from './fxzb/fxya'
|
|||
import Hsybjs from './fxzb/hsybjs'
|
||||
import Ybfagl from './fxzb/ybfagl'
|
||||
import Csgl from './fxzb/csgl'
|
||||
import Yjxx from './fxzb/yjxx'
|
||||
import Gzpz from './fxzb/gzpz'
|
||||
|
||||
import Qxdw_Gc from './fxzb/qxdw/gc/index.js'
|
||||
import Qxwl_Gc from './fxzb/qxwl/gc'
|
||||
|
|
@ -121,6 +123,8 @@ import Ywgz from './sz/ywgz'
|
|||
import Gcaq from './sz/khzbgl'
|
||||
//系统管理
|
||||
import SystemPage from './systemMange'
|
||||
import Yhxwrz from './yhxwrz'
|
||||
import Yhxwfx from './yhxwfx'
|
||||
|
||||
|
||||
const HomePage = lazy(() => import('./Home'))
|
||||
|
|
@ -162,6 +166,10 @@ const AppRouters: React.FC = () => {
|
|||
{ path: 'sy/hsyb/ybfagl', element: <Ybfagl /> },
|
||||
{ path: 'sy/hsyb/csgl', element: <Csgl /> },
|
||||
|
||||
// 四预-洪水预警
|
||||
{ path: 'sy/hsyj/yjxx', element: <Yjxx/> },
|
||||
{ path: 'sy/hsyj/gzpz', element: <Gzpz /> },
|
||||
|
||||
// 调度规程
|
||||
{ path: 'sy/ddgc', element: <Ddgc /> },
|
||||
|
||||
|
|
@ -298,6 +306,8 @@ const AppRouters: React.FC = () => {
|
|||
{ path: 'sys/role', element: <SystemPage src={'/mgr/home/role'}/> },
|
||||
{ path: 'sys/menuM', element: <SystemPage src={'/mgr/home/menuM'}/> },
|
||||
{ path: 'sys/loginLog', element: <SystemPage src={'/mgr/home/loginLog'}/> },
|
||||
{ path: 'sys/yhxwrz', element: <Yhxwrz /> },
|
||||
{ path: 'sys/yhxwfx', element: <Yhxwfx /> },
|
||||
],
|
||||
},
|
||||
{ path: '/login', element: <LoginPage /> },
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ const Page = ({ mySetTms }) => {
|
|||
{ key==='位移告警'?<Table_wy data={dataObj.shiftWarn} onCancel={()=>setOpen(false)}/>:null }
|
||||
{ key==='渗压告警'?<Table_sy data={dataObj.pressWarn} onCancel={()=>setOpen(false)}/>:null }
|
||||
{ key==='渗流告警'?<Table_sl data={dataObj.flowWarn} onCancel={()=>setOpen(false)}/>:null }
|
||||
{key === 'AI告警' ? <Table_AI /> : null}
|
||||
{key === 'AI告警' ? <Table_AI tms={tms} /> : null}
|
||||
{ key==='白蚁告警'?<Table_by data={dataObj.byWarn} onCancel={()=>setOpen(false)}/>:null }
|
||||
</div>
|
||||
</Modal>
|
||||
|
|
|
|||
|
|
@ -10,20 +10,20 @@ import apiurl from "../../../../service/apiurl";
|
|||
import moment from 'moment';
|
||||
|
||||
|
||||
const Page = () => {
|
||||
const Page = ({ tms }) => {
|
||||
|
||||
const { tableProps, search, refresh } = usePageTable(createCrudService('/gunshiApp/tsg/rescue/goods/page/query').find_noCode,{});
|
||||
// const { tableProps, search, refresh } = usePageTable(createCrudService('/gunshiApp/tsg/rescue/goods/page/query').find_noCode,{});
|
||||
|
||||
useEffect(()=>{
|
||||
const params = {
|
||||
search: {}
|
||||
};
|
||||
search(params)
|
||||
}, [])
|
||||
// useEffect(()=>{
|
||||
// const params = {
|
||||
// search: {}
|
||||
// };
|
||||
// search(params)
|
||||
// }, [])
|
||||
|
||||
return (
|
||||
<div className="ant-card-body" style={{padding:"0 10px",height:'600px',overflowY:'auto'}}>
|
||||
<AiWarn/>
|
||||
<AiWarn tm={tms}/>
|
||||
{/* <div>时间:{moment().format('YYYY-MM-DD HH:mm:ss')} 至 {moment().format('YYYY-MM-DD HH:mm:ss')}</div> */}
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,177 @@
|
|||
import React, { useEffect, useState, useMemo, useRef } from 'react';
|
||||
import { Form, Button, Input, Row, Upload, Col, Table, DatePicker, InputNumber, message, Image, Modal, Radio, Popconfirm } from 'antd';
|
||||
import { DeleteOutlined, VideoCameraOutlined } from '@ant-design/icons';
|
||||
import { formItemLayout, btnItemLayout } from '../../../components/crud/FormLayoutProps';
|
||||
import apiurl from '../../../service/apiurl';
|
||||
import NormalSelect from '../../../components/Form/NormalSelect';
|
||||
import moment from 'moment';
|
||||
const ModalForm = ({ mode, record, onEdit, onSave, onSimilarSave }) => {
|
||||
const [form] = Form.useForm();
|
||||
const onfinish = (values) => {
|
||||
const userId = localStorage.getItem('userId')
|
||||
values.userId = userId
|
||||
values.createTime = values.createTime ? moment(values.createTime).format("YYYY-MM-DD 00:00:00") : undefined
|
||||
if (mode === 'edit') {
|
||||
onEdit(apiurl.sy.yjxxpz.edit, { ...record, ...values })
|
||||
}
|
||||
if (mode === 'save') {
|
||||
onSave(apiurl.sy.yjxxpz.save, values)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (mode == "save") {
|
||||
const name = localStorage.getItem('userName')
|
||||
form.setFieldValue("createName", name)
|
||||
form.setFieldValue("createTime", moment())
|
||||
}
|
||||
}, [mode])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form
|
||||
form={form}
|
||||
{...formItemLayout}
|
||||
onFinish={onfinish}
|
||||
initialValues={record}
|
||||
>
|
||||
<Row>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="规则名称"
|
||||
name="ruleName"
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
<Input style={{ width: '100%' }} allowClear disabled={mode === 'view'} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="预警等级"
|
||||
name="warningLevel"
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
<NormalSelect
|
||||
options={[
|
||||
{ label: '蓝色', value: 0 },
|
||||
{ label: '黄色', value: 1 },
|
||||
{ label: '橙色', value: 2 },
|
||||
{ label: '红色', value: 3 }
|
||||
]}
|
||||
allowClear={true}
|
||||
style={{ width: '100%' }}
|
||||
disabled={mode === 'view'}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="启用状态"
|
||||
name="status"
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
<Radio.Group disabled={mode === 'view'}>
|
||||
<Radio value={0}>未启用</Radio>
|
||||
<Radio value={1}>启用</Radio>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="规则配置"
|
||||
name="durationHours"
|
||||
rules={[{ required: true, message: '请选择对象' }]}
|
||||
>
|
||||
<NormalSelect
|
||||
allowClear
|
||||
style={{ width: '100%' }}
|
||||
disabled={mode === 'view'}
|
||||
placeholder="请选择对象"
|
||||
options={[
|
||||
{ label: '未来1h水库预报水位', value: 1 },
|
||||
{ label: '未来3h水库预报水位', value: 3 },
|
||||
{ label: '未来6h水库预报水位', value: 6 },
|
||||
{ label: '未来12h水库预报水位', value: 12 },
|
||||
{ label: '未来24h水库预报水位', value: 24 },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={4}>
|
||||
<Form.Item
|
||||
label=""
|
||||
name="operator"
|
||||
rules={[{ required: true, message: '请选择关系' }]}
|
||||
>
|
||||
<NormalSelect
|
||||
allowClear
|
||||
style={{ width: '100%' }}
|
||||
disabled={mode === 'view'}
|
||||
placeholder="请选择关系"
|
||||
options={[
|
||||
{ label: '>', value: '>' },
|
||||
{ label: '≥', value: '>=' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Form.Item
|
||||
label=""
|
||||
name="type"
|
||||
rules={[{ required: true, message: '请选择阈值' }]}
|
||||
>
|
||||
<NormalSelect
|
||||
allowClear
|
||||
style={{ width: '100%' }}
|
||||
disabled={mode === 'view'}
|
||||
placeholder="请选择阈值"
|
||||
options={[
|
||||
{ label: '汛限水位(109.00m)', value: 0 },
|
||||
{ label: '设计洪水位(111.89m)', value: 1 },
|
||||
{ label: '校核洪水位(113.06m)', value: 2 },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="创建人"
|
||||
name="createName"
|
||||
>
|
||||
<Input disabled={true} style={{ width: '100%' }} allowClear />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="创建时间"
|
||||
name="createTime"
|
||||
getValueFromEvent={(e, dateString) => dateString}
|
||||
getValueProps={(value) => ({ value: value ? moment(value) : undefined })}
|
||||
>
|
||||
<DatePicker disabled={true} style={{ width: '100%' }} allowClear format={"YYYY-MM-DD HH:mm:ss"} />
|
||||
</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,109 @@
|
|||
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 {FileWordOutlined,FilePdfOutlined,FileZipOutlined,FileExcelOutlined } from '@ant-design/icons';
|
||||
import { useSelector } from 'react-redux';
|
||||
import ToolBar from './toolbar';
|
||||
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';
|
||||
import moment from 'moment';
|
||||
const url = "http://223.75.53.141:9100/gs-tsg"
|
||||
const Page = () => {
|
||||
const role = useSelector(state => state.auth.role);
|
||||
const editBtn = role?.rule?.find(item => item.menuName == "编辑")|| true;
|
||||
const viewBtn = role?.rule?.find(item => item.menuName == "查看")|| true;
|
||||
const delBtn = role?.rule?.find(item => item.menuName == "删除")|| true;
|
||||
const levelObj = {
|
||||
0: "蓝色",
|
||||
1: "黄色",
|
||||
2: "橙色",
|
||||
3: "红色",
|
||||
}
|
||||
const statusObj = {
|
||||
0: "未启用",
|
||||
1: "启用",
|
||||
}
|
||||
const refModal = useRef();
|
||||
const [searchVal, setSearchVal] = useState(false)
|
||||
const columns = [
|
||||
{ title: '序号', key: 'inx', dataIndex: 'inx', width: 60, align: "center" },
|
||||
{ title: '规则名称', key: 'ruleName', dataIndex: 'ruleName', width: 140, align: "center", },
|
||||
{ title: '预警等级', key: 'warningLevel', dataIndex: 'warningLevel', width: 100, align: "center", render: (v) => <span>{levelObj[v]}</span> },
|
||||
{ title: '状态', key: 'status', dataIndex: 'status', width: 100,align:"center",render: (v) => <span>{statusObj[v]}</span> },
|
||||
{ title: '规则描述', key: 'ruleDesc', dataIndex: 'ruleDesc', width: 300, align: "center", },
|
||||
{ title: '创建时间', key: 'createTime', dataIndex: 'createTime', width: 140, align: "center"},
|
||||
{ title: '创建人', key: 'createName', dataIndex: 'createName', width: 140, align: "center"},
|
||||
{
|
||||
title: '操作', key: 'operation', width: 100, fixed: 'right', align: 'center',
|
||||
render: (value, row, index) => (<CrudOpRender_text edit={true} del={true} command={(cmd) => () => command(cmd)(row)} />)
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
const width = useMemo(() => columns.reduce((total, cur) => total + (cur.width), 0), [columns]);
|
||||
|
||||
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.sy.yjxxpz.delete + `${params.id}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.sy.yjxxpz.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')}
|
||||
role={role}
|
||||
/>
|
||||
</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}
|
||||
// onCrudSuccess={()=>{refresh({addvcd:localStorage.getItem('ADCD6')})}}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Page;
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
import React, { useEffect,useState } from 'react';
|
||||
import { Form, Input, Button, DatePicker } from 'antd';
|
||||
|
||||
import moment from 'moment';
|
||||
import NormalSelect from '../../../components/Form/NormalSelect';
|
||||
const { RangePicker } = DatePicker;
|
||||
const ToolBar = ({ setSearchVal, onSave, storeData, role }) => {
|
||||
const addBtn = role?.rule?.find(item => item.menuName == "新增")|| true;
|
||||
const searchBtn = role?.rule?.find(item => item.menuName == "查询")|| true;
|
||||
|
||||
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const onFinish = (values) => {
|
||||
setSearchVal({...values})
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{display:'flex',justifyContent:'space-between'}}>
|
||||
<Form form={form} className='toolbarBox' layout="inline" onFinish={onFinish}>
|
||||
<Form.Item label="规则名称" name="ruleName">
|
||||
<Input allowClear style={{width:200}}/>
|
||||
</Form.Item>
|
||||
<Form.Item label="预警等级" name="warningLevel">
|
||||
<NormalSelect
|
||||
allowClear
|
||||
style={{ width: '150px' }}
|
||||
options={[
|
||||
{ label: '蓝色', value: 0 },
|
||||
{ label: '黄色', value: 1 },
|
||||
{ label: '橙色', value: 2 },
|
||||
{ label: '红色', value: 3 }
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
{searchBtn ? <Form.Item>
|
||||
<Button type="primary" htmlType="submit">查询</Button>
|
||||
</Form.Item> : null }
|
||||
|
||||
<Form.Item>
|
||||
<Button onClick={() => form.resetFields()}>重置</Button>
|
||||
</Form.Item>
|
||||
{
|
||||
(onSave && addBtn) ?
|
||||
<Form.Item>
|
||||
<Button onClick={onSave}>新增</Button>
|
||||
</Form.Item>
|
||||
:null
|
||||
}
|
||||
</Form>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default ToolBar;
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
import React,{useEffect,useState,useMemo,useRef} from 'react';
|
||||
import { Form, Button, Input, Row,Upload, Col, Table, DatePicker, InputNumber,message,Image,Modal,Radio ,Popconfirm } from 'antd';
|
||||
import { DeleteOutlined,VideoCameraOutlined } from '@ant-design/icons';
|
||||
import { formItemLayout, btnItemLayout } from '../../../components/crud/FormLayoutProps';
|
||||
import apiurl from '../../../service/apiurl';
|
||||
import NormalSelect from '../../../components/Form/NormalSelect';
|
||||
import moment from 'moment';
|
||||
const ModalForm = ({ mode, record, onEdit, onSave, onSimilarSave }) => {
|
||||
const [form] = Form.useForm();
|
||||
const onfinish = (values) => {
|
||||
const userId = localStorage.getItem('userId')
|
||||
values.userId = userId
|
||||
if (mode === 'edit') {
|
||||
onEdit(apiurl.rcgl.wxyh.edit,{...record,...values})
|
||||
}
|
||||
if (mode === 'save') {
|
||||
onSave(apiurl.rcgl.wxyh.save,values)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form
|
||||
form={form}
|
||||
{...formItemLayout}
|
||||
onFinish={onfinish}
|
||||
initialValues={record}
|
||||
>
|
||||
<Row>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="规则名称"
|
||||
name="ruleName"
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
<Input style={{ width: '100%' }} allowClear disabled={mode === 'view'} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="预警等级"
|
||||
name="warningLevel"
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
<NormalSelect
|
||||
options={[
|
||||
{ label: '蓝色', value: 0 },
|
||||
{ label: '黄色', value: 1 },
|
||||
{ label: '橙色', value: 2 },
|
||||
{ label: '红色', value: 3 }
|
||||
]}
|
||||
allowClear={true}
|
||||
style={{ width: '100%' }}
|
||||
disabled={mode === 'view'}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="启用状态"
|
||||
name="status"
|
||||
rules={[{ required: true }]}
|
||||
>
|
||||
<Radio.Group disabled={mode === 'view'}>
|
||||
<Radio value={0}>未启用</Radio>
|
||||
<Radio value={1}>启用</Radio>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col span={24}>
|
||||
<Form.Item
|
||||
label="规则配置"
|
||||
required
|
||||
labelCol={{ span: 3 }}
|
||||
wrapperCol={{ span: 19 }}
|
||||
>
|
||||
<Row gutter={16}>
|
||||
<Col span={8}>
|
||||
<Form.Item name="durationHours" rules={[{ required: true }]} noStyle>
|
||||
<NormalSelect
|
||||
allowClear
|
||||
style={{ width: '100%' }}
|
||||
disabled={mode === 'view'}
|
||||
placeholder="请选择对象"
|
||||
options={[
|
||||
{ label: '未来1h水库预报水位', value: 1 },
|
||||
{ label: '未来3h水库预报水位', value: 3 },
|
||||
{ label: '未来6h水库预报水位', value: 6 },
|
||||
{ label: '未来12h水库预报水位', value: 12 },
|
||||
{ label: '未来24h水库预报水位', value: 24 },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Form.Item name="operator" rules={[{ required: true }]} noStyle>
|
||||
<NormalSelect
|
||||
allowClear
|
||||
style={{ width: '100%' }}
|
||||
disabled={mode === 'view'}
|
||||
placeholder="请选择关系"
|
||||
options={[
|
||||
{ label: '>', value: '>' },
|
||||
{ label: '≥', value: '>=' },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Form.Item name="type" rules={[{ required: true }]} noStyle>
|
||||
<NormalSelect
|
||||
allowClear
|
||||
style={{ width: '100%' }}
|
||||
disabled={mode === 'view'}
|
||||
placeholder="请选择阈值"
|
||||
options={[
|
||||
{ label: '汛限水位(109.00m)', value: 0 },
|
||||
{ label: '设计洪水位(111.89m)', value: 1 },
|
||||
{ label: '校核洪水位(113.06m)', value: 2 },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
</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,105 @@
|
|||
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 {FileWordOutlined,FilePdfOutlined,FileZipOutlined,FileExcelOutlined } from '@ant-design/icons';
|
||||
import { useSelector } from 'react-redux';
|
||||
import ToolBar from './toolbar';
|
||||
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';
|
||||
import moment from 'moment';
|
||||
const url = "http://223.75.53.141:9100/gs-tsg"
|
||||
const Page = () => {
|
||||
const role = useSelector(state => state.auth.role);
|
||||
const editBtn = role?.rule?.find(item => item.menuName == "编辑")|| true;
|
||||
const viewBtn = role?.rule?.find(item => item.menuName == "查看")|| true;
|
||||
const delBtn = role?.rule?.find(item => item.menuName == "删除")|| true;
|
||||
const levelObj = {
|
||||
0: "蓝色",
|
||||
1: "黄色",
|
||||
2: "橙色",
|
||||
3: "红色",
|
||||
}
|
||||
const refModal = useRef();
|
||||
const [searchVal, setSearchVal] = useState(false)
|
||||
const columns = [
|
||||
{ title: '序号', key: 'inx', dataIndex: 'inx', width: 60, align: "center" },
|
||||
{ title: '预警时间', key: 'createTime', dataIndex: 'createTime', width: 140, align: "center", },
|
||||
{ title: '规则名称', key: 'ruleName', dataIndex: 'ruleName', width: 140, align: "center", },
|
||||
{ title: '预警等级', key: 'warningLevel', dataIndex: 'warningLevel', width: 100, align: "center", render: (v) => <span>{levelObj[v]}</span> },
|
||||
{ title: '预警信息', key: 'ruleDesc', dataIndex: 'ruleDesc', width: 300, align: "center", },
|
||||
{
|
||||
title: '操作', key: 'operation', width: 100, fixed: 'right', align: 'center',
|
||||
render: (value, row, index) => (<CrudOpRender_text view={true} command={(cmd) => () => command(cmd)(row)} />)
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
const width = useMemo(() => columns.reduce((total, cur) => total + (cur.width), 0), [columns]);
|
||||
|
||||
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.sy.yjxxpz.delete + `${params.id}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.sy.yjxxpz.page).find_noCode);
|
||||
|
||||
/**
|
||||
* @description 处理成功的回调
|
||||
*/
|
||||
const successCallback = () => {
|
||||
refresh()
|
||||
}
|
||||
useEffect(() => {
|
||||
if (searchVal) {
|
||||
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')}
|
||||
role={role}
|
||||
/>
|
||||
</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}
|
||||
// onCrudSuccess={()=>{refresh({addvcd:localStorage.getItem('ADCD6')})}}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Page;
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
import React, { useEffect,useState } from 'react';
|
||||
import { Form, Input, Button, DatePicker } from 'antd';
|
||||
|
||||
import moment from 'moment';
|
||||
import NormalSelect from '../../../components/Form/NormalSelect';
|
||||
const { RangePicker } = DatePicker;
|
||||
const ToolBar = ({ setSearchVal, onSave, storeData, role }) => {
|
||||
const addBtn = role?.rule?.find(item => item.menuName == "新增")|| true;
|
||||
const searchBtn = role?.rule?.find(item => item.menuName == "查询")|| true;
|
||||
|
||||
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const onFinish = (values) => {
|
||||
let dateTimeRangeSo;
|
||||
if (values.tm) {
|
||||
dateTimeRangeSo = {
|
||||
start: moment(values.tm[0]).format('YYYY-MM-DD 00:00:00'),
|
||||
end: moment(values.tm[1]).format('YYYY-MM-DD 23:59:59')
|
||||
}
|
||||
}
|
||||
delete values.tm
|
||||
setSearchVal({...values, dateTimeRangeSo});
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
let dateTimeRangeSo = {
|
||||
start: moment().subtract(1,"months").format('YYYY-MM-DD 00:00:00'),
|
||||
end: moment().format('YYYY-MM-DD 23:59:59')
|
||||
}
|
||||
form.setFieldValue("tm", [moment(dateTimeRangeSo.start), moment(dateTimeRangeSo.end)])
|
||||
setSearchVal({ dateTimeRangeSo })
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{display:'flex',justifyContent:'space-between'}}>
|
||||
<Form form={form} className='toolbarBox' layout="inline" onFinish={onFinish}>
|
||||
<Form.Item label="预警时间" name="tm">
|
||||
<RangePicker
|
||||
allowClear
|
||||
style={{ width: "300px" }}
|
||||
format="YYYY-MM-DD"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item label="预警等级" name="warningLevel">
|
||||
<NormalSelect
|
||||
allowClear
|
||||
style={{ width: '150px' }}
|
||||
options={[
|
||||
{ label: '蓝色', value: 0 },
|
||||
{ label: '黄色', value: 1 },
|
||||
{ label: '橙色', value: 2 },
|
||||
{ label: '红色', value: 3 }
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
{searchBtn ? <Form.Item>
|
||||
<Button type="primary" htmlType="submit">查询</Button>
|
||||
</Form.Item> : null }
|
||||
|
||||
<Form.Item>
|
||||
<Button onClick={() => form.resetFields()}>重置</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default ToolBar;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
import pieMonth from "./pieMonth";
|
||||
export default function jrxOptions(data = {}, type = "1", typeName = '1') {
|
||||
// debugger
|
||||
console.log("data", data);
|
||||
|
|
@ -14,8 +14,8 @@ export default function jrxOptions(data = {}, type = "1",typeName='1') {
|
|||
const type2 = ["UPD10", "UPD13"];
|
||||
const type3 = ["UPD2", "UPD5", "UPD8", "UPD17"];
|
||||
const type4 = ["UPD11", "UPD14"];
|
||||
const type5 = ["UPD3", "UPD6", "UPD9"];
|
||||
const type6 = ["UPD12", "UPD15"];
|
||||
const type5 = ["UPD3", "UPD6", "UPD12"];
|
||||
const type6 = ["UPD9", "UPD15"];
|
||||
const type7 = ["UPD24", "UPD26", "UPD28"]; //UPD24:109.87,UPD26:109.75,UPD28:109.43
|
||||
const type8 = ["UPD25", "UPD27", "UPD29"]; //UPD25:109.87,UPD27:109.75,UPD29:109.43
|
||||
|
||||
|
|
@ -29,7 +29,6 @@ export default function jrxOptions(data = {}, type = "1",typeName='1') {
|
|||
typeName == "7" ? type7 :
|
||||
typeName == "8" ? type8 :
|
||||
[];
|
||||
|
||||
// 字体颜色
|
||||
const textColor = '#666'
|
||||
const imageUrl370 = `${process.env.PUBLIC_URL}/assets/images/zb370.png `
|
||||
|
|
@ -62,48 +61,141 @@ export default function jrxOptions(data = {}, type = "1",typeName='1') {
|
|||
[[0, 102], [4, 102], [xValue, data?.rz]]
|
||||
: [];
|
||||
// gz1、gz2、gz3、gz4分别为渗压管
|
||||
const gz1 = data[alltype[0]] ?
|
||||
type == "3" ? [[typeName =='5' ?47:51, typeName =='5' ?76.56:92.18], [typeName =='5' ?47:51, data[alltype[0]]]] :
|
||||
type == "2" ? [[typeName =='3' ? 45.5:50, typeName =='3' ?76.76:77.18], [typeName =='3' ? 45.5:50, data[alltype[0]]]] :
|
||||
type == "1" ? [[44, typeName =='1' ?79.16:77.18], [44, data[alltype[0]]]] :
|
||||
[[55, typeName =='7'?109.08:108.77], [55, data[alltype[0]]]]
|
||||
: [];
|
||||
|
||||
// const gz1 = data[alltype[0]] ?
|
||||
// type == "3" ? [[typeName == '5' ? 47 : 51, typeName == '5' ? 90.50 : 81.85], [typeName == '5' ? 47 : 51, data[alltype[0]]]] :
|
||||
// type == "2" ? [[typeName == '3' ? 45.5 : 50, typeName == '3' ? 84.41 : 83.78], [typeName == '3' ? 45.5 : 50, data[alltype[0]]]] :
|
||||
// type == "1" ? [[typeName == '1' ? 44 : 51.5, typeName == '1' ? 80.11 : 78.64], [typeName == '1' ? 44 : 51.5, data[alltype[0]]]] :
|
||||
// [[55, typeName == '7' ? 109.08 : 108.77], [55, data[alltype[0]]]]
|
||||
// : [];
|
||||
|
||||
|
||||
const gz2 = data[alltype[1]] ?
|
||||
type == "3" ? [[typeName =='5' ?51:62, typeName =='5' ?77.18:83.50], [typeName =='5' ?51:62, data[alltype[1]]]] :
|
||||
type == "2" ? [[typeName =='3' ?50:61, typeName =='3' ?77.18:77.50], [typeName =='3' ?50:61, data[alltype[1]]]] :
|
||||
type == "1" ? [[51.5, typeName =='1' ?77.18:74.5], [51.5, data[alltype[1]]]] :
|
||||
[[65, typeName =='7'?109.32:109.36], [65, data[alltype[1]]]] :
|
||||
[];
|
||||
// const gz2 = data[alltype[1]] ?
|
||||
// type == "3" ? [[typeName == '5' ? 51 : 62, typeName == '5' ? 90.94 : 84.85], [typeName == '5' ? 51 : 62, data[alltype[1]]]] :
|
||||
// type == "2" ? [[typeName == '3' ? 50 : 61, typeName == '3' ? 84.04 : 81.05], [typeName == '3' ? 50 : 61, data[alltype[1]]]] :
|
||||
// type == "1" ? [[typeName == '1' ? 51.5 : 58, typeName == '1' ? 78.61 : 82.75], [typeName == '1' ? 51.5 : 58, data[alltype[1]]]] :
|
||||
// [[65, typeName == '7' ? 109.32 : 109.36], [65, data[alltype[1]]]] :
|
||||
// [];
|
||||
|
||||
const gz3 = data[alltype[2]] ?
|
||||
type == "3" ? [[62, 81.50], [62, data[alltype[2]]]] :
|
||||
type == "2" ? [[61, 80.50], [61, data[alltype[2]]]] :
|
||||
type == "1" ? [[58, 66.50], [58, data[alltype[2]]]] :
|
||||
[[77, typeName =='7'?109.01:108.87], [77, data[alltype[2]]]] : [];
|
||||
// const gz3 = data[alltype[2]] ?
|
||||
// type == "3" ? [[62, 92.65], [62, data[alltype[2]]]] :
|
||||
// type == "2" ? [[61, 83.93], [61, data[alltype[2]]]] :
|
||||
// type == "1" ? [[58, 81.38], [58, data[alltype[2]]]] :
|
||||
// [[77, typeName == '7' ? 109.01 : 108.87], [77, data[alltype[2]]]] : [];
|
||||
|
||||
|
||||
const gz4 = data[alltype[3]] ?
|
||||
type == "3" ? [] :
|
||||
type == "2" ? [[79, 73.50], [79, data[alltype[3]]]] :
|
||||
type == "1" ? [[79, 72.50], [79, data[alltype[3]]]] :
|
||||
[[85, 166], [85, data[alltype[3]]]] : [];
|
||||
// const gz4 = data[alltype[3]] ?
|
||||
// type == "3" ? [] :
|
||||
// type == "2" ? [[79, 79.57], [79, data[alltype[3]]]] :
|
||||
// type == "1" ? [[79, 79.09], [79, data[alltype[3]]]] :
|
||||
// [[85, 166], [85, data[alltype[3]]]] : [];
|
||||
|
||||
// 将渗压管连起来的线
|
||||
// 心墙中心两点(插入到连线中)
|
||||
const xCenter = type === "3" ? 49 : (type === "2" ? 47.5 : (type === "1" ? 47.5 : 60));
|
||||
// 简化规则:typeName 为 2/4/6 → 渗压管都在右侧;FB0+010/FB0+030(typeName 为 7/8)不绘制心墙连线
|
||||
const rightSideOnly = ['2', '4', '6'].includes(typeName);
|
||||
const skipCenterLine = ['7', '8'].includes(typeName);
|
||||
|
||||
// 左/右管取值(右侧优先 alltype[0],无则 alltype[1])
|
||||
const leftSyg = rightSideOnly ? undefined : data[alltype[0]];
|
||||
const rightSyg = rightSideOnly ? (data[alltype[0]] ?? data[alltype[1]]) : data[alltype[1]];
|
||||
|
||||
let midPts = [];
|
||||
if (!skipCenterLine && data?.rz) {
|
||||
if (leftSyg !== undefined && leftSyg !== null) {
|
||||
const A = leftSyg - 1;
|
||||
const B = (rightSyg !== undefined && rightSyg !== null) ? (rightSyg + 0.5) : undefined;
|
||||
if (B !== undefined) {
|
||||
if (A > B) {
|
||||
midPts = [[xCenter, A], [xCenter, B]];
|
||||
} else {
|
||||
midPts = [[xCenter, leftSyg], [xCenter, rightSyg]];
|
||||
}
|
||||
}
|
||||
} else if (rightSyg !== undefined && rightSyg !== null) {
|
||||
// 左边无渗压管:第一个点为(X, 水位-1),第二个点为(X, 右管+0.5)
|
||||
midPts = [[xCenter, data.rz - 1], [xCenter, rightSyg + 0.5]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const baseY1 = type == "3" ? (typeName =='5' ?90.50:81.85)
|
||||
: type == "2" ? (typeName =='3' ?84.41:83.78)
|
||||
: type == "1" ? (typeName =='1' ?80.11:78.64)
|
||||
: (typeName =='7'?109.08:108.77);
|
||||
|
||||
const baseY2 = type == "3" ? (typeName =='5' ?90.94:84.85)
|
||||
: type == "2" ? (typeName =='3' ?84.04:81.05)
|
||||
: type == "1" ? (typeName =='1' ?78.61:82.75)
|
||||
: (typeName =='7'?109.32:109.36);
|
||||
|
||||
const baseY3 = type == "3" ? 92.65
|
||||
: type == "2" ? 83.93
|
||||
: type == "1" ? 81.38
|
||||
: (typeName =='7'?109.01:108.87);
|
||||
|
||||
const baseY4 = type == "3" ? null
|
||||
: type == "2" ? 79.57
|
||||
: type == "1" ? 79.09
|
||||
: 166;
|
||||
|
||||
// 各管的 X(取你原来的 X)
|
||||
const x1 = type == "3" ? (typeName =='5' ?47:51)
|
||||
: type == "2" ? (typeName =='3' ? 45.5:50)
|
||||
: type == "1" ? (typeName =='1' ?44:51.5)
|
||||
: 53.5;
|
||||
|
||||
const x2 = type == "3" ? (typeName =='5' ?51:63)
|
||||
: type == "2" ? (typeName =='3' ?50:61)
|
||||
: type == "1" ? (typeName =='1' ?51.5:61)
|
||||
: 66;
|
||||
|
||||
const x3 = type == "3" ? 63
|
||||
: type == "2" ? 61
|
||||
: type == "1" ? 61
|
||||
: 77;
|
||||
|
||||
const x4 = type == "3" ? null
|
||||
: type == "2" ? 79
|
||||
: type == "1" ? 81
|
||||
: 85;
|
||||
|
||||
|
||||
// 管口高程(可能为空)
|
||||
const mouth1 = pieMonth[alltype[0]];
|
||||
const mouth2 = pieMonth[alltype[1]];
|
||||
const mouth3 = pieMonth[alltype[2]];
|
||||
const mouth4 = pieMonth[alltype[3]];
|
||||
|
||||
// 蓝色段:从“管口(若有)/管底”到 UPD 值
|
||||
const gz1 = data[alltype[0]] ? [[x1, baseY1], [x1, data[alltype[0]]]] : [];
|
||||
const gz2 = data[alltype[1]] ? [[x2, baseY2], [x2, data[alltype[1]]]] : [];
|
||||
const gz3 = data[alltype[2]] ? [[x3, baseY3], [x3, data[alltype[2]]]] : [];
|
||||
const gz4 = data[alltype[3]] && x4 !== null ? [[x4, baseY4], [x4, data[alltype[3]]]] : [];
|
||||
|
||||
// 灰色段:从“管底”到“管口”(仅当 mouth 存在)
|
||||
const gk1 = (mouth1 !== null && mouth1 !== undefined) ? [[x1, baseY1], [x1, mouth1]] : [];
|
||||
const gk2 = (mouth2 !== null && mouth2 !== undefined) ? [[x2, baseY2], [x2, mouth2]] : [];
|
||||
const gk3 = (mouth3 !== null && mouth3 !== undefined) ? [[x3, baseY3], [x3, mouth3]] : [];
|
||||
const gk4 = (mouth4 !== null && mouth4 !== undefined && x4 !== null) ? [[x4, baseY4], [x4, mouth4]] : [];
|
||||
|
||||
// 将渗压管连起来的线(插入 midPts)
|
||||
const line = data?.rz ?
|
||||
type == "3" ?
|
||||
[
|
||||
[xValue, data?.rz],
|
||||
...(rightSideOnly ? midPts : []),
|
||||
[typeName == '5' ? 47 : 51, data[alltype[0]]],
|
||||
[typeName =='5' ?51:62, data[alltype[1]]],
|
||||
[62, data[alltype[2]]],
|
||||
|
||||
...(!rightSideOnly ? midPts : []),
|
||||
[typeName == '5' ? 51 : 63, data[alltype[1]]],
|
||||
[63, data[alltype[2]]],
|
||||
] :
|
||||
type == "2" ?
|
||||
[
|
||||
[xValue, data?.rz],
|
||||
...(rightSideOnly ? midPts : []),
|
||||
[typeName == '3' ? 45.5 : 50, data[alltype[0]]],
|
||||
...(!rightSideOnly ? midPts : []),
|
||||
[typeName == '3' ? 50 : 61, data[alltype[1]]],
|
||||
[61, data[alltype[2]]],
|
||||
[79, data[alltype[3]]]
|
||||
|
|
@ -111,15 +203,19 @@ export default function jrxOptions(data = {}, type = "1",typeName='1') {
|
|||
type == "1" ?
|
||||
[
|
||||
[xValue, data?.rz],
|
||||
[44, data[alltype[0]]],
|
||||
[51.5, data[alltype[1]]],
|
||||
[58, data[alltype[2]]],
|
||||
[79, data[alltype[3]]]
|
||||
...(rightSideOnly ? midPts : []),
|
||||
[typeName == '1' ? 44 : 51.5, data[alltype[0]]],
|
||||
...(!rightSideOnly ? midPts : []),
|
||||
[typeName == '1' ? 51.5 : 61, data[alltype[1]]],
|
||||
[61, data[alltype[2]]],
|
||||
[81, data[alltype[3]]]
|
||||
] :
|
||||
[
|
||||
[xValue, data?.rz],
|
||||
[55, data[alltype[0]]],
|
||||
[65, data[alltype[1]]],
|
||||
...(rightSideOnly ? midPts : []),
|
||||
[53.5, data[alltype[0]]],
|
||||
...(!rightSideOnly ? midPts : []),
|
||||
[66, data[alltype[1]]],
|
||||
[77, data[alltype[2]]],
|
||||
[85, data[alltype[3]]]
|
||||
]
|
||||
|
|
@ -321,6 +417,42 @@ export default function jrxOptions(data = {}, type = "1",typeName='1') {
|
|||
color: '#5487FF'
|
||||
},
|
||||
data: rz1
|
||||
},
|
||||
{
|
||||
type: 'line',
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
z: 1,
|
||||
itemStyle: { color: 'rgba(154, 160, 166,.4)' },
|
||||
lineStyle: { color: 'rgba(154, 160, 166,.4)', width: 6 },
|
||||
data: gk1
|
||||
},
|
||||
{
|
||||
type: 'line',
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
z: 1,
|
||||
itemStyle: { color: 'rgba(154, 160, 166,.4)' },
|
||||
lineStyle: { color: 'rgba(154, 160, 166,.4)', width: 6 },
|
||||
data: gk2
|
||||
},
|
||||
{
|
||||
type: 'line',
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
z: 1,
|
||||
itemStyle: { color: 'rgba(154, 160, 166,.4)' },
|
||||
lineStyle: { color: 'rgba(154, 160, 166,.4)', width: 6 },
|
||||
data: gk3
|
||||
},
|
||||
{
|
||||
type: 'line',
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
z: 1,
|
||||
itemStyle: { color: 'rgba(154, 160, 166,.4)' },
|
||||
lineStyle: { color: 'rgba(154, 160, 166,.4)', width: 6 },
|
||||
data: gk4
|
||||
},
|
||||
// 管位
|
||||
{
|
||||
|
|
@ -385,15 +517,15 @@ export default function jrxOptions(data = {}, type = "1",typeName='1') {
|
|||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
z: 1,
|
||||
smooth: 0.6, // 设置平滑度
|
||||
smoothMonotone: 'x', // 保持 x 方向的单调性
|
||||
// smooth: 0.6, // 设置平滑度
|
||||
// smoothMonotone: 'x', // 保持 x 方向的单调性
|
||||
itemStyle: {
|
||||
color: '#5487FF'
|
||||
},
|
||||
lineStyle: {
|
||||
color: '#5487FF',
|
||||
width: 2,
|
||||
curveness: 0.5 // 增加曲线程度
|
||||
// curveness: 0.5 // 增加曲线程度
|
||||
},
|
||||
data: filteredArray
|
||||
},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
export default {
|
||||
// ZB0+130
|
||||
UPD1: 113.66,
|
||||
UPD4: 113.66,
|
||||
UPD7: 105.27,
|
||||
UPD16: 89.54,
|
||||
|
||||
// ZB0+132
|
||||
UPD10: 113.66,
|
||||
UPD13: 105.38,
|
||||
|
||||
// ZB0+250
|
||||
UPD2: 113.98,
|
||||
UPD5: 114.53,
|
||||
UPD8: 104.45,
|
||||
UPD17: 91.33,
|
||||
|
||||
// ZB0+252
|
||||
UPD11: 114.36,
|
||||
UPD14: 104.49,
|
||||
|
||||
// ZB0+370
|
||||
UPD3: 114.12,
|
||||
UPD6: 114.34,
|
||||
UPD12: 104.52,
|
||||
|
||||
// ZB0+372
|
||||
UPD9: 114.28,
|
||||
UPD15: 105.16,
|
||||
|
||||
// FB0+010
|
||||
UPD24: 114.22,
|
||||
UPD26: 114.44,
|
||||
UPD28: 112.28,
|
||||
|
||||
// FB0+030
|
||||
UPD25: 114.22,
|
||||
UPD27: 114.48,
|
||||
UPD29: 112.28,
|
||||
};
|
||||
|
|
@ -6,7 +6,12 @@ import { exportFile } from '../../../utils/tools';
|
|||
import apiurl from '../../../service/apiurl';
|
||||
import usePageTable from '../../../components/crud/usePageTable2';
|
||||
import { createCrudService } from '../../../components/crud/_';
|
||||
export default function ModalContent({zfjkData}) {
|
||||
export default function ModalContent({ item }) {
|
||||
const myType = {
|
||||
// 闸前水位站 2闸后水位站 3流量站
|
||||
'1': '工作闸门',
|
||||
'2': '检修闸门',
|
||||
}
|
||||
const columns = [
|
||||
{
|
||||
title: '序号',
|
||||
|
|
@ -15,25 +20,20 @@ export default function ModalContent({zfjkData}) {
|
|||
width: 80,
|
||||
},
|
||||
{
|
||||
title: '闸阀名称',
|
||||
key: 'valveName',
|
||||
dataIndex:'valveName',
|
||||
title: '闸门名称',
|
||||
key: 'stcd',
|
||||
dataIndex:'stcd',
|
||||
width: 150,
|
||||
render: (v) => <span>{myType[v]}</span>
|
||||
},
|
||||
{
|
||||
title: '当前开度(m)',
|
||||
key: 'gtop',
|
||||
dataIndex:'gtop',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '操作内容',
|
||||
dataIndex:'opContent',
|
||||
key: 'opContent',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '操作结果',
|
||||
dataIndex:'status',
|
||||
key: 'status',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '操作时间',
|
||||
title: '数据采集时间',
|
||||
dataIndex:'tm',
|
||||
key: 'tm',
|
||||
width: 150,
|
||||
|
|
@ -41,7 +41,7 @@ export default function ModalContent({zfjkData}) {
|
|||
]
|
||||
const [searchVal, setSearchVal] = useState(false)
|
||||
// 闸阀弹框更多数据
|
||||
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.gsxl.zfzl.historypage).find_noCode);
|
||||
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.gsxl.zfzl.historypage1).find_noCode);
|
||||
const exportExcel = () => {
|
||||
let params = {
|
||||
...searchVal,
|
||||
|
|
@ -50,7 +50,7 @@ export default function ModalContent({zfjkData}) {
|
|||
pageSize:tableProps.pagination.pageSize
|
||||
}
|
||||
}
|
||||
httppost5(apiurl.gsxl.zfzl.historyPageExport, params).then(res => {
|
||||
httppost5(apiurl.gsxl.zfzl.historyPageExport1, params).then(res => {
|
||||
exportFile(`闸门操作记录.xlsx`,res.data)
|
||||
})
|
||||
}
|
||||
|
|
@ -70,7 +70,7 @@ export default function ModalContent({zfjkData}) {
|
|||
<ModalToolBar
|
||||
setSearchVal={setSearchVal}
|
||||
exportFile={exportExcel}
|
||||
list={zfjkData}
|
||||
item={item}
|
||||
/>
|
||||
</Card>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { Form, Input, Button, DatePicker } from 'antd';
|
|||
import moment from 'moment';
|
||||
import NormalSelect from '../../../components/Form/NormalSelect';
|
||||
const { RangePicker } = DatePicker;
|
||||
const ToolBar = ({ setSearchVal, exportFile,list }) => {
|
||||
const ToolBar = ({ setSearchVal, exportFile,item }) => {
|
||||
const optionsType = [
|
||||
{
|
||||
label: "今日",
|
||||
|
|
@ -70,27 +70,27 @@ const ToolBar = ({ setSearchVal, exportFile,list }) => {
|
|||
|
||||
}
|
||||
useEffect(() => {
|
||||
if (list.length > 0) {
|
||||
if (item) {
|
||||
let dateTimeSo = {
|
||||
start: moment().subtract(7, "days").format('YYYY-MM-DD 00:00:00'),
|
||||
end: moment().format('YYYY-MM-DD 00:00:00')
|
||||
}
|
||||
form.setFieldValue("tm", [moment(dateTimeSo.start), moment(dateTimeSo.end)])
|
||||
form.setFieldValue("valveCode", list[0]?.valveCode)
|
||||
setSearchVal({dateTimeRangeSo:dateTimeSo, valveCode:list[0]?.valveCode})
|
||||
form.setFieldValue("stcd", item.stcd)
|
||||
setSearchVal({dateTimeRangeSo:dateTimeSo, stcd:item.stcd})
|
||||
}
|
||||
}, [list])
|
||||
}, [item])
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||
<Form form={form} className='toolbarBox' layout="inline" onFinish={onFinish} onValuesChange={onValuesChange}>
|
||||
<Form.Item label="闸门名称" name="valveCode">
|
||||
<Form.Item label="闸门名称" name="stcd">
|
||||
<NormalSelect
|
||||
style={{ width: '150px' }}
|
||||
options={list}
|
||||
options={[{label:'工作闸门',value:"1"},{label:'检修闸门',value:"2"}]}
|
||||
allowClear={false}
|
||||
fieldNames={{label: 'valveName',value: 'valveCode'}}
|
||||
disabled={true}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item label="日期范围" name="tm">
|
||||
|
|
|
|||
|
|
@ -17,165 +17,12 @@ import ModalContent from './ModalContent';
|
|||
const url = "http://223.75.53.141:9100/gs-tsg"
|
||||
const CanvasW = 1080
|
||||
const CanvasH = 640
|
||||
// const waterRatio = 0
|
||||
const zmobj = {
|
||||
"hpCode": "HP0074208040002120",
|
||||
"stcd": "4265630075",
|
||||
"ctrlType": "PLC",
|
||||
"ctrlProtocol": "PLC",
|
||||
"uprzStcd": null,
|
||||
"dwrzStcd": null,
|
||||
"flowStcd": null,
|
||||
"gaType": "waga",
|
||||
"ctrlPass": null,
|
||||
"maxHgt": 1.9,
|
||||
"minHgt": 0,
|
||||
"name": "五岭包节制闸",
|
||||
"ghtX": null,
|
||||
"ghtY": null,
|
||||
"irrCode": "D00000020",
|
||||
"irrName": "三干渠",
|
||||
"engCode": "ENG100076",
|
||||
"engName": "三干渠管理处",
|
||||
"orgCode": "A07",
|
||||
"gaorNum": 3,
|
||||
"wagaType": "节制闸",
|
||||
"plcType": null,
|
||||
"bim": 0,
|
||||
"vip": 0,
|
||||
"miu": null,
|
||||
"lgtd": 112.242945,
|
||||
"lttd": 30.848166,
|
||||
"runtime": [
|
||||
null,
|
||||
{
|
||||
"stcd": "4265630075",
|
||||
"gateNumber": 1,
|
||||
"realAperture": 376,
|
||||
"setAperture": 0,
|
||||
"sensorLever": null,
|
||||
"altitudeLever": null,
|
||||
"remoteSignal": 0,
|
||||
"powerSignal": 0,
|
||||
"openingSignal": 0,
|
||||
"closeingSignal": 0,
|
||||
"errorSignal": 0,
|
||||
"openedSignal": 0,
|
||||
"closedSignal": 0,
|
||||
"tm": "2024-09-25 20:03:26",
|
||||
"_online": true
|
||||
},
|
||||
{
|
||||
"stcd": "4265630075",
|
||||
"gateNumber": 2,
|
||||
"realAperture": 388,
|
||||
"setAperture": 0,
|
||||
"sensorLever": null,
|
||||
"altitudeLever": null,
|
||||
"remoteSignal": 0,
|
||||
"powerSignal": 0,
|
||||
"openingSignal": 0,
|
||||
"closeingSignal": 0,
|
||||
"errorSignal": 0,
|
||||
"openedSignal": 0,
|
||||
"closedSignal": 0,
|
||||
"tm": "2024-09-25 20:03:26",
|
||||
"_online": true
|
||||
},
|
||||
{
|
||||
"stcd": "4265630075",
|
||||
"gateNumber": 3,
|
||||
"realAperture": 394,
|
||||
"setAperture": 0,
|
||||
"sensorLever": null,
|
||||
"altitudeLever": null,
|
||||
"remoteSignal": 0,
|
||||
"powerSignal": null,
|
||||
"openingSignal": 0,
|
||||
"closeingSignal": 0,
|
||||
"errorSignal": 0,
|
||||
"openedSignal": 0,
|
||||
"closedSignal": 0,
|
||||
"tm": "2024-09-25 20:03:26",
|
||||
"_online": true
|
||||
}
|
||||
],
|
||||
"real": {
|
||||
"stcd": "4265630075",
|
||||
"stationName": "五岭包节制闸",
|
||||
"z1": null,
|
||||
"zz1": null,
|
||||
"z1tm": null,
|
||||
"z2": null,
|
||||
"zz2": null,
|
||||
"z2tm": null,
|
||||
"hq": null,
|
||||
"hqtm": null,
|
||||
"demtl": null
|
||||
},
|
||||
"cctvs": [],
|
||||
"_idx": 88,
|
||||
"_fav": false,
|
||||
"_sort": 10086
|
||||
}
|
||||
|
||||
const runtime = [
|
||||
null,
|
||||
{
|
||||
"stcd": "4265630075",
|
||||
"gateNumber": 1,
|
||||
"realAperture": 976,
|
||||
"setAperture": 0,
|
||||
"sensorLever": null,
|
||||
"altitudeLever": null,
|
||||
"remoteSignal": 0,
|
||||
"powerSignal": 0,
|
||||
"openingSignal": 0,
|
||||
"closeingSignal": 0,
|
||||
"errorSignal": 0,
|
||||
"openedSignal": 0,
|
||||
"closedSignal": 0,
|
||||
"tm": "2024-09-25 20:03:31"
|
||||
},
|
||||
{
|
||||
"stcd": "4265630075",
|
||||
"gateNumber": 2,
|
||||
"realAperture": 388,
|
||||
"setAperture": 0,
|
||||
"sensorLever": null,
|
||||
"altitudeLever": null,
|
||||
"remoteSignal": 0,
|
||||
"powerSignal": 0,
|
||||
"openingSignal": 0,
|
||||
"closeingSignal": 0,
|
||||
"errorSignal": 0,
|
||||
"openedSignal": 0,
|
||||
"closedSignal": 0,
|
||||
"tm": "2024-09-25 20:03:31"
|
||||
},
|
||||
{
|
||||
"stcd": "4265630075",
|
||||
"gateNumber": 3,
|
||||
"realAperture": 394,
|
||||
"setAperture": 0,
|
||||
"sensorLever": null,
|
||||
"altitudeLever": null,
|
||||
"remoteSignal": 0,
|
||||
"powerSignal": null,
|
||||
"openingSignal": 0,
|
||||
"closeingSignal": 0,
|
||||
"errorSignal": 0,
|
||||
"openedSignal": 0,
|
||||
"closedSignal": 0,
|
||||
"tm": "2024-09-25 20:03:31"
|
||||
}
|
||||
]
|
||||
|
||||
const myType = {
|
||||
// 闸前水位站 2闸后水位站 3流量站
|
||||
'1': '闸前水位/水深(m)',
|
||||
'2': '闸后水位/水深(m)',
|
||||
'3': '流量 (m³/s)',
|
||||
'1': '工作闸门',
|
||||
'2': '检修闸门',
|
||||
}
|
||||
|
||||
const Page = () => {
|
||||
|
|
@ -203,15 +50,16 @@ const Page = () => {
|
|||
|
||||
const zfColumns = [
|
||||
{
|
||||
title: '闸阀名称',
|
||||
key: 'valveName',
|
||||
dataIndex:'valveName',
|
||||
title: '闸门名称',
|
||||
key: 'stcd',
|
||||
dataIndex:'stcd',
|
||||
width: 150,
|
||||
render: (v) => <span>{myType[v]}</span>
|
||||
},
|
||||
{
|
||||
title: '当前开关状态',
|
||||
key: 'status',
|
||||
dataIndex:'status',
|
||||
title: '当前开度(m)',
|
||||
key: 'gtop',
|
||||
dataIndex:'gtop',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
|
|
@ -263,9 +111,9 @@ const Page = () => {
|
|||
const pts = contextCoordinates(xunit, hole);
|
||||
const eqpnoList = useMemo(() => damList ? new Array(damList.length).fill(0).map((o, index) => index) : [], [damList]);
|
||||
|
||||
useEffect(() => {
|
||||
getList()
|
||||
}, [])
|
||||
// useEffect(() => {
|
||||
// getList()
|
||||
// }, [])
|
||||
|
||||
const getList = async () => {
|
||||
const { code, data } = await httppost2(apiurl.zmjk.video)
|
||||
|
|
@ -335,9 +183,10 @@ const Page = () => {
|
|||
|
||||
// 闸阀监控列表数据
|
||||
const [zfjkData, setzfjkData] = useState([])
|
||||
const [rowItem, setRowItem] = useState({})
|
||||
const getZfjkData = async () => {
|
||||
try {
|
||||
const res = await httppost2(apiurl.gsxl.zfzl.list)
|
||||
const res = await httppost2(apiurl.gsxl.zfzl.list1)
|
||||
if (res.code == 200) {
|
||||
setzfjkData(res.data)
|
||||
}
|
||||
|
|
@ -426,8 +275,8 @@ const Page = () => {
|
|||
|
||||
useEffect(() => {
|
||||
getZfjkData()
|
||||
getZfjkHistoryData()
|
||||
getZfjkSwData()
|
||||
// getZfjkHistoryData()
|
||||
// getZfjkSwData()
|
||||
}, [])
|
||||
|
||||
|
||||
|
|
@ -438,20 +287,28 @@ const Page = () => {
|
|||
{/* <Card className='nonebox'>
|
||||
</Card> */}
|
||||
<div className="ant-card-body" style={{ padding: "20px 0 0 0" }}>
|
||||
<div className="sg_zmjk_left">
|
||||
<div className='sg_zmjk_left_title'>
|
||||
<div className="sg_zmjk_left" style={{width:'100%'}}>
|
||||
{/* <div className='sg_zmjk_left_title'>
|
||||
<Divider type="vertical" style={{ width: 5, background: '#259def', height: 20 }} />
|
||||
闸阀监控
|
||||
</div>
|
||||
</div> */}
|
||||
<div className='sz_left_up_table'>
|
||||
<Table
|
||||
columns={zfColumns}
|
||||
rowKey={(record) => record.tm}
|
||||
rowKey={(record) => record.id}
|
||||
dataSource={zfjkData}
|
||||
pagination={false}
|
||||
onRow={
|
||||
(data)=>({
|
||||
onClick:()=>{
|
||||
setOpen(true)
|
||||
setRowItem(data)
|
||||
}
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className='sg_zmjk_left_title' style={{ marginTop: 150,display:'flex',justifyContent:'space-between' }}>
|
||||
{/* <div className='sg_zmjk_left_title' style={{ marginTop: 150,display:'flex',justifyContent:'space-between' }}>
|
||||
<div><Divider type="vertical" style={{ width: 5, background: '#259def', height: 20 }} />
|
||||
最近操作记录</div>
|
||||
<div onClick={() => setOpen(true)}>
|
||||
|
|
@ -468,76 +325,24 @@ const Page = () => {
|
|||
dataSource={zfjkHistoryListData}
|
||||
pagination={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/* <div className="sg_zmjk_left">
|
||||
<Stage width={1080} height={640}>
|
||||
<Sider pts={pts} side="left" />
|
||||
<Sider pts={pts} side="right" />
|
||||
<Topper1 pts={pts} type={hole} />
|
||||
<ZmColumns runtime={damList} zmobj={zmobj} pts={pts} waterRatio={waterRatio} />
|
||||
<Topper2 pts={pts} waterRatio={waterRatio} />
|
||||
</Stage>
|
||||
<div style={{ position: 'absolute', left: 0, top: 20, width: '100%', height: 100, display: 'flex', alignContent: 'center' }}>
|
||||
<div key="sider1" style={{ flexGrow: 1, width: 100 }}></div>
|
||||
{
|
||||
eqpnoList.map(o => (
|
||||
<div key={o}
|
||||
onClick={() => {}}
|
||||
className='o' style={{ flexGrow: 1, width: 100, display: 'flex', justifyContent: 'center', cursor: 'pointer' }}>
|
||||
<div style={{ width: 80, height: 40, backgroundColor: '#43c4e7', borderRadius: 12, color: '#fff', display: 'flex', justifyContent: 'center', alignItems: 'center', fontSize: 28 }}>#{o+1}</div>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
<div key="sider2" style={{ flexGrow: 1, width: 100 }}></div>
|
||||
</div>
|
||||
<div style={{ position: 'absolute', left: 0, bottom: 20, width: '100%', height: 100, display: 'flex', alignContent: 'center' }}>
|
||||
<div key="sider1" style={{ flexGrow: 1, width: 100 }}></div>
|
||||
{
|
||||
eqpnoList.map(o => (
|
||||
<div key={o} className='o' style={{ flexGrow: 1, width: 100, display: 'flex', justifyContent: 'center' }}>
|
||||
<div
|
||||
onClick={() => {}}
|
||||
style={{ width: 80, height: 32, border: '1px solid #444', backgroundColor: '#fff', borderRadius: 4, color: '#888', display: 'flex', justifyContent: 'center', alignItems: 'center', fontSize: 18, cursor: 'pointer' }}
|
||||
>
|
||||
{renAperture(damList[o]?.realAperture)}
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
<div key="sider2" style={{ flexGrow: 1, width: 100 }}></div>
|
||||
</div>
|
||||
</div> */}
|
||||
<div className="sg_zmjk_right">
|
||||
</div>
|
||||
|
||||
{/* <div className="sg_zmjk_right">
|
||||
<div className='sg_zmjk_right_video'>
|
||||
<div className='sg_zmjk_right_video_title'>
|
||||
<Divider type="vertical" style={{ width: 5, background: '#259def', height: 20 }} />
|
||||
监控视频</div>
|
||||
<div className='sg_zmjk_right_video_content'>
|
||||
{/* <div className='sg_zmjk_right_video_content_left'>
|
||||
{
|
||||
videoList.map((item,index)=>(
|
||||
<div className={index===itemIndex?'sg_zmjk_right_video_content_left_item itemChecked':'sg_zmjk_right_video_content_left_item'} onClick={()=>{setItemIndex(index);getVideoSrc(item.indexCode)}}>
|
||||
{item.name}
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div> */}
|
||||
|
||||
<div className='sg_zmjk_right_video_content_right'>
|
||||
{
|
||||
videoArr?.src &&
|
||||
<div
|
||||
className="content-video"
|
||||
style={{ width: '100%', height: '100%', cursor: "pointer" }}
|
||||
onClick={() => {
|
||||
// if (controlerParams.type == 1) {
|
||||
// setVideoOpen(true)
|
||||
// setIsShow(!isShow)
|
||||
// }
|
||||
}}
|
||||
>
|
||||
<HFivePlayer size={1} wsUrl={videoArr} playerID={'111'} />
|
||||
{/* <div style={{textAlign:"right"}}>注:单击视频显示/隐藏云台</div> */}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
|
@ -554,39 +359,11 @@ const Page = () => {
|
|||
dataSource={zfjkSwData}
|
||||
pagination={false}
|
||||
/>
|
||||
{/* {
|
||||
list?.map((item)=>{
|
||||
if(item.type===1){
|
||||
return (
|
||||
<div className='sg_zmjk_right_information_content'>
|
||||
<div>{myType[item.type]}</div>
|
||||
<div>{item.value||'-'} / {getNum(item.value,data.inEle)}</div>
|
||||
<div>{item.tm?.slice(5,19)}</div>
|
||||
</div>
|
||||
)
|
||||
}else if(item.type===2){
|
||||
return (
|
||||
<div className='sg_zmjk_right_information_content'>
|
||||
<div>{myType[item.type]}</div>
|
||||
<div>{item.value||'-'} / {getNum(item.value,data.inEle)}</div>
|
||||
<div>{item.tm?.slice(5,19)}</div>
|
||||
</div>
|
||||
)
|
||||
}else{
|
||||
return (
|
||||
<div className='sg_zmjk_right_information_content'>
|
||||
<div>{myType[item.type]}</div>
|
||||
<div>{item.value}</div>
|
||||
<div>{item.tm?.slice(5,19)}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
} */}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{/* <div className='sg_zmjk_right_more' onClick={() => setOpen(true)}>查看更多信息</div> */}
|
||||
</div>
|
||||
<div className='sg_zmjk_right_more' onClick={() => setOpen(true)}>查看更多信息</div>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -601,28 +378,7 @@ const Page = () => {
|
|||
}}
|
||||
>
|
||||
<div style={{ height: '600px' }}>
|
||||
<ModalContent zfjkData={zfjkData} />
|
||||
{/* <Tabs>
|
||||
<Tabs.TabPane tab="基本信息" key="item-1">
|
||||
<Descriptions bordered size="small" column={3} >
|
||||
<Descriptions.Item label="启闭设备类型" style={{ width: '16.5%' }}>{{ 1: '卷扬式', 2: '螺杆式', 3: '凹轮式', 4: '涡轮式', 5: '丝杆式' }?.[data?.hdgrTp] || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="动力类型" style={{ width: '16.5%' }}>{{ 1: '手动', 2: '电动', 3: '手电两用' }?.[data?.pwrTp] || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="水闸类型" style={{ width: '16.5%' }}>{{ 1: '分(泄)洪闸', 2: '节制闸', 3: '排(退)水闸', 4: '引(进)水闸', 5: '挡潮闸', 6: '船闸', 9: '其他' }?.[data?.wagaType] || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="进口高程">{data?.inEle || '-'} m</Descriptions.Item>
|
||||
<Descriptions.Item label="出口高程">{data?.outEle || '-'} m</Descriptions.Item>
|
||||
<Descriptions.Item label="闸门孔数">{data?.gaorNum || '-'} 孔</Descriptions.Item>
|
||||
<Descriptions.Item label="设计流量">{data?.dsfl || '-'} m³/s</Descriptions.Item>
|
||||
<Descriptions.Item label="实达流量">{data?.stfl || '-'} m³/s</Descriptions.Item>
|
||||
<Descriptions.Item label="闸门尺寸">{data?.gateSize || '-'} m*m</Descriptions.Item>
|
||||
<Descriptions.Item label="工程等级">{{ 1: 'Ⅰ', 2: 'Ⅱ', 3: 'Ⅲ', 4: 'Ⅳ', 5: 'Ⅴ' }?.[data?.engGrad] || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="运行状况">{{ 1: '在用良好', 2: '在用故障', 3: '停用' }?.[data?.runStat] || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="建成时间">{data?.compDate || '-'}</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="工程图片" key="item-2">
|
||||
<Image width={800} src={url + data?.files?.filePath} alt='' />
|
||||
</Tabs.TabPane>
|
||||
</Tabs> */}
|
||||
<ModalContent item={rowItem} />
|
||||
</div>
|
||||
</Modal>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import React from 'react'
|
||||
import { Image } from 'antd'
|
||||
import HFivePlayer from '../../../components/video1Plary'
|
||||
|
||||
export default function Card({record}) {
|
||||
return (
|
||||
<div className='card-box' style={{border:"1px solid #fff",boxShadow:"0 0 10px #c0c0c0",padding:10,marginBottom:10,marginLeft:10}}>
|
||||
|
|
@ -7,6 +9,10 @@ export default function Card({record}) {
|
|||
src={record?.imgPath}
|
||||
style={{width:360,height:220}}
|
||||
></Image>
|
||||
{/* <div style={{width:360,height:220}}>
|
||||
<HFivePlayer size={1} wsUrl={record?.resIndexCode} playerID={record?.id} />
|
||||
|
||||
</div> */}
|
||||
<div style={{display:"flex",alignItems:"center",columnGap:5}}>
|
||||
<span style={{
|
||||
padding: "4px 2px",
|
||||
|
|
|
|||
|
|
@ -5,33 +5,88 @@ import ToolBar from './toolbar';
|
|||
import apiurl from '../../../service/apiurl';
|
||||
import usePageTable from '../../../components/crud/usePageTable3';
|
||||
import { createCrudService } from '../../../components/crud/_';
|
||||
import { httpget2,httppost2 } from '../../../utils/request';
|
||||
import HFivePlayer from '../../../components/video1Plary';
|
||||
import CardShow from "./Card"
|
||||
import "./index.less"
|
||||
const Page = () => {
|
||||
import moment from 'moment';
|
||||
const Page = (props) => {
|
||||
const tm = props?.tm;
|
||||
const statusObj = {
|
||||
0: "未处理",
|
||||
1: '已处理'
|
||||
};
|
||||
const levelStatus = {
|
||||
1: '低',
|
||||
2: '中',
|
||||
3: '高'
|
||||
}
|
||||
const role = useSelector(state => state.auth.role);
|
||||
const columns = [
|
||||
{ title: '序号', key: 'inx', dataIndex: 'inx', width: 60, align: "center" },
|
||||
{ title: '事件源名称', key: 'resName', dataIndex: 'resName', width: 150, ellipsis: true },
|
||||
{
|
||||
title: '事件类型名称', key: 'eventTypeName', dataIndex: 'eventTypeName', width: 150, ellipsis: true
|
||||
},
|
||||
{ title: '事件处理状态', key: 'handleStatus', dataIndex: 'handleStatus', width: 120, render: (v) => <span>{statusObj[v]}</span> },
|
||||
{ title: '事件等级', key: 'eventLevel', dataIndex: 'eventLevel', width: 100, render: (v) => <span>{levelStatus[v]}</span> },
|
||||
{ title: '事件开始时间', key: 'startTime', dataIndex: 'startTime', width: 150, render: (v) => <span>{v ? moment(v).format("YYYY-MM-DD HH:mm:ss") : ''}</span> },
|
||||
{ title: '事件结束时间', key: 'endTime', dataIndex: 'endTime', width: 150, render: (v) => <span>{v ? moment(v).format("YYYY-MM-DD HH:mm:ss") : ''}</span> },
|
||||
// {
|
||||
// title: '操作', key: 'opr', dataIndex: 'opr', width: 100, align: "center",
|
||||
// render:(v,r)=><Button type="link" onClick={()=>replay(r)}>回放</Button>
|
||||
// },
|
||||
|
||||
];
|
||||
const [searchVal, setSearchVal] = useState(false)
|
||||
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.spjk1.aiWarn.page).find_noCode);
|
||||
const onchange = (page, pageSize) => {
|
||||
const obj = {
|
||||
pageNumber: page,
|
||||
pageSize: pageSize,
|
||||
const [replayOpen, setReplayOpen] = useState(false)
|
||||
const [replayItem, setReplayItem] = useState({})
|
||||
const [videoSrc, setVideoSrc] = useState('')
|
||||
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.spjk1.aiWarn.page1).find_noCode);
|
||||
const width = useMemo(() => columns.reduce((total, cur) => total + (cur.width), 0), [columns]);
|
||||
|
||||
const replay = (r) => {
|
||||
setReplayOpen(true);
|
||||
setReplayItem(r)
|
||||
getVideoSrc(r)
|
||||
}
|
||||
const searchParams = {
|
||||
...obj,
|
||||
// search: {
|
||||
// ...searchVal,
|
||||
// }
|
||||
|
||||
const getVideoSrc = async(data) => {
|
||||
try {
|
||||
// 仅获取播放地址,回放时间由播放器拼接
|
||||
const res = await httpget2(`${apiurl.gsxl.zfzl.videosrc}${data.resIndexCode}`)
|
||||
setVideoSrc(res.data)
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
search(searchParams)
|
||||
}
|
||||
// 当外部传入 tm([start,end])时,初始化查询条件
|
||||
useEffect(() => {
|
||||
if (tm && Array.isArray(tm) && tm[0]) {
|
||||
setSearchVal({
|
||||
startTime: moment(tm[0]).format('YYYY-MM-DD HH:mm:ss'),
|
||||
})
|
||||
}
|
||||
}, [tm])
|
||||
|
||||
// 路由直接进入 AI 告警页(没有 tm)时,初始化一次默认查询
|
||||
useEffect(() => {
|
||||
if (!tm) {
|
||||
setSearchVal({})
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const params = {
|
||||
search: {
|
||||
...searchVal,
|
||||
}
|
||||
};
|
||||
// 避免初始化时触发空查询造成二次请求闪烁
|
||||
if (searchVal !== false) {
|
||||
search(params)
|
||||
}
|
||||
}, [searchVal])
|
||||
return (
|
||||
<>
|
||||
|
|
@ -41,35 +96,33 @@ const Page = () => {
|
|||
<ToolBar
|
||||
setSearchVal={setSearchVal}
|
||||
role={role}
|
||||
tm={tm}
|
||||
/>
|
||||
</Card>
|
||||
<div className="ant-card-body" style={{padding:"20px 0 0 0",display:"flex",flexWrap:"wrap",maxHeight:650,overflowY:"auto"}}>
|
||||
{
|
||||
tableProps.dataSource.length > 0 ?
|
||||
tableProps.dataSource.map((item,i) => {
|
||||
return (
|
||||
<div key={i} >
|
||||
<CardShow
|
||||
record={item}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}) : null
|
||||
}
|
||||
</div>
|
||||
<div style={{textAlign: "right", marginTop: "25px",marginRight:40}}>
|
||||
<Pagination
|
||||
current={tableProps.pagination.current}
|
||||
total={tableProps.pagination.total}
|
||||
showTotal={tableProps.pagination.showTotal}
|
||||
pageSize={tableProps.pagination.pageSize}
|
||||
showSizeChanger
|
||||
showQuickJumper
|
||||
pageSizeOptions={[4, 8, 12, 16]}
|
||||
onChange={onchange}
|
||||
/>
|
||||
<div className="ant-card-body" style={{ padding: "20px 0 0 0" }}>
|
||||
<Table columns={columns} rowKey="inx" {...tableProps} scroll={{ x: width, y: "calc( 100vh - 500px )" }} />
|
||||
</div>
|
||||
</div>
|
||||
<Modal
|
||||
open={replayOpen}
|
||||
width={800}
|
||||
title={replayItem?.resName}
|
||||
onCancel={() => setReplayOpen(false)}
|
||||
footer={null}
|
||||
destroyOnClose
|
||||
>
|
||||
<div style={{ width: "100%", height: 500 }}>
|
||||
<HFivePlayer
|
||||
size={1}
|
||||
wsUrl={{
|
||||
src: videoSrc,
|
||||
indexCode: replayItem?.resIndexCode,
|
||||
beginTime: replayItem?.startTime,
|
||||
endTime: replayItem?.endTime,
|
||||
}}
|
||||
playerID={replayItem?.id} />
|
||||
</div>
|
||||
</Modal>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -5,26 +5,22 @@ import moment from 'moment';
|
|||
import { httppost2 } from '../../../utils/request';
|
||||
import apiurl from '../../../service/apiurl';
|
||||
const { RangePicker } = DatePicker;
|
||||
const ToolBar = ({ setSearchVal, onSave, storeData, role }) => {
|
||||
const ToolBar = ({ setSearchVal, onSave, storeData, role, tm }) => {
|
||||
const searchBtn = role?.rule?.find(item => item.menuName == "查询")|| true;
|
||||
|
||||
const warnTypes = [
|
||||
{
|
||||
label: "人员闯入",
|
||||
label: "低",
|
||||
value:1
|
||||
},
|
||||
{
|
||||
label: "工程车辆识别",
|
||||
label: "中",
|
||||
value:2
|
||||
},
|
||||
{
|
||||
label: "漂浮物识别",
|
||||
label: "高",
|
||||
value:3
|
||||
},
|
||||
{
|
||||
label: "游泳识别",
|
||||
value:4
|
||||
},
|
||||
}
|
||||
]
|
||||
const [form] = Form.useForm();
|
||||
const [codeList, setCodeList] = useState([])
|
||||
|
|
@ -38,46 +34,30 @@ const ToolBar = ({ setSearchVal, onSave, storeData, role }) => {
|
|||
}
|
||||
}
|
||||
const onFinish = (values) => {
|
||||
let dateSo;
|
||||
if (values.tm) {
|
||||
dateSo = {
|
||||
start: moment(values.tm[0]).format('YYYY-MM-DD 00:00:00'),
|
||||
end: moment(values.tm[1]).format('YYYY-MM-DD 23:59:59')
|
||||
if (values.startTime) {
|
||||
values.startTime = moment(values.startTime).format('YYYY-MM-DD HH:mm:ss');
|
||||
}
|
||||
setSearchVal({...values});
|
||||
}
|
||||
delete values.tm
|
||||
setSearchVal({...values, dateTimeRangeSo:dateSo});
|
||||
}
|
||||
|
||||
// 预填开始时间(来自外部 tm)
|
||||
useEffect(() => {
|
||||
getStationCode()
|
||||
let time = [moment().subtract(1,"weeks"),moment()]
|
||||
let dateSo = {
|
||||
start:moment(time[0]).format('YYYY-MM-DD 00:00:00'),
|
||||
end:moment(time[1]).format('YYYY-MM-DD 23:59:59'),
|
||||
if (tm && Array.isArray(tm) && tm[0]) {
|
||||
form.setFieldsValue({ startTime: moment(tm[0]) })
|
||||
}
|
||||
form.setFieldValue("tm",time)
|
||||
setSearchVal({dateTimeRangeSo:dateSo})
|
||||
}, [])
|
||||
}, [tm])
|
||||
return (
|
||||
<>
|
||||
<div style={{display:'flex',justifyContent:'space-between'}}>
|
||||
<Form form={form} className='toolbarBox' layout="inline" onFinish={onFinish} >
|
||||
<Form.Item label="告警日期" name="tm">
|
||||
<RangePicker
|
||||
<Form.Item label="事件开始时间" name="startTime">
|
||||
<DatePicker
|
||||
allowClear
|
||||
style={{ width: "350px" }}
|
||||
format="YYYY-MM-DD"
|
||||
style={{ width: "200px" }}
|
||||
showTime
|
||||
placeholder='请选择时间'
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item label="告警点位" name="indexCode">
|
||||
<NormalSelect
|
||||
allowClear
|
||||
style={{ width: "150px" }}
|
||||
options={codeList}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item label="告警类型" name="type">
|
||||
<Form.Item label="事件等级" name="eventLevel">
|
||||
<NormalSelect
|
||||
allowClear
|
||||
style={{ width: "150px" }}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
export default function hotOption(data) {
|
||||
const result = data.map(item => {
|
||||
if (item.menu3 && item.menu3 == '布置图') item.menu2 = '';
|
||||
return{
|
||||
...item,
|
||||
menu: item.menu1 + "-" + item.menu2 + (item?.menu3 ? "-" + item.menu3 : '')
|
||||
}
|
||||
})
|
||||
const maxY = Math.ceil(Math.max(...data.map(item => item.count)))
|
||||
const minY = Math.floor(Math.min(...data.map(item => item.count)))
|
||||
return {
|
||||
grid: {
|
||||
left:"25%",
|
||||
top: "0%",
|
||||
bottom:"0%"
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
},
|
||||
calculable: true,
|
||||
xAxis: {
|
||||
type: "value",
|
||||
min:minY,
|
||||
max: maxY,
|
||||
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: "category",
|
||||
inverse: true,
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
// textStyle: {
|
||||
// color: '#999'
|
||||
// },
|
||||
fontSize:14//调整坐标轴字体大小
|
||||
},
|
||||
data: result.map(item => item.menu),
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: "",
|
||||
type: "bar",
|
||||
barWidth:"30%",
|
||||
label: {
|
||||
normal: {
|
||||
show: true,
|
||||
// position: "insideRight",
|
||||
},
|
||||
offset:[100,0]
|
||||
},
|
||||
itemStyle: {
|
||||
color:"#1283e3"
|
||||
},
|
||||
data: result.map(item => item.count),
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,254 @@
|
|||
import React, { Fragment, useRef, useMemo,useEffect,useState } from 'react';
|
||||
import { Divider,Tabs,Dropdown,Space} from 'antd';
|
||||
import ToolBar from './toolbar';
|
||||
import { DownOutlined,UpOutlined } from '@ant-design/icons';
|
||||
import apiurl from '../../service/apiurl';
|
||||
import moment from 'moment';
|
||||
import { httpget2, httppost2 } from '../../utils/request';
|
||||
import userBarOption from "./userBarOption"
|
||||
import userLineOption from "./userLineOption"
|
||||
import hotOption from './hotOption';
|
||||
import ReactEcharts from 'echarts-for-react';
|
||||
import "./index.less"
|
||||
|
||||
const Page = () => {
|
||||
|
||||
const [searchVal, setSearchVal] = useState(false)
|
||||
const [todayData, setTodayData] = useState({})
|
||||
const [activeCount, setActiveCount] = useState()
|
||||
const [userCountData, setUserCountData] = useState()
|
||||
const [hotData, setHotData] = useState()
|
||||
const [tabs, setTabs] = useState({active:0})
|
||||
const [showMore, setShowMore] = useState(false)
|
||||
const [height, setHeight] = useState("100%")
|
||||
const [hotWidth, setHotWidth] = useState("100%")
|
||||
const dtoption = useMemo(() => {
|
||||
if (userCountData) {
|
||||
return userBarOption(userCountData)
|
||||
}
|
||||
}, [userCountData])
|
||||
|
||||
const lineoption = useMemo(() => {
|
||||
if (activeCount) {
|
||||
return userLineOption(activeCount)
|
||||
}
|
||||
}, [activeCount])
|
||||
|
||||
const hotoption = useMemo(() => {
|
||||
if (hotData) {
|
||||
let substrData = [];
|
||||
if (!showMore) {
|
||||
substrData = hotData.slice(0, 10)
|
||||
} else {
|
||||
substrData = hotData
|
||||
}
|
||||
setHeight(((substrData.length) * 10) + "%")
|
||||
try {
|
||||
const labels = substrData.map(item => (
|
||||
(item.menu1 || '') + '-' + (item.menu2 || '') + (item.menu3 ? '-' + item.menu3 : '')
|
||||
));
|
||||
const maxLen = Math.max(...labels.map(l => (l || '').length), 0);
|
||||
const px = Math.min(Math.max(maxLen * 12 + 600, 800), 2400);
|
||||
setHotWidth(px + 'px');
|
||||
} catch (e) {}
|
||||
return hotOption(substrData)
|
||||
}
|
||||
}, [hotData,showMore])
|
||||
|
||||
|
||||
|
||||
// 获取今日数据
|
||||
const getTodayData = async () => {
|
||||
try {
|
||||
const res = await httpget2(apiurl.systemM.action.todayData)
|
||||
setTodayData(res.data)
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 获取日活跃数
|
||||
const getActiveCount = async (params) => {
|
||||
try {
|
||||
const {data} = await httppost2(apiurl.systemM.action.activeCount,params)
|
||||
const {appList,webList} = data
|
||||
if(appList&&webList){
|
||||
setActiveCount({appList:appList,webList:webList})
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 获取前十用户活跃数
|
||||
const getUserActiveCount = async (params) => {
|
||||
try {
|
||||
const { data } = await httppost2(apiurl.systemM.action.userCount, params)
|
||||
const {appList,webList} = data
|
||||
if(appList&&webList){
|
||||
setUserCountData({appList:appList,webList:webList})
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取热点数据
|
||||
const getHotData = async (data) => {
|
||||
try {
|
||||
const res = await httppost2(apiurl.systemM.action.hotData, data)
|
||||
setHotData(res.data)
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
getTodayData()
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (searchVal) {
|
||||
getActiveCount(searchVal)
|
||||
getUserActiveCount(searchVal)
|
||||
|
||||
}
|
||||
}, [searchVal])
|
||||
|
||||
useEffect(() => {
|
||||
if (searchVal && tabs) {
|
||||
const params = {
|
||||
...searchVal,
|
||||
loginType:Number(tabs?.active)
|
||||
}
|
||||
getHotData(params)
|
||||
}
|
||||
}, [searchVal,tabs])
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='content-root clearFloat' style={{padding:8,paddingBottom:"0"}}>
|
||||
<div className='action-top'>
|
||||
<div className='comomn-title'>
|
||||
<img alt='' src={`${process.env.PUBLIC_URL}/assets/panelTitle.png`} />
|
||||
<span>今日数据总览</span>
|
||||
</div>
|
||||
<div className='data-panel'>
|
||||
<div className='panel-item'>
|
||||
<span className='name'>WEB端访问次数</span>
|
||||
<p className='value'>{todayData?.web1Count || '-' }</p>
|
||||
</div>
|
||||
<Divider type="vertical" style={{fontSize:100,background:"#d7d7d7"}}/>
|
||||
<div className='panel-item'>
|
||||
<span className='name'>WEB端浏览次数</span>
|
||||
<p className='value'>{todayData?.web2Count || '-' }</p>
|
||||
</div>
|
||||
<Divider type="vertical" style={{fontSize:100,background:"#d7d7d7"}} />
|
||||
<div className='panel-item'>
|
||||
<span className='name'>WEB端平均访问时长</span>
|
||||
<p className='value'>{todayData?.web3Count || '-' } <span style={{fontSize:16}}>h</span></p>
|
||||
|
||||
</div>
|
||||
<Divider type="vertical" style={{fontSize:100,background:"#d7d7d7"}} />
|
||||
<div className='panel-item'>
|
||||
<span className='name'>移动端访问次数</span>
|
||||
<p className='value'>{todayData?.app1Count || '-'}</p>
|
||||
</div>
|
||||
<Divider type="vertical" style={{fontSize:100,background:"#d7d7d7"}}/>
|
||||
<div className='panel-item'>
|
||||
<span className='name'>移动端浏览次数</span>
|
||||
<p className='value'>{todayData?.app2Count || '-'}</p>
|
||||
</div>
|
||||
<Divider type="vertical" style={{fontSize:100,background:"#d7d7d7"}}/>
|
||||
<div className='panel-item'>
|
||||
<span className='name'>移动端平均访问时长</span>
|
||||
<p className='value'>{todayData?.app3Count || '-'} <span style={{fontSize:16}}>h</span></p>
|
||||
|
||||
</div>
|
||||
<Divider type="vertical" style={{fontSize:100,background:"#d7d7d7"}} />
|
||||
</div>
|
||||
</div>
|
||||
<div className='action-middle'>
|
||||
<ToolBar
|
||||
setSearchVal={setSearchVal}
|
||||
/>
|
||||
</div>
|
||||
<div className='action-bottom'>
|
||||
<div className='left'>
|
||||
<div className='left-top'>
|
||||
<div className='comomn-title'>
|
||||
<img alt='' src={`${process.env.PUBLIC_URL}/assets/panelTitle.png`} />
|
||||
<span>访问用户前十</span>
|
||||
</div>
|
||||
<div className='left-top-charts'>
|
||||
<ReactEcharts
|
||||
option={dtoption || {}}
|
||||
style={{ width: "100%", height: '100%' }}
|
||||
notMerge={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className='left-bottom'>
|
||||
<div className='comomn-title'>
|
||||
<img alt='' src={`${process.env.PUBLIC_URL}/assets/panelTitle.png`} />
|
||||
<span>日活跃用户数</span>
|
||||
</div>
|
||||
<div className='left-bottom-charts'>
|
||||
<ReactEcharts
|
||||
option={lineoption || {}}
|
||||
style={{ width: "100%", height: '100%' }}
|
||||
notMerge={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='right'>
|
||||
<div className='right-title'>
|
||||
<div className='comomn-title'>
|
||||
<img alt='' src={`${process.env.PUBLIC_URL}/assets/panelTitle.png`} />
|
||||
<span>功能热度前十</span>
|
||||
</div>
|
||||
<Tabs
|
||||
defaultActiveKey="1"
|
||||
onChange={(e) => { setTabs({ active: e }); setShowMore(false)}}
|
||||
items={[
|
||||
{
|
||||
label: `web端`,
|
||||
key: 0,
|
||||
children: ``,
|
||||
},
|
||||
{
|
||||
label: `移动端`,
|
||||
key: 1,
|
||||
children: ``,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<div className='more'>
|
||||
<a onClick={(e) => { e.preventDefault(); setShowMore(!showMore) }}>
|
||||
<Space>
|
||||
更多
|
||||
{!showMore ? <DownOutlined /> :<UpOutlined /> }
|
||||
</Space>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className='right-charts'>
|
||||
<ReactEcharts
|
||||
option={hotoption || {}}
|
||||
style={{ width: hotWidth, height: height }}
|
||||
notMerge={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Page;
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
.action-top{
|
||||
width: 100%;
|
||||
height: 170px;
|
||||
background-color: #fff;
|
||||
|
||||
.data-panel{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
column-gap: 45px;
|
||||
align-items: center;
|
||||
.panel-item{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
.name{
|
||||
color: #999999;
|
||||
font-weight: 400;
|
||||
font-family: '微软雅黑', sans-serif;
|
||||
font-size: 16px;
|
||||
}
|
||||
.value{
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.action-middle{
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
margin: 10px 0;
|
||||
background-color: #fff;
|
||||
padding-left: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.action-bottom{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
column-gap: 10px;
|
||||
.left{
|
||||
width: 50%;
|
||||
.left-top{
|
||||
background-color: #fff;
|
||||
.left-top-charts{
|
||||
width: 100%;
|
||||
height: 250px;
|
||||
}
|
||||
}
|
||||
.left-bottom{
|
||||
background-color: #fff;
|
||||
margin-top: 10px;
|
||||
.left-bottom-charts{
|
||||
width: 100%;
|
||||
height: 248px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.right{
|
||||
width: 50%;
|
||||
background-color: #fff;
|
||||
.right-title{
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 20px;
|
||||
.ant-tabs-top > .ant-tabs-nav, .ant-tabs-bottom > .ant-tabs-nav, .ant-tabs-top > div > .ant-tabs-nav, .ant-tabs-bottom > div > .ant-tabs-nav{
|
||||
margin: 0;
|
||||
}
|
||||
.ant-tabs-top > .ant-tabs-nav::before, .ant-tabs-bottom > .ant-tabs-nav::before, .ant-tabs-top > div > .ant-tabs-nav::before, .ant-tabs-bottom > div > .ant-tabs-nav::before{
|
||||
border: none;
|
||||
}
|
||||
.more{
|
||||
position: absolute;
|
||||
right: 6%;
|
||||
top: 30%;
|
||||
|
||||
}
|
||||
}
|
||||
.right-charts{
|
||||
width: 100%;
|
||||
height: 552px;
|
||||
overflow-y: auto;
|
||||
overflow-x: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
.comomn-title{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 10px;
|
||||
padding: 20px 10px;
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
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 }) => {
|
||||
|
||||
const optionsType = [
|
||||
{
|
||||
label: "今日",
|
||||
value:1
|
||||
},
|
||||
{
|
||||
label: "近一周",
|
||||
value:2
|
||||
},
|
||||
{
|
||||
label:"近一月",
|
||||
value:3
|
||||
},
|
||||
{
|
||||
label:"近三月",
|
||||
value:4
|
||||
},
|
||||
{
|
||||
label:"近一年",
|
||||
value:5
|
||||
},
|
||||
]
|
||||
const [form] = Form.useForm();
|
||||
|
||||
|
||||
const onValuesChange = (e) => {
|
||||
switch (e.ranger) {
|
||||
case 1:
|
||||
form.setFieldValue("tm", [moment().startOf("day"), moment()])
|
||||
setSearchVal({
|
||||
stm: moment().startOf("day").format("YYYY-MM-DD 00:00:00"),
|
||||
etm: moment().format("YYYY-MM-DD 23:59:59")
|
||||
})
|
||||
break;
|
||||
case 2:
|
||||
form.setFieldValue("tm",[moment().subtract(7, 'days'),moment()])
|
||||
setSearchVal({
|
||||
stm: moment().subtract(7, 'days').format("YYYY-MM-DD 00:00:00"),
|
||||
etm: moment().format("YYYY-MM-DD 23:59:59")
|
||||
})
|
||||
break;
|
||||
case 3:
|
||||
form.setFieldValue("tm",[moment().subtract(1, 'months'),moment()])
|
||||
setSearchVal({
|
||||
stm: moment().subtract(1, 'months').format("YYYY-MM-DD 00:00:00"),
|
||||
etm: moment().format("YYYY-MM-DD 23:59:59")
|
||||
})
|
||||
break;
|
||||
case 4:
|
||||
form.setFieldValue("tm",[moment().subtract(3, 'months'),moment()])
|
||||
setSearchVal({
|
||||
stm: moment().subtract(3, 'months').format("YYYY-MM-DD 00:00:00"),
|
||||
etm: moment().format("YYYY-MM-DD 23:59:59")
|
||||
})
|
||||
break;
|
||||
case 5:
|
||||
form.setFieldValue("tm",[moment().subtract(1, 'years'),moment()])
|
||||
setSearchVal({
|
||||
stm: moment().subtract(1, 'years').format("YYYY-MM-DD 00:00:00"),
|
||||
etm: moment().format("YYYY-MM-DD 23:59:59")
|
||||
})
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
form.setFieldValue("tm", [moment().subtract(7, 'days'), moment()])
|
||||
setSearchVal({
|
||||
stm: moment().subtract(7, 'days').format("YYYY-MM-DD 00:00:00"),
|
||||
etm: moment().format("YYYY-MM-DD 23:59:59")
|
||||
})
|
||||
}, [])
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{display:'flex',justifyContent:'space-between'}}>
|
||||
<Form form={form} className='toolbarBox' layout="inline" onValuesChange={onValuesChange}>
|
||||
<Form.Item label="时间" name="tm">
|
||||
<RangePicker
|
||||
allowClear
|
||||
style={{ width: "350px" }}
|
||||
format="YYYY-MM-DD"
|
||||
onChange={e => {
|
||||
setSearchVal({
|
||||
stm: e[0].format("YYYY-MM-DD 00:00:00"),
|
||||
etm: e[1].format("YYYY-MM-DD 23:59:59")
|
||||
})
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item label="常用时段" name="ranger">
|
||||
<NormalSelect
|
||||
allowClear
|
||||
style={{ width: "150px" }}
|
||||
options={optionsType}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default ToolBar;
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
import { rotate } from "ol/coordinate";
|
||||
|
||||
|
||||
export default function userBarOption(data) {
|
||||
const appList = data.appList.map(item => ({
|
||||
...item, appCount: item?.count
|
||||
}))
|
||||
const webList = data.webList.map(item => ({
|
||||
...item, webCount: item?.count
|
||||
}))
|
||||
const arr = [...appList,...webList]
|
||||
const compareLength = appList.length - webList.length;
|
||||
// 找出长度大的数组
|
||||
const mapArr1 = compareLength >= 0 ? appList : webList;
|
||||
// 找出长度小的数组
|
||||
const mapArr2 = compareLength < 0 ? appList : webList;
|
||||
|
||||
const maxY = Math.ceil(Math.max(...arr.map(item => item.count)))
|
||||
const minY = Math.floor(Math.min(...arr.map(item => item.count)))
|
||||
const result = mapArr1.map(item => {
|
||||
let filterData = mapArr2.find(o => item.name == o.name)
|
||||
return {
|
||||
...item,
|
||||
...filterData,
|
||||
}
|
||||
})
|
||||
return {
|
||||
grid: {
|
||||
top: "15%",
|
||||
bottom:"20%"
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
},
|
||||
legend: {
|
||||
show:true
|
||||
},
|
||||
|
||||
calculable: true,
|
||||
xAxis: [
|
||||
{
|
||||
type: "category",
|
||||
axisLabel:{
|
||||
interval:0,
|
||||
rotate:15
|
||||
},
|
||||
data:result.map(item => item.name),
|
||||
},
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: "value",
|
||||
name:"访问次数",
|
||||
min:minY - 1,
|
||||
max:maxY + 1,
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: "WEB端",
|
||||
type: "bar",
|
||||
barWidth:"13%",
|
||||
itemStyle: {
|
||||
color:"#357efe"
|
||||
},
|
||||
data:result.map(item => item?.webCount || 0),
|
||||
},
|
||||
{
|
||||
name: "移动端",
|
||||
type: "bar",
|
||||
barWidth:"13%",
|
||||
|
||||
itemStyle: {
|
||||
color:"#62dffe"
|
||||
},
|
||||
data:result.map(item => item?.appCount || 0),
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
export default function userLineOption(data) {
|
||||
const appList = data.appList.map(item => ({
|
||||
...item, appCount: item?.count
|
||||
}))
|
||||
const webList = data.webList.map(item => ({
|
||||
...item, webCount: item?.count
|
||||
}))
|
||||
const arr = [...appList,...webList]
|
||||
const compareLength = appList.length - webList.length;
|
||||
// 找出长度大的数组
|
||||
const mapArr1 = compareLength >= 0 ? appList : webList;
|
||||
// 找出长度小的数组
|
||||
const mapArr2 = compareLength < 0 ? appList : webList;
|
||||
|
||||
const maxY = Math.ceil(Math.max(...arr.map(item => item.count)))
|
||||
const minY = Math.floor(Math.min(...arr.map(item => item.count)))
|
||||
const result = mapArr1.map(item => {
|
||||
let filterData = mapArr2.find(o => item.createDate == o.createDate)
|
||||
return {
|
||||
...item,
|
||||
...filterData,
|
||||
}
|
||||
})
|
||||
return {
|
||||
grid: {
|
||||
top: "15%",
|
||||
bottom:"20%"
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "axis",
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
top:"0%"
|
||||
},
|
||||
|
||||
calculable: true,
|
||||
xAxis: [
|
||||
{
|
||||
type: "category",
|
||||
data: result.map(item => item.createDate),
|
||||
},
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: "value",
|
||||
min:minY - 1,
|
||||
max:maxY + 1,
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: "WEB端",
|
||||
type: "line",
|
||||
smooth:true,
|
||||
itemStyle: {
|
||||
color:"#357efe"
|
||||
},
|
||||
label: {
|
||||
normal: {
|
||||
show: true,
|
||||
position: "top",
|
||||
},
|
||||
},
|
||||
|
||||
data: result.map(item => item?.webCount || 0),
|
||||
},
|
||||
{
|
||||
name: "移动端",
|
||||
type: "line",
|
||||
smooth:true,
|
||||
itemStyle: {
|
||||
color:"#62dffe"
|
||||
},
|
||||
label: {
|
||||
normal: {
|
||||
show: true,
|
||||
position: "top",
|
||||
},
|
||||
},
|
||||
|
||||
data: result.map(item => item?.appCount || 0),
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
import React, { Fragment, useRef, useMemo,useEffect,useState } from 'react';
|
||||
import { Table, Card, Row, Col, Divider, Empty } from 'antd';
|
||||
import apiurl from '../../service/apiurl';
|
||||
|
||||
import usePageTable from '../../components/crud/usePageTable2';
|
||||
import { paginate_noCode } from '../../components/crud/_';
|
||||
|
||||
// 页面初始默认查询参数
|
||||
const options = {
|
||||
search:{
|
||||
// year:moment().format('YYYY')
|
||||
},
|
||||
};
|
||||
const Page = () => {
|
||||
const refModal = useRef();
|
||||
const isRender = useRef(true)
|
||||
const [searchVal, setSearchVal] = useState({year:options.search.year})
|
||||
|
||||
const columns = [
|
||||
{ title: '序号', key: 'inx', dataIndex: 'inx', width: 100, align:"center" },
|
||||
{ title: '用户', key: 'name', dataIndex: 'name', width: 200 },
|
||||
{ title: '页面', key: 'menu1', dataIndex: 'menu1', width: 300, render:(i,row)=>{
|
||||
return (row.menu1?row.menu1:'')+(row.menu2?('-'+row.menu2):'')+(row.menu3?('-'+row.menu3):'')
|
||||
}},
|
||||
{ title: '时间', key: 'createTime', dataIndex: 'createTime', width: 150},
|
||||
];
|
||||
|
||||
const width = useMemo(() => columns.reduce((total, cur) => total + (cur.width), 0), [columns]);
|
||||
const { tableProps, search, refresh } = usePageTable((params)=>paginate_noCode(apiurl.systemM.yhxwrz.page,params),options);
|
||||
|
||||
useEffect(()=>{
|
||||
// if(isRender.current){
|
||||
// isRender.current = false
|
||||
// return
|
||||
// }
|
||||
|
||||
const params = {
|
||||
search: {
|
||||
...searchVal
|
||||
}
|
||||
};
|
||||
search(params)
|
||||
|
||||
},[searchVal])
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='content-root clearFloat xybm' style={{paddingRight:"0",paddingBottom:"0"}}>
|
||||
<div className='AdcdTreeTableBox'>
|
||||
{/* <Card className='nonebox'>
|
||||
<ToolBar setSearchVal={setSearchVal}/>
|
||||
</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>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Page;
|
||||
Loading…
Reference in New Issue