Compare commits

..

1 Commits

Author SHA1 Message Date
秦子超 3b2a1445c7 提交 2025-11-21 09:49:24 +08:00
35 changed files with 972 additions and 2138 deletions

View File

@ -1,3 +1,3 @@
GENERATE_SOURCEMAP=true GENERATE_SOURCEMAP=true
PUBLIC_URL=/tsg PUBLIC_URL=/tsg
REACT_APP_API_URL=http://223.75.53.141:83 REACT_APP_API_URL=http://local.gunshiiot.com:18083

View File

@ -1,3 +1,3 @@
GENERATE_SOURCEMAP=false GENERATE_SOURCEMAP=false
PUBLIC_URL=/tsg PUBLIC_URL=/tsg
REACT_APP_API_URL=http://223.75.53.141:83 REACT_APP_API_URL=http://local.gunshiiot.com:18083

1
.gitignore vendored
View File

@ -24,7 +24,6 @@ yarn-debug.log*
yarn-error.log* yarn-error.log*
yarn.lock yarn.lock
build.7z build.7z
build1.zip
#ai #ai
.serena/ .serena/

File diff suppressed because one or more lines are too long

View File

View File

@ -13,124 +13,56 @@ import { currentBreadcrumbs } from '../../models/auth/_';
import {page} from '../../service/warn'; import {page} from '../../service/warn';
import { qryBasicWatershedDetailApi } from "../../service/preplan"; import { qryBasicWatershedDetailApi } from "../../service/preplan";
import moment from "moment" import moment from "moment"
import { httppostAuth } from '../../utils/request'; import { httppost2 } from '../../utils/request';
import apiurl from '../../service/apiurl'; import apiurl from '../../service/apiurl';
const { Header, Content, Sider } = Layout; const { Header, Content, Sider } = Layout;
const meunObj:any = { const meunObj:any = {
'home':'水库一张图', 'home':'基本情况',
'sq':'四全', 'fxzb':'防汛准备',
'qfg':'全覆盖', 'sxfd':'思想发动',
'zcdjxx':'注册登记信息', 'fxkhgzh':'防汛抗旱工作会',
'qys':'全要素', 'fbzrh':'防办主任会',
'kqys':'库区要素', 'fxpxb':'防汛培训班',
'gcys':'工程要素', 'fxtj':'防汛图件',
'xyys': '下游要素', 'zzjg':'组织机构',
'qth':"全天候", 'zq':'政区',
'sksq':"水库水情", 'gc':'工程',
'hdsq': "河道水情", 'gczx':'工程整修',
'ssyq':'实时水情',
'trsq':'土壤墒情',
'skyh':'水库溢洪',
'spjk':'视频监控',
'ytygc':'已投运工程', 'ytygc':'已投运工程',
'qzq':'全周期', 'zjgc':'在建工程',
'gcdsj':'工程大事记', 'hdqz':'河道清障',
'qzqda':'全周期档案', 'yaxb':'预案修编',
'sz':'四制', 'zqya':'政区预案',
'gltx':'管理体系', 'ytygcya':'已投运工程预案',
'zzjgck':'组织机构查看', 'zjgcya':'在建工程预案',
'zrrgl': '责任人管理', 'hsddya':'洪水调度方案',
'pxgl':'培训管理',
'pxjhgl':'培训计划管理',
'pxjlgl':'培训记录管理',
'szzf':'水政执法',
'ajdj':'案件登记',
'ajtj':'案件统计',
'clyj':'处理依据',
'jdkh':'监督考核',
'khtj':'考核统计',
'khrwgl':'考核任务管理',
'khwtzg':'考核问题整改',
'khzbgl':'考核指标管理',
'khmbgl':'考核模版管理',
'zdgl':'制度管理',
'flfg':'法律法规',
'zsk':'知识库',
'ddfa':'调度方案库',
'ywgz':'业务规则库',
'gcaq':'工程安全知识库',
'sy':'四预',
'fhxzfx': '防洪形式',
'tqyb': '天气预报',
'hsyb':'洪水预报',
'hyybjs':'洪水预报计算',
'ybfagl':'预报方案管理',
'csgl': '参数管理',
'hsyj':'洪水预警',
'yjxx':'预警信息',
'gzpz': '规则配置',
'hsyy':'洪水预演',
'fxya':'防汛预案',
'ddgc':'调度规程',
'qxdw':'抢险队伍', 'qxdw':'抢险队伍',
'qxwl': '抢险物料', 'qxwl':'抢险物料',
'sg':"四管", 'jczw':'检测站网',
'xcxj':"巡查巡检", 'yqz':'雨情站',
'xcrw':"巡查任务", 'sqz':'水情站',
'xjwtcl':"巡查问题处理",
'xjxpz':"巡检项配置",
'aqgl':"安全管理",
'fxgkqd':"风险管控清单",
'aqyhpc':"安全隐患排查",
'aqjcgl':"安全检查管理",
'aqsgdj':"安全事故登记",
'aqjdtz':"安全鉴定台帐",
'cxjgtz':"除险加固台帐",
'byfz':"白蚁防治",
'bypc':"白蚁监测",
'byxc':"防治宣传",
'zmjk':"闸门监控",
'wxyh':"维修养护",
'zbgl':"值班管理",
'zbb':'值班表', 'zbb':'值班表',
'zbrz':'值班日志', 'txl':'通讯录',
'btbb':'报表管理', 'ysgzq':'雨水工灾情',
'sdjyrbb':'时段降雨日报表', 'ssyq':'实时雨情',
'rjylnbb':'日降雨量年报表', 'sssq':'实时水情',
'sdswbb':'时段水位日报表', 'ssgq':'实时工情',
'rjswbb':'日均水位年报表', 'yxqk':'运行情况',
'dbaq':'告警管理', 'gcxq':'工程险情',
'aigj':'AI告警', 'dbaq':'大坝安全监测数据',
'gbyj':'广播预警', 'sszq':'实时灾情',
'gcaqjc':'工程安全监测', 'fxdd':'防汛调度',
'bzt':'布置图', 'dqxsfx':'当前形势分析',
'gcaqfx':'工程安全分析', 'tqyb':'天气预报',
'jrx':'浸润线', 'hsyb':'洪水预报',
'gcaqyj':'工程安全预警', 'skhs':'水库洪水',
'yhyj':'隐患预警', 'hdhs':'河道洪水',
'yjgzpz':'预警规则配置', 'ddjc':'调度决策',
'sjtjcx':'数据统计查询', 'yjxy':'应急响应',
'sjlr':'人工监测数据录入', 'ddzl':'调度指令',
'czcx':'测值查询', 'videoSurveillance':'视频监控',
'syjx':'渗压监测', 'fxdp':'防汛大屏',
'sljx':'渗流监测',
'wyjx':'位移监测',
'ndsytjb':'年度渗压统计表',
'ndsltjb':'年度渗流统计表',
'ndwytjb':'年度位移统计表',
'szydd':'水资源调度',
'gsnlfx':'供水能力分析',
'diaodu':'调度记录',
'gstjfx':'供水统计分析',
'dxnjyzl':'典型年降雨资料',
'skzfzl': '水库蒸发资料',
'sys':'系统管理',
'user':'用户管理',
'department':'部门管理',
'role':'角色管理',
'menuM':'菜单管理',
'loginLog':'登录日志',
} }
@ -181,25 +113,31 @@ const DashboardLayout: React.FC = () => {
// 这个方法是统计菜单点击情况的 // 这个方法是统计菜单点击情况的
useEffect(()=>{ // useEffect(()=>{
(async()=>{ // (async()=>{
const list = location.pathname.split('/') // const list = location.pathname.split('/')
let menu1:any = meunObj?.[list[2]] //一级菜单 // let menu1:any = meunObj?.[list[2]]
let menu2:any = meunObj?.[list[3]] //二级菜单 // let menu2:any = meunObj?.[list[3]]
let menu3:any = meunObj?.[list[4]] //三级菜单 // let menu3:any = meunObj?.[list[4]]
if(menu1==='水库一张图'){ // if(menu1==='基本情况'){
menu2 = '水库一张图' // menu2 = '基本情况'
} // }
// if(menu1==='视频监控'){
// menu2 = '视频监控'
// }
// if(menu1==='防汛大屏'){
// menu2 = '防汛大屏'
// }
const res = await httppostAuth(apiurl.setMenu,{ // const res = await httppost2(apiurl.setMenu,{
createId:localStorage.getItem('userId'), // createId:localStorage.getItem('userId'),
loginType:0, // loginType:0,
menu1:menu1, // menu1:menu1,
menu2:menu2, // menu2:menu2,
menu3:menu3 // menu3:menu3
}) // })
})() // })()
},[location.pathname]) // },[location.pathname])
const menuIndexes = useMemo(() => findMenu(menu, pathname), [menu, pathname]); const menuIndexes = useMemo(() => findMenu(menu, pathname), [menu, pathname]);

View File

@ -2,7 +2,6 @@ import { FC, useEffect, useRef, useState } from 'react'
// import styles from './index.module.less' // import styles from './index.module.less'
import { message, Spin } from "antd"; import { message, Spin } from "antd";
import EZUIKit from 'ezuikit-js'; import EZUIKit from 'ezuikit-js';
import moment from 'moment';
/** /**
* 海康视频H5插件视频播放 * 海康视频H5插件视频播放
@ -24,16 +23,10 @@ const HFivePlayer = ({ wsUrl, playerID, size }) => {
const initVideo = () => { 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({ playerYsy.current = new EZUIKit.EZUIKitPlayer({
id: 'player' + playerID, // 视频容器ID id: 'player' + playerID, // 视频容器ID
accessToken: wsUrl.src, accessToken: wsUrl.src,
url: ezUrl, url: `ezopen://open.ys7.com/${wsUrl.indexCode}/1.live`,
// plugin: ["talk"], // 加载插件talk-对讲 // plugin: ["talk"], // 加载插件talk-对讲
width: parentRef.current?.offsetWidth, width: parentRef.current?.offsetWidth,
height: parentRef.current?.offsetHeight, height: parentRef.current?.offsetHeight,
@ -140,13 +133,6 @@ const HFivePlayer = ({ wsUrl, playerID, size }) => {
if (wsUrl?.src) { if (wsUrl?.src) {
setIsLoading(true) //开始加载 setIsLoading(true) //开始加载
let preUrl = wsUrl?.src // 播放地址 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); console.log(preUrl);
const param = { const param = {
playURL: preUrl, playURL: preUrl,

View File

@ -49,15 +49,6 @@ const apiurl = {
view:baseFileView view:baseFileView
}, },
systemM: { 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: { userM: {
updatePassword:service_xyt + '/system/user/profile/updatePwd' updatePassword:service_xyt + '/system/user/profile/updatePwd'
} }
@ -235,17 +226,6 @@ 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: { fxzb1: {
ddgc: { ddgc: {
@ -559,12 +539,9 @@ const apiurl = {
}, },
zfzl: { zfzl: {
list: service_fxdd + "/gateValveReal/list", list: service_fxdd + "/gateValveReal/list",
list1: service_fxdd + "/gate/list",
historypage: service_fxdd + '/gateValveReal/log/page', historypage: service_fxdd + '/gateValveReal/log/page',
historypage1: service_fxdd + '/gate/page/history',
historyList: service_fxdd + '/gateValveReal/log/loglist', historyList: service_fxdd + '/gateValveReal/log/loglist',
historyPageExport: service_fxdd + '/gateValveReal/log/exp', historyPageExport: service_fxdd + '/gateValveReal/log/exp',
historyPageExport1: service_fxdd + '/gate/exp',
swInfo:service_fxdd + '/reservoir/water/waterInfo', swInfo:service_fxdd + '/reservoir/water/waterInfo',
krlist: service_fxdd + "/reservoir/water/data", krlist: service_fxdd + "/reservoir/water/data",
info: service_fxdd + "/attGateValve/detail", info: service_fxdd + "/attGateValve/detail",
@ -593,7 +570,6 @@ const apiurl = {
spjk1: { spjk1: {
aiWarn: { aiWarn: {
page: service_fxdd + "/stImgWarnR/page", page: service_fxdd + "/stImgWarnR/page",
page1: service_fxdd + "/iscaiEvent/page",
list: service_fxdd + "/attCctvBase/list", list: service_fxdd + "/attCctvBase/list",
controler:service_fxdd + "/attCctvBase/control" controler:service_fxdd + "/attCctvBase/control"
} }

View File

@ -21,7 +21,6 @@ function request(url, options,type) {
const opt = { ...options }; const opt = { ...options };
opt.headers = opt.headers || {}; opt.headers = opt.headers || {};
opt.headers.Accept = 'application/json'; opt.headers.Accept = 'application/json';
// opt.headers.Authorization = "Bearer" + ' ' + localStorage.getItem('access_token');
// opt.credentials = opt.credentials || 'include'; // opt.credentials = opt.credentials || 'include';
return fetch(url, opt) return fetch(url, opt)
@ -399,21 +398,6 @@ export function httppost2(url, data = {}) {
return send(url, options); 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 = {}) { export function httppost5(url, data = {}) {
const options = { const options = {
method: 'POST', method: 'POST',

View File

@ -21,8 +21,6 @@ import Fxya from './fxzb/fxya'
import Hsybjs from './fxzb/hsybjs' import Hsybjs from './fxzb/hsybjs'
import Ybfagl from './fxzb/ybfagl' import Ybfagl from './fxzb/ybfagl'
import Csgl from './fxzb/csgl' 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 Qxdw_Gc from './fxzb/qxdw/gc/index.js'
import Qxwl_Gc from './fxzb/qxwl/gc' import Qxwl_Gc from './fxzb/qxwl/gc'
@ -123,8 +121,6 @@ import Ywgz from './sz/ywgz'
import Gcaq from './sz/khzbgl' import Gcaq from './sz/khzbgl'
//系统管理 //系统管理
import SystemPage from './systemMange' import SystemPage from './systemMange'
import Yhxwrz from './yhxwrz'
import Yhxwfx from './yhxwfx'
const HomePage = lazy(() => import('./Home')) const HomePage = lazy(() => import('./Home'))
@ -166,10 +162,6 @@ const AppRouters: React.FC = () => {
{ path: 'sy/hsyb/ybfagl', element: <Ybfagl /> }, { path: 'sy/hsyb/ybfagl', element: <Ybfagl /> },
{ path: 'sy/hsyb/csgl', element: <Csgl /> }, { path: 'sy/hsyb/csgl', element: <Csgl /> },
// 四预-洪水预警
{ path: 'sy/hsyj/yjxx', element: <Yjxx/> },
{ path: 'sy/hsyj/gzpz', element: <Gzpz /> },
// 调度规程 // 调度规程
{ path: 'sy/ddgc', element: <Ddgc /> }, { path: 'sy/ddgc', element: <Ddgc /> },
@ -306,8 +298,6 @@ const AppRouters: React.FC = () => {
{ path: 'sys/role', element: <SystemPage src={'/mgr/home/role'}/> }, { path: 'sys/role', element: <SystemPage src={'/mgr/home/role'}/> },
{ path: 'sys/menuM', element: <SystemPage src={'/mgr/home/menuM'}/> }, { path: 'sys/menuM', element: <SystemPage src={'/mgr/home/menuM'}/> },
{ path: 'sys/loginLog', element: <SystemPage src={'/mgr/home/loginLog'}/> }, { path: 'sys/loginLog', element: <SystemPage src={'/mgr/home/loginLog'}/> },
{ path: 'sys/yhxwrz', element: <Yhxwrz /> },
{ path: 'sys/yhxwfx', element: <Yhxwfx /> },
], ],
}, },
{ path: '/login', element: <LoginPage /> }, { path: '/login', element: <LoginPage /> },

View File

@ -357,6 +357,8 @@ export default class Map3D extends BaseMap {
// this.demo.getCzml2(viewer) //demo // this.demo.getCzml2(viewer) //demo
// demo.getWater(viewer)//水面 // demo.getWater(viewer)//水面
// this.demo.getWater3(viewer) // this.demo.getWater3(viewer)
// this.demo.getWater4(viewer)
// this.demo.getWAter5(viewer)
// demo.getTool(viewer)//工具 // demo.getTool(viewer)//工具
// await this.demo.getWater2(viewer,[ // await this.demo.getWater2(viewer,[

View File

@ -258,63 +258,127 @@ export default class LayerMgr {
//全村的希望 //全村的希望
async getWater3(viewer) { async getWater3(viewer) {
// baseWaterColor: new Cesium.Color(64 / 255.0, 157 / 255.0, 253 / 255.0, 1), // 水的基本颜色
// normalMap: normalMap,
// // normalMap: Cesium.buildModuleUrl(
// // `${process.env.PUBLIC_URL}/models/waternormals.jpg`
// // ),
// frequency: 1000.0,
// animationSpeed: 0.01,
// amplitude: 10,
// specularIntensity: 1, // 镜面反射强度
const simpleWaterMaterial = new Cesium.Material({ const simpleWaterMaterial = new Cesium.Material({
fabric: { fabric: {
type: 'FixedWater', type: 'AdvancedWater',
uniforms: { uniforms: {
color: new Cesium.Color(64 / 255.0, 157 / 255.0, 253 / 255.0, 1), baseWaterColor: new Cesium.Color(0.2, 0.4, 0.7, 0.85),
highlightColor: new Cesium.Color(0.5, 0.8, 1.0, 1), specularColor: new Cesium.Color(1.0, 1.0, 1.0, 1.0),
speed: 0.01, reflectionColor: new Cesium.Color(0.3, 0.6, 0.9, 1.0),
// frequency: 50.0 smallWaveSpeed: 0.05,
bigWaveSpeed: 0.02,
frequency: 1000.0, smallWaveFrequency: 800.0,
animationSpeed: 0.01, bigWaveFrequency: 200.0,
amplitude: 10, waveAmplitude: 5.0,
specularIntensity: 1, // 镜面反射强度 foamThreshold: 0.4,
time: 0.0
}, },
source: source: `
// 简单的噪声函数
float noise(vec2 p) {
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
}
// 2D噪声函数
float noise2D(vec2 p) {
vec2 i = floor(p);
vec2 f = fract(p);
f = f * f * (3.0 - 2.0 * f);
float a = noise(i);
float b = noise(i + vec2(1.0, 0.0));
float c = noise(i + vec2(0.0, 1.0));
float d = noise(i + vec2(1.0, 1.0));
return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
}
// 分形噪声
float fbm(vec2 p) {
float value = 0.0;
float amplitude = 0.5;
float frequency = 1.0;
for(int i = 0; i < 4; i++) {
value += amplitude * noise2D(p * frequency);
amplitude *= 0.5;
frequency *= 2.0;
}
return value;
}
czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st * 3.0;
float time = czm_frameNumber * 0.005;
// 大波浪 - 主要形状
float bigWave1 = sin(st.x * bigWaveFrequency + time * bigWaveSpeed) *
cos(st.y * bigWaveFrequency * 0.7 + time * bigWaveSpeed * 1.3);
float bigWave2 = cos(st.x * bigWaveFrequency * 0.8 - st.y * bigWaveFrequency * 1.2 +
time * bigWaveSpeed * 0.7) * 0.7;
// 小波浪 - 细节
float smallWave1 = fbm(vec2(st.x * smallWaveFrequency + time,
st.y * smallWaveFrequency)) * 0.5;
float smallWave2 = fbm(vec2(st.x * smallWaveFrequency * 1.7 - time * 0.7,
st.y * smallWaveFrequency * 1.3)) * 0.3;
// 组合波浪
float totalWave = (bigWave1 * 0.6 + bigWave2 * 0.4 +
smallWave1 * 0.3 + smallWave2 * 0.2) * waveAmplitude;
// 计算法线 - 使用波浪梯度
vec2 eps = vec2(0.001, 0.0);
float h1 = sin((st.x + eps.x) * bigWaveFrequency + time) *
cos(st.y * bigWaveFrequency * 0.7 + time);
float h2 = sin(st.x * bigWaveFrequency + time) *
cos((st.y + eps.x) * bigWaveFrequency * 0.7 + time);
vec3 normal = normalize(vec3(h1 - totalWave, h2 - totalWave, 1.0));
// 基于法线的光照计算
vec3 lightDir = czm_sunDirectionEC;
float diffuse = max(dot(normal, lightDir), 0.0);
// 高光计算
vec3 viewDir = vec3(0.0, 0.0, 1.0); // 简化视角方向
vec3 halfDir = normalize(lightDir + viewDir);
float specular = pow(max(dot(normal, halfDir), 0.0), 120.0) * 1.5;
// 泡沫生成 - 基于波浪陡度
float foam = smoothstep(foamThreshold, 1.0, abs(totalWave));
// 深度效果 - 模拟浅水和深水
float depthEffect = 1.0 - smoothstep(0.0, 1.0, st.y);
vec3 deepWaterColor = baseWaterColor.rgb * 0.7;
vec3 shallowWaterColor = baseWaterColor.rgb * 1.3;
vec3 waterBase = mix(deepWaterColor, shallowWaterColor, depthEffect);
// 颜色混合
vec3 diffuseColor = waterBase * (diffuse * 0.6 + 0.4);
vec3 specularColor = specularColor.rgb * specular;
vec3 foamColor = mix(diffuseColor, vec3(1.0), foam * 0.3);
// 最终颜色
material.diffuse = foamColor + specularColor;
// 透明度 - 边缘更透明
float edgeAlpha = 1.0 - smoothstep(0.0, 0.2, min(min(st.x, st.y), min(1.0-st.x, 1.0-st.y)));
material.alpha = baseWaterColor.a * (0.9 - edgeAlpha * 0.3);
// 材质属性
material.normal = normal;
material.specular = min(specular * 2.0, 1.0);
material.shininess = 100.0;
return material;
}
` `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
float time = czm_frameNumber * speed;
// 创建多层波纹
float wave1 = sin(st.x * frequency * 2.0 + st.y * frequency + time) * 0.4;
float wave2 = cos(st.x * frequency * 1.5 - st.y * frequency * 1.2 + time * 1.7) * 0.3;
float wave3 = sin(st.x * frequency * 3.0 + st.y * frequency * 0.8 + time * 0.6) * 0.2;
float combinedWave = (wave1 + wave2 + wave3) / 3.0;
// 颜色混合 - 基础色与高光色
vec3 waterColor = mix(color.rgb, highlightColor.rgb,
abs(combinedWave) * 2.0);
// 透明度变化
float alpha = color.a * (0.6 + combinedWave * 0.4);
material.diffuse = waterColor;
material.alpha = alpha;
material.specular = 0.7 + combinedWave * 0.3;
material.shininess = 50.0; // 增加光泽度
return material;
}
`
} }
}); });
// 创建水面Primitive // 创建水面Primitive
const waterPrimitive = new Cesium.Primitive({ const waterPrimitive = new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({ geometryInstances: new Cesium.GeometryInstance({
@ -401,6 +465,152 @@ export default class LayerMgr {
waterPrimitive2.show = true waterPrimitive2.show = true
} }
getWater4(viewer) {
const realisticWaterMaterial = new Cesium.Material({
fabric: {
type: 'AdvancedWater',
uniforms: {
baseWaterColor: new Cesium.Color(0.2, 0.4, 0.7, 0.85),
specularColor: new Cesium.Color(1.0, 1.0, 1.0, 1.0),
reflectionColor: new Cesium.Color(0.3, 0.6, 0.9, 1.0),
smallWaveSpeed: 0.05,
bigWaveSpeed: 0.02,
smallWaveFrequency: 1000.0,
bigWaveFrequency: 100.0,
waveAmplitude: 0.5,
foamThreshold: 0.2,
time: 0.0
},
source: `
// 简单的噪声函数
float noise(vec2 p) {
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
}
// 2D噪声函数
float noise2D(vec2 p) {
vec2 i = floor(p);
vec2 f = fract(p);
f = f * f * (3.0 - 2.0 * f);
float a = noise(i);
float b = noise(i + vec2(1.0, 0.0));
float c = noise(i + vec2(0.0, 1.0));
float d = noise(i + vec2(1.0, 1.0));
return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
}
// 分形噪声
float fbm(vec2 p) {
float value = 0.0;
float amplitude = 0.5;
float frequency = 1.0;
for(int i = 0; i < 4; i++) {
value += amplitude * noise2D(p * frequency);
amplitude *= 0.5;
frequency *= 2.0;
}
return value;
}
czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st * 3.0;
float time = czm_frameNumber * 0.005;
// 大波浪 - 主要形状
float bigWave1 = sin(st.x * bigWaveFrequency + time * bigWaveSpeed) *
cos(st.y * bigWaveFrequency * 0.7 + time * bigWaveSpeed * 1.3);
float bigWave2 = cos(st.x * bigWaveFrequency * 0.8 - st.y * bigWaveFrequency * 1.2 +
time * bigWaveSpeed * 0.7) * 0.7;
// 小波浪 - 细节
float smallWave1 = fbm(vec2(st.x * smallWaveFrequency + time,
st.y * smallWaveFrequency)) * 0.5;
float smallWave2 = fbm(vec2(st.x * smallWaveFrequency * 1.7 - time * 0.7,
st.y * smallWaveFrequency * 1.3)) * 0.3;
// 组合波浪
float totalWave = (bigWave1 * 0.6 + bigWave2 * 0.4 +
smallWave1 * 0.3 + smallWave2 * 0.2) * waveAmplitude;
// 计算法线 - 使用波浪梯度
vec2 eps = vec2(0.001, 0.0);
float h1 = sin((st.x + eps.x) * bigWaveFrequency + time) *
cos(st.y * bigWaveFrequency * 0.7 + time);
float h2 = sin(st.x * bigWaveFrequency + time) *
cos((st.y + eps.x) * bigWaveFrequency * 0.7 + time);
vec3 normal = normalize(vec3(h1 - totalWave, h2 - totalWave, 1.0));
// 基于法线的光照计算
vec3 lightDir = czm_sunDirectionEC;
float diffuse = max(dot(normal, lightDir), 0.0);
// 高光计算
vec3 viewDir = vec3(0.0, 1.0, 0.0); // 简化视角方向
vec3 halfDir = normalize(viewDir);
float specular = pow(max(dot(normal, halfDir), 0.0), 120.0) * 1.5;
// 泡沫生成 - 基于波浪陡度
float foam = smoothstep(foamThreshold, 1.0, abs(totalWave));
// 深度效果 - 模拟浅水和深水
float depthEffect = 1.0 - smoothstep(0.0, 1.0, st.y);
vec3 deepWaterColor = baseWaterColor.rgb * 0.7;
vec3 shallowWaterColor = baseWaterColor.rgb * 1.3;
vec3 waterBase = mix(deepWaterColor, shallowWaterColor, depthEffect);
// 颜色混合
vec3 diffuseColor = waterBase * (diffuse * 0.6 + 0.4);
vec3 specularColor = specularColor.rgb * specular;
vec3 foamColor = mix(diffuseColor, vec3(1.0), foam * 0.3);
// 最终颜色
material.diffuse = foamColor + specularColor;
// 透明度 - 边缘更透明
float edgeAlpha = 1.0 - smoothstep(0.0, 0.2, min(min(st.x, st.y), min(1.0-st.x, 1.0-st.y)));
material.alpha = baseWaterColor.a * (0.9 - edgeAlpha * 0.3);
// 材质属性
material.normal = normal;
material.specular = min(specular * 2.0, 1.0);
material.shininess = 100.0;
return material;
}
`
}
});
// 创建水面Primitive
const waterPrimitive = new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(
Cesium.Cartesian3.fromDegreesArrayHeights([
114.76352489831815,31.494754219571522,80,114.76520120583086,31.4999564874016,80,114.76980240861486,31.498491685970183,80,114.77288986029524,31.499291609035314,80,114.7752374682663,31.497030189270138,80,114.77496372060254,31.49482620567726,80,114.77471997997016,31.490858103316754,80,114.77276936030704,31.48685100847121,80,114.77069081826704,31.483979297273798,80,114.76965049062629,31.48370282132599,80,114.76441718716531,31.48255871323312,80,114.76372798131092,31.47900692403831,80,114.76293736420705,31.477822176429328,80,114.75120596797079,31.471419526420515,80,114.75038568642819,31.469139708715907,80,114.74958949458313,31.46814991520691,80,114.74789070463534,31.468121367311053,80,114.7471786876506,31.466373139201135,80,114.74930655086952,31.461932951570883,80,114.74805372401946,31.458130678122178,80,114.7445797538948,31.45414539792457,80,114.73993504386465,31.45124971272249,80,114.73636690633312,31.452374249551728,80,114.73813467149844,31.456832583528676,80,114.74095195126414,31.460165343908727,80,114.74011304826205,31.464062436365865,80,114.73995399997894,31.46681589187651,80,114.74014787758605,31.470080972179417,80,114.74046551608743,31.47381704756393,80,114.74421736191424,31.47792376112243,80,114.7520809314138,31.483752378529545,80,114.7580325301891,31.49028179289772,80,114.76385167039098,31.493196679385143,80
])
),
extrudedHeight: 0.1,
perPositionHeight: true,
vertexFormat: Cesium.MaterialAppearance.VERTEX_FORMAT
})
}),
appearance: new Cesium.MaterialAppearance({
material: realisticWaterMaterial,
translucent: true
}),
show:true,
});
viewer.scene.primitives.add(waterPrimitive);
}
async getQxsy(viewer) { async getQxsy(viewer) {
try { try {
let tileset = await Cesium.Cesium3DTileset.fromUrl( let tileset = await Cesium.Cesium3DTileset.fromUrl(
@ -1732,5 +1942,169 @@ export default class LayerMgr {
viewer.dataSources.add(Cesium.CzmlDataSource.load(czml)); viewer.dataSources.add(Cesium.CzmlDataSource.load(czml));
viewer.clock.shouldAnimate = false; // 暂停动画 viewer.clock.shouldAnimate = false; // 暂停动画
} }
async getWAter5(viewer) {
const realisticWaterMaterial = new Cesium.Material({
fabric: {
type: 'AdvancedWater',
uniforms: {
baseWaterColor: new Cesium.Color(0.2, 0.4, 0.7, 0.85),
specularColor: new Cesium.Color(1.0, 1.0, 1.0, 1.0),
reflectionColor: new Cesium.Color(0.3, 0.6, 0.9, 1.0),
smallWaveSpeed: 0.5,
bigWaveSpeed: 0.2,
smallWaveFrequency: 1000.0, // 调整频率以适应世界坐标
bigWaveFrequency: 1000.0, // 调整频率以适应世界坐标
waveAmplitude: 1.0,
foamThreshold: 1.0,
time: 0.0
},
source: `
// 简单的噪声函数
float noise(vec2 p) {
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
}
// 2D噪声函数
float noise2D(vec2 p) {
vec2 i = floor(p);
vec2 f = fract(p);
f = f * f * (3.0 - 2.0 * f);
float a = noise(i);
float b = noise(i + vec2(1.0, 0.0));
float c = noise(i + vec2(0.0, 1.0));
float d = noise(i + vec2(1.0, 1.0));
return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
}
// 分形噪声
float fbm(vec2 p) {
float value = 0.0;
float amplitude = 0.5;
float frequency = 1.0;
for(int i = 0; i < 4; i++) {
value += amplitude * noise2D(p * frequency);
amplitude *= 0.5;
frequency *= 2.0;
}
return value;
}
czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
// 获取世界坐标 - 使用正确的方法
vec4 worldPosition = czm_inverseModelView * vec4(materialInput.positionToEyeEC, 1.0);
vec3 worldPos = worldPosition.xyz;
// 使用世界坐标的x和z分量忽略y分量因为水面是水平的
vec2 worldCoord = worldPos.xz / 100000.0; // 缩放以适应波浪频率
// 使用系统时间确保所有Primitive使用相同的时间
float time = czm_frameNumber * 0.005;
// 大波浪 - 主要形状
float bigWave1 = sin(worldCoord.x * bigWaveFrequency + time * bigWaveSpeed) *
cos(worldCoord.y * bigWaveFrequency * 0.7 + time * bigWaveSpeed * 1.3);
float bigWave2 = cos(worldCoord.x * bigWaveFrequency * 0.8 - worldCoord.y * bigWaveFrequency * 1.2 +
time * bigWaveSpeed * 0.7) * 0.7;
// 小波浪 - 细节
float smallWave1 = fbm(vec2(worldCoord.x * smallWaveFrequency + time,
worldCoord.y * smallWaveFrequency)) * 0.5;
float smallWave2 = fbm(vec2(worldCoord.x * smallWaveFrequency * 1.7 - time * 0.7,
worldCoord.y * smallWaveFrequency * 1.3)) * 0.3;
// 组合波浪
float totalWave = (bigWave1 * 0.6 + bigWave2 * 0.4 +
smallWave1 * 0.3 + smallWave2 * 0.2) * waveAmplitude;
// 计算法线 - 使用波浪梯度
vec2 eps = vec2(0.001, 0.0);
float h1 = sin((worldCoord.x + eps.x) * bigWaveFrequency + time) *
cos(worldCoord.y * bigWaveFrequency * 0.7 + time);
float h2 = sin(worldCoord.x * bigWaveFrequency + time) *
cos((worldCoord.y + eps.x) * bigWaveFrequency * 0.7 + time);
vec3 normal = normalize(vec3(h1 - totalWave, h2 - totalWave, 1.0));
// 基于法线的光照计算
vec3 lightDir = czm_sunDirectionEC;
float diffuse = max(dot(normal, lightDir), 0.0);
// 高光计算
vec3 viewDir = normalize(materialInput.positionToEyeEC);
vec3 reflectDir = reflect(-lightDir, normal);
float specular = pow(max(dot(viewDir, reflectDir), 0.0), 120.0) * 1.5;
// 泡沫生成 - 基于波浪陡度
float foam = smoothstep(foamThreshold, 1.0, abs(totalWave));
// 使用固定的水颜色,不再依赖纹理坐标
vec3 waterBase = baseWaterColor.rgb;
// 颜色混合
vec3 diffuseColor = waterBase * (diffuse * 0.6 + 0.4);
vec3 specularColor = specularColor.rgb * specular;
vec3 foamColor = mix(diffuseColor, vec3(1.0), foam * 0.3);
// 最终颜色
material.diffuse = foamColor + specularColor;
// 固定的透明度
material.alpha = baseWaterColor.a;
// 材质属性
material.normal = normal;
material.specular = min(specular * 2.0, 1.0);
material.shininess = 100.0;
return material;
}
`
}
});
const { czml } = await fetch(`${process.env.PUBLIC_URL}/data/json/czml3.json`)
.then(resp => resp.json())
.then(data => data)
.catch(() => []);
const waterPrimitiveList = czml.map((item,index)=>{
// 创建水面Primitive
const waterPrimitive = new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(
Cesium.Cartesian3.fromDegreesArrayHeights(
item.cartographicDegrees
)
),
extrudedHeight: 0.1,
perPositionHeight: true,
vertexFormat: Cesium.MaterialAppearance.VERTEX_FORMAT
})
}),
appearance: new Cesium.MaterialAppearance({
material: realisticWaterMaterial,
translucent: true
}),
show:index===false,
});
waterPrimitive.id = 'myWater_'+index
viewer.scene.primitives.add(waterPrimitive)
return waterPrimitive
})
await this.sleep(2000)
for(let i = 0; i < waterPrimitiveList.length; ++i) {
const item = waterPrimitiveList[i]
if(i>0){
waterPrimitiveList[i-1].show = false
}
item.show = true
await this.sleep(2000)
}
}
} }

View File

@ -121,7 +121,7 @@ const Page = ({ mySetTms }) => {
{ key==='位移告警'?<Table_wy data={dataObj.shiftWarn} onCancel={()=>setOpen(false)}/>:null } { key==='位移告警'?<Table_wy data={dataObj.shiftWarn} onCancel={()=>setOpen(false)}/>:null }
{ key==='渗压告警'?<Table_sy data={dataObj.pressWarn} 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==='渗流告警'?<Table_sl data={dataObj.flowWarn} onCancel={()=>setOpen(false)}/>:null }
{key === 'AI告警' ? <Table_AI tms={tms} /> : null} {key === 'AI告警' ? <Table_AI /> : null}
{ key==='白蚁告警'?<Table_by data={dataObj.byWarn} onCancel={()=>setOpen(false)}/>:null } { key==='白蚁告警'?<Table_by data={dataObj.byWarn} onCancel={()=>setOpen(false)}/>:null }
</div> </div>
</Modal> </Modal>

View File

@ -10,20 +10,20 @@ import apiurl from "../../../../service/apiurl";
import moment from 'moment'; import moment from 'moment';
const Page = ({ tms }) => { const Page = () => {
// 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(()=>{ useEffect(()=>{
// const params = { const params = {
// search: {} search: {}
// }; };
// search(params) search(params)
// }, []) }, [])
return ( return (
<div className="ant-card-body" style={{padding:"0 10px",height:'600px',overflowY:'auto'}}> <div className="ant-card-body" style={{padding:"0 10px",height:'600px',overflowY:'auto'}}>
<AiWarn tm={tms}/> <AiWarn/>
{/* <div>时间:{moment().format('YYYY-MM-DD HH:mm:ss')} 至 {moment().format('YYYY-MM-DD HH:mm:ss')}</div> */} {/* <div>时间:{moment().format('YYYY-MM-DD HH:mm:ss')} 至 {moment().format('YYYY-MM-DD HH:mm:ss')}</div> */}
</div> </div>
) )

View File

@ -1,177 +0,0 @@
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;

View File

@ -1,109 +0,0 @@
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;

View File

@ -1,57 +0,0 @@
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;

View File

@ -1,149 +0,0 @@
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;

View File

@ -1,105 +0,0 @@
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;

View File

@ -1,71 +0,0 @@
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;

View File

@ -1,23 +1,23 @@
import pieMonth from "./pieMonth";
export default function jrxOptions(data = {}, type = "1", typeName = '1') { export default function jrxOptions(data = {}, type = "1",typeName='1') {
// debugger // debugger
console.log("data", data); console.log("data",data);
// data.rz = 112 // data.rz = 112
// 根据断面类型确定y轴刻度以及最大和最小 // 根据断面类型确定y轴刻度以及最大和最小
const yMin = type == "3" ? 70 : type == "2" ? 67 : const yMin = type == "3" ? 70 : type == "2" ? 67 :
type == '1' ? 59 : 99; type == '1' ? 59 : 99;
const yMax = type == "3" ? 129 : type == "2" ? 117 const yMax = type == "3" ? 129 : type == "2" ? 117
: type == "1" ? 118 : 116; : type == "1" ? 118 : 116;
// 断面上的渗压管 // 断面上的渗压管
const type1 = ["UPD1", "UPD4", "UPD7", "UPD16"]; const type1 = ["UPD1", "UPD4", "UPD7", "UPD16"];
const type2 = ["UPD10", "UPD13"]; const type2 = ["UPD10", "UPD13"];
const type3 = ["UPD2", "UPD5", "UPD8", "UPD17"]; const type3 = ["UPD2", "UPD5", "UPD8", "UPD17"];
const type4 = ["UPD11", "UPD14"]; const type4 = ["UPD11", "UPD14"];
const type5 = ["UPD3", "UPD6", "UPD12"]; const type5 = ["UPD3", "UPD6", "UPD9"];
const type6 = ["UPD9", "UPD15"]; const type6 = ["UPD12", "UPD15"];
const type7 = ["UPD24", "UPD26", "UPD28"]; //UPD24:109.87,UPD26:109.75,UPD28:109.43 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 const type8 = ["UPD25", "UPD27","UPD29"]; //UPD25:109.87,UPD27:109.75,UPD29:109.43
// 管底高程 // 管底高程
const alltype = typeName == "1" ? type1 : const alltype = typeName == "1" ? type1 :
@ -28,7 +28,8 @@ export default function jrxOptions(data = {}, type = "1", typeName = '1') {
typeName == "6" ? type6 : typeName == "6" ? type6 :
typeName == "7" ? type7 : typeName == "7" ? type7 :
typeName == "8" ? type8 : typeName == "8" ? type8 :
[]; [];
// 字体颜色 // 字体颜色
const textColor = '#666' const textColor = '#666'
const imageUrl370 = `${process.env.PUBLIC_URL}/assets/images/zb370.png ` const imageUrl370 = `${process.env.PUBLIC_URL}/assets/images/zb370.png `
@ -36,8 +37,8 @@ export default function jrxOptions(data = {}, type = "1", typeName = '1') {
const imageUrl130 = `${process.env.PUBLIC_URL}/assets/images/zb130.png ` const imageUrl130 = `${process.env.PUBLIC_URL}/assets/images/zb130.png `
const imageUrl010 = `${process.env.PUBLIC_URL}/assets/images/fb010.png ` const imageUrl010 = `${process.env.PUBLIC_URL}/assets/images/fb010.png `
const imageUrl = type == "1" ? imageUrl130 : const imageUrl = type == "1" ? imageUrl130 :
type == "2" ? imageUrl250 : type == "2" ? imageUrl250 :
type == "3" ? imageUrl370 : imageUrl010 type == "3" ? imageUrl370 : imageUrl010
; ;
const rule = `${process.env.PUBLIC_URL}/assets/images/ruler.png ` const rule = `${process.env.PUBLIC_URL}/assets/images/ruler.png `
@ -58,173 +59,76 @@ export default function jrxOptions(data = {}, type = "1", typeName = '1') {
type == "1" ? type == "1" ?
[[0, 88], [10, 88], [xValue, data?.rz]] [[0, 88], [10, 88], [xValue, data?.rz]]
: :
[[0, 102], [4, 102], [xValue, data?.rz]] [[0, 102], [4, 102], [xValue, data?.rz]]
: []; : [];
// gz1、gz2、gz3、gz4分别为渗压管 // gz1、gz2、gz3、gz4分别为渗压管
const gz1 = data[alltype[0]] ?
// 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 == "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' ?76.76:77.18], [typeName =='3' ? 45.5:50, 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" ? [[44, typeName =='1' ?79.16:77.18], [44, 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]]]]
// [[55, typeName == '7' ? 109.08 : 108.77], [55, data[alltype[0]]]] : [];
// : [];
// 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, 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, 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+030typeName 为 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 gz2 = data[alltype[1]] ?
const mouth1 = pieMonth[alltype[0]]; type == "3" ? [[typeName =='5' ?51:62, typeName =='5' ?77.18:83.50], [typeName =='5' ?51:62, data[alltype[1]]]] :
const mouth2 = pieMonth[alltype[1]]; type == "2" ? [[typeName =='3' ?50:61, typeName =='3' ?77.18:77.50], [typeName =='3' ?50:61, data[alltype[1]]]] :
const mouth3 = pieMonth[alltype[2]]; type == "1" ? [[51.5, typeName =='1' ?77.18:74.5], [51.5, data[alltype[1]]]] :
const mouth4 = pieMonth[alltype[3]]; [[65, typeName =='7'?109.32:109.36], [65, data[alltype[1]]]] :
[];
// 蓝色段:从“管口(若有)/管底”到 UPD 值 const gz3 = data[alltype[2]] ?
const gz1 = data[alltype[0]] ? [[x1, baseY1], [x1, data[alltype[0]]]] : []; type == "3" ? [[62, 81.50], [62, data[alltype[2]]]] :
const gz2 = data[alltype[1]] ? [[x2, baseY2], [x2, data[alltype[1]]]] : []; type == "2" ? [[61, 80.50], [61, data[alltype[2]]]] :
const gz3 = data[alltype[2]] ? [[x3, baseY3], [x3, data[alltype[2]]]] : []; type == "1" ? [[58, 66.50], [58, data[alltype[2]]]] :
const gz4 = data[alltype[3]] && x4 !== null ? [[x4, baseY4], [x4, data[alltype[3]]]] : []; [[77, typeName =='7'?109.01:108.87], [77, data[alltype[2]]]] : [];
// 灰色段:从“管底”到“管口”(仅当 mouth 存在)
const gk1 = (mouth1 !== null && mouth1 !== undefined) ? [[x1, baseY1], [x1, mouth1]] : []; const gz4 = data[alltype[3]] ?
const gk2 = (mouth2 !== null && mouth2 !== undefined) ? [[x2, baseY2], [x2, mouth2]] : []; type == "3" ? [] :
const gk3 = (mouth3 !== null && mouth3 !== undefined) ? [[x3, baseY3], [x3, mouth3]] : []; type == "2" ? [[79, 73.50], [79, data[alltype[3]]]] :
const gk4 = (mouth4 !== null && mouth4 !== undefined && x4 !== null) ? [[x4, baseY4], [x4, mouth4]] : []; type == "1" ? [[79, 72.50], [79, data[alltype[3]]]] :
[[85, 166], [85, data[alltype[3]]]] : [];
// 将渗压管连起来的线(插入 midPts
// 将渗压管连起来的线
const line = data?.rz ? const line = data?.rz ?
type == "3" ? type == "3" ?
[ [
[xValue, data?.rz], [xValue, data?.rz],
...(rightSideOnly ? midPts : []), [typeName =='5' ?47:51, data[alltype[0]]],
[typeName == '5' ? 47 : 51, data[alltype[0]]], [typeName =='5' ?51:62, data[alltype[1]]],
...(!rightSideOnly ? midPts : []), [62, data[alltype[2]]],
[typeName == '5' ? 51 : 63, data[alltype[1]]],
[63, data[alltype[2]]],
] : ] :
type == "2" ? type == "2" ?
[ [
[xValue, data?.rz], [xValue, data?.rz],
...(rightSideOnly ? midPts : []), [typeName =='3' ? 45.5:50, data[alltype[0]]],
[typeName == '3' ? 45.5 : 50, data[alltype[0]]], [typeName =='3' ?50:61, data[alltype[1]]],
...(!rightSideOnly ? midPts : []),
[typeName == '3' ? 50 : 61, data[alltype[1]]],
[61, data[alltype[2]]], [61, data[alltype[2]]],
[79, data[alltype[3]]] [79, data[alltype[3]]]
] : ] :
type == "1" ? type == "1"?
[ [
[xValue, data?.rz], [xValue, data?.rz],
...(rightSideOnly ? midPts : []), [44, data[alltype[0]]],
[typeName == '1' ? 44 : 51.5, data[alltype[0]]], [51.5, data[alltype[1]]],
...(!rightSideOnly ? midPts : []), [58, data[alltype[2]]],
[typeName == '1' ? 51.5 : 61, data[alltype[1]]], [79, data[alltype[3]]]
[61, data[alltype[2]]], ]:
[81, data[alltype[3]]] [
] : [xValue, data?.rz],
[ [55, data[alltype[0]]],
[xValue, data?.rz], [65, data[alltype[1]]],
...(rightSideOnly ? midPts : []), [77, data[alltype[2]]],
[53.5, data[alltype[0]]], [85, data[alltype[3]]]
...(!rightSideOnly ? midPts : []), ]
[66, data[alltype[1]]],
[77, data[alltype[2]]],
[85, data[alltype[3]]]
]
: [] : []
const filteredArray = line.filter(subArray => { const filteredArray = line.filter(subArray => {
return subArray.every(item => item !== null && item !== undefined); return subArray.every(item => item !== null && item !== undefined);
}); });
return { return {
toolbox: { toolbox: {
show: true, show: true,
@ -315,7 +219,7 @@ export default function jrxOptions(data = {}, type = "1", typeName = '1') {
}, },
yAxis: { yAxis: {
type: 'value', type: 'value',
min: yMin, min:yMin,
max: yMax, max: yMax,
interval: 5, interval: 5,
// data:[155,160,180,190,210], // data:[155,160,180,190,210],
@ -371,7 +275,7 @@ export default function jrxOptions(data = {}, type = "1", typeName = '1') {
origin: "end", origin: "end",
color: 'rgba(0, 128, 255, 0.3)' // 设置区域填充颜色 color: 'rgba(0, 128, 255, 0.3)' // 设置区域填充颜色
}, },
data: [...rz, ...rz1] data:[...rz, ...rz1]
}, },
{ {
@ -418,42 +322,6 @@ export default function jrxOptions(data = {}, type = "1", typeName = '1') {
}, },
data: rz1 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
},
// 管位 // 管位
{ {
type: 'line', type: 'line',
@ -517,15 +385,15 @@ export default function jrxOptions(data = {}, type = "1", typeName = '1') {
symbol: 'none', symbol: 'none',
symbolSize: 10, symbolSize: 10,
z: 1, z: 1,
// smooth: 0.6, // 设置平滑度 smooth: 0.6, // 设置平滑度
// smoothMonotone: 'x', // 保持 x 方向的单调性 smoothMonotone: 'x', // 保持 x 方向的单调性
itemStyle: { itemStyle: {
color: '#5487FF' color: '#5487FF'
}, },
lineStyle: { lineStyle: {
color: '#5487FF', color: '#5487FF',
width: 2, width: 2,
// curveness: 0.5 // 增加曲线程度 curveness: 0.5 // 增加曲线程度
}, },
data: filteredArray data: filteredArray
}, },

View File

@ -1,40 +0,0 @@
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,
};

View File

@ -6,34 +6,34 @@ import { exportFile } from '../../../utils/tools';
import apiurl from '../../../service/apiurl'; import apiurl from '../../../service/apiurl';
import usePageTable from '../../../components/crud/usePageTable2'; import usePageTable from '../../../components/crud/usePageTable2';
import { createCrudService } from '../../../components/crud/_'; import { createCrudService } from '../../../components/crud/_';
export default function ModalContent({ item }) { export default function ModalContent({zfjkData}) {
const myType = {
// 闸前水位站 2闸后水位站 3流量站
'1': '工作闸门',
'2': '检修闸门',
}
const columns = [ const columns = [
{ {
title: '序号', title: '序号',
key: 'inx', key: 'inx',
dataIndex:'inx', dataIndex:'inx',
width: 80, width: 80,
},
{
title: '闸门名称',
key: 'stcd',
dataIndex:'stcd',
width: 150,
render: (v) => <span>{myType[v]}</span>
}, },
{ {
title: '当前开度(m)', title: '闸阀名称',
key: 'gtop', key: 'valveName',
dataIndex:'gtop', dataIndex:'valveName',
width: 150, width: 150,
}, },
{ {
title: '数据采集时间', title: '操作内容',
dataIndex:'opContent',
key: 'opContent',
width: 150,
},
{
title: '操作结果',
dataIndex:'status',
key: 'status',
width: 150,
},
{
title: '操作时间',
dataIndex:'tm', dataIndex:'tm',
key: 'tm', key: 'tm',
width: 150, width: 150,
@ -41,7 +41,7 @@ export default function ModalContent({ item }) {
] ]
const [searchVal, setSearchVal] = useState(false) const [searchVal, setSearchVal] = useState(false)
// 闸阀弹框更多数据 // 闸阀弹框更多数据
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.gsxl.zfzl.historypage1).find_noCode); const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.gsxl.zfzl.historypage).find_noCode);
const exportExcel = () => { const exportExcel = () => {
let params = { let params = {
...searchVal, ...searchVal,
@ -50,7 +50,7 @@ export default function ModalContent({ item }) {
pageSize:tableProps.pagination.pageSize pageSize:tableProps.pagination.pageSize
} }
} }
httppost5(apiurl.gsxl.zfzl.historyPageExport1, params).then(res => { httppost5(apiurl.gsxl.zfzl.historyPageExport, params).then(res => {
exportFile(`闸门操作记录.xlsx`,res.data) exportFile(`闸门操作记录.xlsx`,res.data)
}) })
} }
@ -70,7 +70,7 @@ export default function ModalContent({ item }) {
<ModalToolBar <ModalToolBar
setSearchVal={setSearchVal} setSearchVal={setSearchVal}
exportFile={exportExcel} exportFile={exportExcel}
item={item} list={zfjkData}
/> />
</Card> </Card>

View File

@ -4,7 +4,7 @@ import { Form, Input, Button, DatePicker } from 'antd';
import moment from 'moment'; import moment from 'moment';
import NormalSelect from '../../../components/Form/NormalSelect'; import NormalSelect from '../../../components/Form/NormalSelect';
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
const ToolBar = ({ setSearchVal, exportFile,item }) => { const ToolBar = ({ setSearchVal, exportFile,list }) => {
const optionsType = [ const optionsType = [
{ {
label: "今日", label: "今日",
@ -70,27 +70,27 @@ const ToolBar = ({ setSearchVal, exportFile,item }) => {
} }
useEffect(() => { useEffect(() => {
if (item) { if (list.length > 0) {
let dateTimeSo = { let dateTimeSo = {
start: moment().subtract(7, "days").format('YYYY-MM-DD 00:00:00'), start: moment().subtract(7, "days").format('YYYY-MM-DD 00:00:00'),
end: moment().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("tm", [moment(dateTimeSo.start), moment(dateTimeSo.end)])
form.setFieldValue("stcd", item.stcd) form.setFieldValue("valveCode", list[0]?.valveCode)
setSearchVal({dateTimeRangeSo:dateTimeSo, stcd:item.stcd}) setSearchVal({dateTimeRangeSo:dateTimeSo, valveCode:list[0]?.valveCode})
} }
}, [item]) }, [list])
return ( return (
<> <>
<div style={{ display: 'flex', justifyContent: 'space-between' }}> <div style={{ display: 'flex', justifyContent: 'space-between' }}>
<Form form={form} className='toolbarBox' layout="inline" onFinish={onFinish} onValuesChange={onValuesChange}> <Form form={form} className='toolbarBox' layout="inline" onFinish={onFinish} onValuesChange={onValuesChange}>
<Form.Item label="闸门名称" name="stcd"> <Form.Item label="闸门名称" name="valveCode">
<NormalSelect <NormalSelect
style={{ width: '150px' }} style={{ width: '150px' }}
options={[{label:'工作闸门',value:"1"},{label:'检修闸门',value:"2"}]} options={list}
allowClear={false} allowClear={false}
disabled={true} fieldNames={{label: 'valveName',value: 'valveCode'}}
/> />
</Form.Item> </Form.Item>
<Form.Item label="日期范围" name="tm"> <Form.Item label="日期范围" name="tm">

View File

@ -17,12 +17,165 @@ import ModalContent from './ModalContent';
const url = "http://223.75.53.141:9100/gs-tsg" const url = "http://223.75.53.141:9100/gs-tsg"
const CanvasW = 1080 const CanvasW = 1080
const CanvasH = 640 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 = { const myType = {
// 闸前水位站 2闸后水位站 3流量站 // 闸前水位站 2闸后水位站 3流量站
'1': '工作闸门', '1': '闸前水位/水深(m)',
'2': '检修闸门', '2': '闸后水位/水深(m)',
'3': '流量 (m³/s)',
} }
const Page = () => { const Page = () => {
@ -50,16 +203,15 @@ const Page = () => {
const zfColumns = [ const zfColumns = [
{ {
title: '闸名称', title: '闸名称',
key: 'stcd', key: 'valveName',
dataIndex:'stcd', dataIndex:'valveName',
width: 150, width: 150,
render: (v) => <span>{myType[v]}</span>
}, },
{ {
title: '当前开度(m)', title: '当前开关状态',
key: 'gtop', key: 'status',
dataIndex:'gtop', dataIndex:'status',
width: 150, width: 150,
}, },
{ {
@ -111,9 +263,9 @@ const Page = () => {
const pts = contextCoordinates(xunit, hole); const pts = contextCoordinates(xunit, hole);
const eqpnoList = useMemo(() => damList ? new Array(damList.length).fill(0).map((o, index) => index) : [], [damList]); const eqpnoList = useMemo(() => damList ? new Array(damList.length).fill(0).map((o, index) => index) : [], [damList]);
// useEffect(() => { useEffect(() => {
// getList() getList()
// }, []) }, [])
const getList = async () => { const getList = async () => {
const { code, data } = await httppost2(apiurl.zmjk.video) const { code, data } = await httppost2(apiurl.zmjk.video)
@ -183,10 +335,9 @@ const Page = () => {
// 闸阀监控列表数据 // 闸阀监控列表数据
const [zfjkData, setzfjkData] = useState([]) const [zfjkData, setzfjkData] = useState([])
const [rowItem, setRowItem] = useState({})
const getZfjkData = async () => { const getZfjkData = async () => {
try { try {
const res = await httppost2(apiurl.gsxl.zfzl.list1) const res = await httppost2(apiurl.gsxl.zfzl.list)
if (res.code == 200) { if (res.code == 200) {
setzfjkData(res.data) setzfjkData(res.data)
} }
@ -275,8 +426,8 @@ const Page = () => {
useEffect(() => { useEffect(() => {
getZfjkData() getZfjkData()
// getZfjkHistoryData() getZfjkHistoryData()
// getZfjkSwData() getZfjkSwData()
}, []) }, [])
@ -287,28 +438,20 @@ const Page = () => {
{/* <Card className='nonebox'> {/* <Card className='nonebox'>
</Card> */} </Card> */}
<div className="ant-card-body" style={{ padding: "20px 0 0 0" }}> <div className="ant-card-body" style={{ padding: "20px 0 0 0" }}>
<div className="sg_zmjk_left" style={{width:'100%'}}> <div className="sg_zmjk_left">
{/* <div className='sg_zmjk_left_title'> <div className='sg_zmjk_left_title'>
<Divider type="vertical" style={{ width: 5, background: '#259def', height: 20 }} /> <Divider type="vertical" style={{ width: 5, background: '#259def', height: 20 }} />
闸阀监控 闸阀监控
</div> */} </div>
<div className='sz_left_up_table'> <div className='sz_left_up_table'>
<Table <Table
columns={zfColumns} columns={zfColumns}
rowKey={(record) => record.id} rowKey={(record) => record.tm}
dataSource={zfjkData} dataSource={zfjkData}
pagination={false} pagination={false}
onRow={
(data)=>({
onClick:()=>{
setOpen(true)
setRowItem(data)
}
})
}
/> />
</div> </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><Divider type="vertical" style={{ width: 5, background: '#259def', height: 20 }} />
最近操作记录</div> 最近操作记录</div>
<div onClick={() => setOpen(true)}> <div onClick={() => setOpen(true)}>
@ -325,24 +468,76 @@ const Page = () => {
dataSource={zfjkHistoryListData} dataSource={zfjkHistoryListData}
pagination={false} pagination={false}
/> />
</div> */} </div>
</div> </div>
{/* <div className="sg_zmjk_left">
{/* <div className="sg_zmjk_right"> <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 className='sg_zmjk_right_video'> <div className='sg_zmjk_right_video'>
<div className='sg_zmjk_right_video_title'> <div className='sg_zmjk_right_video_title'>
<Divider type="vertical" style={{ width: 5, background: '#259def', height: 20 }} /> <Divider type="vertical" style={{ width: 5, background: '#259def', height: 20 }} />
监控视频</div> 监控视频</div>
<div className='sg_zmjk_right_video_content'> <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'> <div className='sg_zmjk_right_video_content_right'>
{ {
videoArr?.src && videoArr?.src &&
<div <div
className="content-video" className="content-video"
style={{ width: '100%', height: '100%', cursor: "pointer" }} style={{ width: '100%', height: '100%', cursor: "pointer" }}
onClick={() => {
// if (controlerParams.type == 1) {
// setVideoOpen(true)
// setIsShow(!isShow)
// }
}}
> >
<HFivePlayer size={1} wsUrl={videoArr} playerID={'111'} /> <HFivePlayer size={1} wsUrl={videoArr} playerID={'111'} />
{/* <div style={{textAlign:"right"}}>注:单击视频显示/隐藏云台</div> */}
</div> </div>
} }
</div> </div>
@ -359,11 +554,39 @@ const Page = () => {
dataSource={zfjkSwData} dataSource={zfjkSwData}
pagination={false} 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> </div>
<div className='sg_zmjk_right_more' onClick={() => setOpen(true)}>查看更多信息</div> {/* <div className='sg_zmjk_right_more' onClick={() => setOpen(true)}>查看更多信息</div> */}
</div> */} </div>
</div> </div>
</div> </div>
</div> </div>
@ -378,7 +601,28 @@ const Page = () => {
}} }}
> >
<div style={{ height: '600px' }}> <div style={{ height: '600px' }}>
<ModalContent item={rowItem} /> <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 || '-'} /s</Descriptions.Item>
<Descriptions.Item label="实达流量">{data?.stfl || '-'} /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> */}
</div> </div>
</Modal> </Modal>
</> </>

View File

@ -1,7 +1,5 @@
import React from 'react' import React from 'react'
import { Image } from 'antd' import { Image } from 'antd'
import HFivePlayer from '../../../components/video1Plary'
export default function Card({record}) { export default function Card({record}) {
return ( return (
<div className='card-box' style={{border:"1px solid #fff",boxShadow:"0 0 10px #c0c0c0",padding:10,marginBottom:10,marginLeft:10}}> <div className='card-box' style={{border:"1px solid #fff",boxShadow:"0 0 10px #c0c0c0",padding:10,marginBottom:10,marginLeft:10}}>
@ -9,10 +7,6 @@ export default function Card({record}) {
src={record?.imgPath} src={record?.imgPath}
style={{width:360,height:220}} style={{width:360,height:220}}
></Image> ></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}}> <div style={{display:"flex",alignItems:"center",columnGap:5}}>
<span style={{ <span style={{
padding: "4px 2px", padding: "4px 2px",

View File

@ -1,128 +1,75 @@
import React, { Fragment, useRef, useMemo, useEffect, useState } from 'react'; import React, { Fragment, useRef, useMemo,useEffect,useState } from 'react';
import { Table, Card, Modal, Form, Input, Button, Row, Pagination, message } from 'antd'; import { Table, Card,Modal,Form,Input,Button,Row,Pagination,message } from 'antd';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import ToolBar from './toolbar'; import ToolBar from './toolbar';
import apiurl from '../../../service/apiurl'; import apiurl from '../../../service/apiurl';
import usePageTable from '../../../components/crud/usePageTable3'; import usePageTable from '../../../components/crud/usePageTable3';
import { createCrudService } from '../../../components/crud/_'; import { createCrudService } from '../../../components/crud/_';
import { httpget2,httppost2 } from '../../../utils/request';
import HFivePlayer from '../../../components/video1Plary';
import CardShow from "./Card" import CardShow from "./Card"
import "./index.less" import "./index.less"
import moment from 'moment'; const Page = () => {
const Page = (props) => {
const tm = props?.tm;
const statusObj = {
0: "未处理",
1: '已处理'
};
const levelStatus = {
1: '低',
2: '中',
3: '高'
}
const role = useSelector(state => state.auth.role); 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 [searchVal, setSearchVal] = useState(false)
const [replayOpen, setReplayOpen] = useState(false) const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.spjk1.aiWarn.page).find_noCode);
const [replayItem, setReplayItem] = useState({}) const onchange = (page, pageSize) => {
const [videoSrc, setVideoSrc] = useState('') const obj = {
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.spjk1.aiWarn.page1).find_noCode); pageNumber: page,
const width = useMemo(() => columns.reduce((total, cur) => total + (cur.width), 0), [columns]); pageSize: pageSize,
}
const replay = (r) => { const searchParams = {
setReplayOpen(true); ...obj,
setReplayItem(r) // search: {
getVideoSrc(r) // ...searchVal,
// }
}
search(searchParams)
} }
const getVideoSrc = async(data) => {
try {
// 仅获取播放地址,回放时间由播放器拼接
const res = await httpget2(`${apiurl.gsxl.zfzl.videosrc}${data.resIndexCode}`)
setVideoSrc(res.data)
} catch (error) {
console.log(error);
}
}
// 当外部传入 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(() => { useEffect(() => {
const params = { const params = {
search: { search: {
...searchVal, ...searchVal,
} }
}; };
// 避免初始化时触发空查询造成二次请求闪烁 search(params)
if (searchVal !== false) {
search(params)
}
}, [searchVal]) }, [searchVal])
return ( return (
<> <>
<div className='content-root clearFloat xybm' style={{ paddingRight: "0", paddingBottom: "0" }}> <div className='content-root clearFloat xybm' style={{paddingRight:"0",paddingBottom:"0"}}>
<div className='lf CrudAdcdTreeTableBox' style={{ width: "100%" }}> <div className='lf CrudAdcdTreeTableBox' style={{ width: "100%" }}>
<Card className='nonebox'> <Card className='nonebox'>
<ToolBar <ToolBar
setSearchVal={setSearchVal} setSearchVal={setSearchVal}
role={role} role={role}
tm={tm}
/> />
</Card> </Card>
<div className="ant-card-body" style={{ padding: "20px 0 0 0" }}> <div className="ant-card-body" style={{padding:"20px 0 0 0",display:"flex",flexWrap:"wrap",maxHeight:650,overflowY:"auto"}}>
<Table columns={columns} rowKey="inx" {...tableProps} scroll={{ x: width, y: "calc( 100vh - 500px )" }} /> {
tableProps.dataSource.length > 0 ?
tableProps.dataSource.map((item,i) => {
return (
<div key={i} >
<CardShow
record={item}
/>
</div>
)
}) : null
}
</div> </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>
</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> </div>
</> </>
); );

View File

@ -5,22 +5,26 @@ import moment from 'moment';
import { httppost2 } from '../../../utils/request'; import { httppost2 } from '../../../utils/request';
import apiurl from '../../../service/apiurl'; import apiurl from '../../../service/apiurl';
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
const ToolBar = ({ setSearchVal, onSave, storeData, role, tm }) => { const ToolBar = ({ setSearchVal, onSave, storeData, role }) => {
const searchBtn = role?.rule?.find(item => item.menuName == "查询")|| true; const searchBtn = role?.rule?.find(item => item.menuName == "查询")|| true;
const warnTypes = [ const warnTypes = [
{ {
label: "", label: "人员闯入",
value:1 value:1
}, },
{ {
label: "", label: "工程车辆识别",
value:2 value:2
}, },
{ {
label: "", label: "漂浮物识别",
value:3 value:3
} },
{
label: "游泳识别",
value:4
},
] ]
const [form] = Form.useForm(); const [form] = Form.useForm();
const [codeList, setCodeList] = useState([]) const [codeList, setCodeList] = useState([])
@ -34,30 +38,46 @@ const ToolBar = ({ setSearchVal, onSave, storeData, role, tm }) => {
} }
} }
const onFinish = (values) => { const onFinish = (values) => {
if (values.startTime) { let dateSo;
values.startTime = moment(values.startTime).format('YYYY-MM-DD HH:mm:ss'); 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')
}
} }
setSearchVal({...values}); delete values.tm
setSearchVal({...values, dateTimeRangeSo:dateSo});
} }
// 预填开始时间(来自外部 tm
useEffect(() => { useEffect(() => {
if (tm && Array.isArray(tm) && tm[0]) { getStationCode()
form.setFieldsValue({ startTime: moment(tm[0]) }) let time = [moment().subtract(1,"weeks"),moment()]
} let dateSo = {
}, [tm]) start:moment(time[0]).format('YYYY-MM-DD 00:00:00'),
end:moment(time[1]).format('YYYY-MM-DD 23:59:59'),
}
form.setFieldValue("tm",time)
setSearchVal({dateTimeRangeSo:dateSo})
}, [])
return ( return (
<> <>
<div style={{display:'flex',justifyContent:'space-between'}}> <div style={{display:'flex',justifyContent:'space-between'}}>
<Form form={form} className='toolbarBox' layout="inline" onFinish={onFinish} > <Form form={form} className='toolbarBox' layout="inline" onFinish={onFinish} >
<Form.Item label="事件开始时间" name="startTime"> <Form.Item label="告警日期" name="tm">
<DatePicker <RangePicker
allowClear allowClear
style={{ width: "200px" }} style={{ width: "350px" }}
showTime format="YYYY-MM-DD"
placeholder='请选择时间'
/> />
</Form.Item> </Form.Item>
<Form.Item label="事件等级" name="eventLevel"> <Form.Item label="告警点位" name="indexCode">
<NormalSelect
allowClear
style={{ width: "150px" }}
options={codeList}
/>
</Form.Item>
<Form.Item label="告警类型" name="type">
<NormalSelect <NormalSelect
allowClear allowClear
style={{ width: "150px" }} style={{ width: "150px" }}

View File

@ -1,72 +0,0 @@
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),
},
],
}
}

View File

@ -1,254 +0,0 @@
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 || '-' }&nbsp;<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 || '-'}&nbsp;<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;

View File

@ -1,93 +0,0 @@
.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;
}

View File

@ -1,115 +0,0 @@
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;

View File

@ -1,87 +0,0 @@
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),
},
],
}
}

View File

@ -1,92 +0,0 @@
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),
},
],
}
}

View File

@ -1,68 +0,0 @@
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;