Compare commits

...

2 Commits

Author SHA1 Message Date
秦子超 68340db129 修改地图打点样式 2026-03-13 17:23:19 +08:00
秦子超 738fe32ee4 改bug 2026-03-13 14:45:15 +08:00
40 changed files with 2154 additions and 158 deletions

210
public/data/json/sdz.json Normal file
View File

@ -0,0 +1,210 @@
[
{
"stnm": "易家井电站",
"stcd": "sdz1",
"lgtd": null,
"lttd": null,
"行政主管单位": "赤壁市水利局",
"工程类别": "小(2)型",
"运营单位": null,
"行政区划": "湖北省赤壁市官塘驿镇",
"总装机容量": 0.02,
"建成年份": 1979,
"工程概况": "引水式发电装机1台",
"开发方式": "引水",
"多年平均发电量": 0.497,
"工程状态": "已建",
"开工时间": null,
"正常蓄水位库容": null,
"生态流量": null,
"所在水系": null,
"所在干流": null,
"所在支流": null,
"所有制情况": null,
"厂房地点": null,
"坝址": null,
"工程图片": null
},
{
"stnm": "海源电站",
"stcd": "sdz2",
"lgtd": null,
"lttd": null,
"行政主管单位": "赤壁市水利局",
"工程类别": "小(2)型",
"运营单位": null,
"行政区划": null,
"总装机容量": 0.158,
"建成年份": 1979,
"工程概况": "引水式发电装机4台",
"开发方式": "引水",
"多年平均发电量": 3.4,
"工程状态": "已建",
"开工时间": null,
"正常蓄水位库容": null,
"生态流量": null,
"所在水系": null,
"所在干流": null,
"所在支流": null,
"所有制情况": null,
"厂房地点": null,
"坝址": null,
"工程图片": null
},
{
"stnm": "大泉洞电站",
"stcd": "sdz3",
"lgtd": 114.162123,
"lttd": 29.678901,
"行政主管单位": "赤壁市水利局",
"工程类别": "小(2)型",
"运营单位": "赤壁水建山水资源有限公司",
"行政区划": "湖北省赤壁市官塘驿镇",
"总装机容量": 0.04,
"建成年份": 1981,
"工程概况": "引水式发电装机2台",
"开发方式": "引水",
"多年平均发电量": 1.35,
"工程状态": "已建",
"开工时间": null,
"正常蓄水位库容": null,
"生态流量": null,
"所在水系": null,
"所在干流": null,
"所在支流": null,
"所有制情况": null,
"厂房地点": null,
"坝址": null,
"工程图片": null
},
{
"stnm": "双石电站",
"stcd": "sdz4",
"lgtd": null,
"lttd": null,
"行政主管单位": "赤壁市水利局",
"工程类别": "小(2)型",
"运营单位": null,
"行政区划": "湖北省赤壁市官塘驿镇",
"总装机容量": 0.1,
"建成年份": 1978,
"工程概况": "装机2台",
"开发方式": "坝后",
"多年平均发电量": 2.056,
"工程状态": "已建",
"开工时间": null,
"正常蓄水位库容": null,
"生态流量": null,
"所在水系": null,
"所在干流": null,
"所在支流": null,
"所有制情况": null,
"厂房地点": null,
"坝址": null,
"工程图片": null
},
{
"stnm": "宝剑电站",
"stcd": "sdz5",
"lgtd": null,
"lttd": null,
"行政主管单位": "赤壁市水利局",
"工程类别": "小(2)型",
"运营单位": null,
"行政区划": "湖北省赤壁市官塘驿镇",
"总装机容量": 0.02,
"建成年份": 1975,
"工程概况": "引水式发电装机2台",
"开发方式": "引水",
"多年平均发电量": 0.444,
"工程状态": "已建",
"开工时间": null,
"正常蓄水位库容": null,
"生态流量": null,
"所在水系": null,
"所在干流": null,
"所在支流": null,
"所有制情况": null,
"厂房地点": null,
"坝址": null,
"工程图片": null
},
{
"stnm": "黄沙电站",
"stcd": "sdz6",
"lgtd": null,
"lttd": null,
"行政主管单位": "赤壁市水利局",
"工程类别": "小(2)型",
"运营单位": null,
"行政区划": "湖北省赤壁市官塘驿镇",
"总装机容量": 0.052,
"建成年份": 1978,
"工程概况": "装机2台",
"开发方式": "坝后",
"多年平均发电量": 1.134,
"工程状态": "已建",
"开工时间": null,
"正常蓄水位库容": null,
"生态流量": null,
"所在水系": null,
"所在干流": null,
"所在支流": null,
"所有制情况": null,
"厂房地点": null,
"坝址": null,
"工程图片": null
},
{
"stnm": "峰口电站",
"stcd": "sdz7",
"lgtd": null,
"lttd": null,
"行政主管单位": "赤壁市水利局",
"工程类别": "小(2)型",
"运营单位": null,
"行政区划": "湖北省赤壁市官塘驿镇",
"总装机容量": 0.01,
"建成年份": 1975,
"工程概况": "引水式发电装机2台",
"开发方式": "引水",
"多年平均发电量": 0.318,
"工程状态": "已建",
"开工时间": null,
"正常蓄水位库容": null,
"生态流量": null,
"所在水系": null,
"所在干流": null,
"所在支流": null,
"所有制情况": null,
"厂房地点": null,
"坝址": null,
"工程图片": null
},
{
"stnm": "矮岭电站",
"stcd": "sdz8",
"lgtd": null,
"lttd": null,
"行政主管单位": "赤壁市水利局",
"工程类别": "小(2)型",
"运营单位": null,
"行政区划": "湖北省赤壁市官塘驿镇",
"总装机容量": 0.01,
"建成年份": 1978,
"工程概况": "引水式发电装机1台",
"开发方式": "引水",
"多年平均发电量": 0.178,
"工程状态": "已建",
"开工时间": null,
"正常蓄水位库容": null,
"生态流量": null,
"所在水系": null,
"所在干流": null,
"所在支流": null,
"所有制情况": null,
"厂房地点": null,
"坝址": null,
"工程图片": null
}
]

View File

@ -0,0 +1,105 @@
import React, { useState, useEffect, useRef } from 'react'
import { Form, Button, Input, Row, Upload, Col, Table, DatePicker, InputNumber, message, Image, Modal, Typography, Select } from 'antd';
import { DeleteOutlined, FileWordOutlined, FilePdfOutlined, FileZipOutlined, FileExcelOutlined } from '@ant-design/icons';
import moment from 'moment'
import apiurl from '../../../service/apiurl';
import PdfView from './pdfView';
// import './index.less'
const baseFileView = "http://223.75.53.141:9100/gs-ss"
const FileView = ({mode, fileList, setFileList,downloadUrl}) => {
const childRef = useRef(null);
const download = (params) => {
let downloadLink = document.createElement("a");
downloadLink.href = process.env.REACT_APP_API_URL+downloadUrl+params
downloadLink.download = `${params.fileName}`;
downloadLink.style.display = "none";
// 将链接添加到页面中
document.body.appendChild(downloadLink);
// 模拟点击事件,开始下载
downloadLink.click();
}
const deleteFile = (fileId) => {
let filterFile = fileList.filter(item => item.response?.data?.fileId !== fileId);
setFileList(filterFile)
}
const viewPdf = (params) => {
if (childRef.current) {
childRef.current.callChildMethod(params);
}
}
return (
<>
<Row gutter={[16]}>
{
fileList.map(file=>(
<Col span={12}>
<div className="file-item" style={{ width: "75%",marginTop:5, borderColor:'rgba(59, 124, 255, 0.6)' }}>
<div className='file-description'>
{
(()=>{
if(file.name.indexOf('.doc') > -1){
return (
<div
onClick={() => { download(file.response?.data?.fileId) }}
style={{ cursor: 'pointer' }}
>
<FileWordOutlined style={{ fontSize: 40 }}/>
</div>
)
}else if(file.name.indexOf('.pdf') > -1){
return (
<div
onClick={() => { viewPdf(file.response?.data?.fileId) }}
style={{ cursor: 'pointer' }}
>
<FilePdfOutlined style={{ fontSize: 40 }} />
</div>
)
}else if(file.name.indexOf('.zip') > -1){
return (
<div
onClick={() => { download(file.response?.data?.fileId) }}
style={{ cursor: 'pointer' }}
>
<FileZipOutlined style={{ fontSize: 40 }} />
</div>
)
}else if(file.name.indexOf('.xls') > -1){
return (
<div
onClick={() => { download(file.response?.data?.fileId) }}
style={{ cursor: 'pointer' }}
>
<FileExcelOutlined style={{ fontSize: 40 }} />
</div>
)
}else{
return (
<Image width={60} src={baseFileView + file.response?.data?.filePath} alt='' />
)
}
})()
}
<span style={{display: 'inline-block',maxWidth: '180px',overflow: 'hidden',textOverflow: 'ellipsis',whiteSpace: 'nowrap'}}>{file.name}</span>
</div>
<div className={mode == "view" ? 'delete-icon disable-icon' : 'delete-icon'} onClick={() => {
deleteFile(file.response?.data?.fileId)
}}>
<DeleteOutlined />
</div>
</div>
</Col>
))
}
</Row>
<PdfView ref={childRef} downloadUrl={downloadUrl}/>
</>
)
}
export default FileView

View File

@ -0,0 +1,90 @@
import React, { useState, useEffect } from 'react'
import { Form, Button, Input, Row, Upload, Col, Table, DatePicker, InputNumber, message, Image, Modal, Typography, Select } from 'antd';
import { DeleteOutlined, FileWordOutlined, FilePdfOutlined, FileZipOutlined, FileExcelOutlined } from '@ant-design/icons';
import moment from 'moment'
import FileView from './fileView';
// import './index.less'
const { RangePicker } = DatePicker
const { Dragger } = Upload;
const FileUpload = ({mode, fileNum=1, value=[], onChange,uploadUrl,onLoadingChange,downloadUrl}) => {
const [fileList, setFileList] = useState([]) //上传文件列表
const [loading, setLoading] = useState(false)
console.log(1111111,fileList);
const fileChange = (info) => {
if (info.file.status === "done") {
setLoading(false);
if(onLoadingChange) onLoadingChange(false);
}
if (info.file.status === "uploading") {
setLoading(true);
if(onLoadingChange) onLoadingChange(true);
}
if (info.file.status === "error") {
message.error("文件上传失败")
setLoading(false);
if(onLoadingChange) onLoadingChange(false);
}
setFileList(info.fileList)
}
useEffect(() => {
if (mode != 'save' ) {
const imgFile = value?.map(o => ({
name: o.fileName,
response: {
data: {
filePath: o.filePath,
fileId: o.fileId
}
},
}))
setFileList(imgFile)
}
}, [])
useEffect(()=>{
if(onChange && fileList){
// let oldFiles = fileList.map(item => (item.response?.data.fileId))
// onChange(oldFiles.join(','))
let oldFiles = fileList.map(item => ({
fileId: item.response?.data?.fileId,
filePath: item.response?.data?.filePath,
fileName:item.response?.data?.fileName
}))
onChange(oldFiles)
}
},[fileList])
return (
<>
{
mode!=='view' &&
<Dragger
name='file'
action={uploadUrl}
onChange={fileChange}
onDrop={(info) => { console.log(info.dataTransfer.files); }}
fileList={fileList}
disabled={loading}
maxCount={fileNum}
// onSuccess={handleSuccess}
>
<p className="ant-upload-text">点击或拖拽文件到此区域上传</p>
<p className="ant-upload-hint">
支持扩展名.doc .docx .xls .pdf .jpg .png .ppt
</p>
</Dragger>
}
<FileView fileList={fileList} setFileList={setFileList} mode={mode} downloadUrl={downloadUrl}/>
</>
)
}
export default FileUpload

View File

@ -0,0 +1,45 @@
import React, { useState, useEffect, forwardRef, useImperativeHandle } from 'react'
import { Modal } from 'antd';
const PdfView = forwardRef((props,ref) => {
const [pdfViewOPen, setPdfViewOPen] = useState(false)
const [iframeSrc, setIframeSrc] = useState('')
useImperativeHandle(ref, () => ({
callChildMethod: showPdf
}));
const showPdf = (url) => {
setIframeSrc(url)
setPdfViewOPen(true)
};
return (
<>
<Modal
open={pdfViewOPen}
width={1000}
title=""
footer={null}
style={{ marginTop: "-5%" }}
onCancel={() => {
setPdfViewOPen(false)
setIframeSrc('')
}}
>
<iframe
style={{
height: '80vh',
width: '100%',
border: 0,
marginTop: 20,
}}
src={`${process.env.PUBLIC_URL}/static/pdf/web/viewer.html?file=${encodeURIComponent(props?.downloadUrl+iframeSrc)}`}
/>
</Modal>
</>
)
})
export default PdfView

View File

@ -483,4 +483,12 @@ input:-webkit-autofill:active {
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
} }
}
//修改Modal全局样式
.ant-modal-content{
background: linear-gradient(135deg, rgba(10, 75, 150, 0.9), rgba(14, 17, 22, 0.8),rgba(14, 17, 22, 0.8),rgba(14, 17, 22, 0.8));
.ant-modal-close {
color: #eee
}
} }

View File

@ -19,12 +19,11 @@ const apiurl = {
videolist: service + '/attCctvBase/list',//视频点 videolist: service + '/attCctvBase/list',//视频点
sylist: service + '/osmoticPressR/list/value?type=1',//渗压站 sylist: service + '/osmoticPressR/list/value?type=1',//渗压站
sllist: service + '/osmoticPressR/list/value?type=2',//渗流站 sllist: service + '/osmoticPressR/list/value?type=2',//渗流站
wylist: service + '/osmoticShiftDevice/list',//位移站 // wylist: service + '/osmoticShiftDevice/list',//位移站
wylist: service + '/osmoticShiftR/list/value',//位移站用这个
azdlist: service + '/shpPlacement/getDetailsAndAddvcdDataList',//安置点 azdlist: service + '/shpPlacement/getDetailsAndAddvcdDataList',//安置点
qsydwlist: service + '/iaCBsnssinfo/getDetailsAndAddvcdDataList',//企事业单位 qsydwlist: service + '/iaCBsnssinfo/getDetailsAndAddvcdDataList',//企事业单位
yhjmhlist: service + '/iaCFlrvvlg/getDetailsAndAddvcdDataList',//沿河居民户 yhjmhlist: service + '/iaCFlrvvlg/getDetailsAndAddvcdDataList',//沿河居民户
sklist: service + '/reservoir/water/listV2',//水库-基础设施没有监测数据
sdzlist: service + '/reservoir/water/listV2',//水电站-基础设施没有监测数据
}, },
monitor: { monitor: {
globalSearch: service +"/globalSearch/findByName",//首页-全局搜索 globalSearch: service +"/globalSearch/findByName",//首页-全局搜索
@ -175,6 +174,39 @@ const apiurl = {
train:service + '/screen/responsibility/getTraining' train:service + '/screen/responsibility/getTraining'
} }
}, },
//知识库
zsk: {
ddfa: {
page: service + "/dispatchScheme/pageByTm",
save:service + "/dispatchScheme/add",
edit: service + "/dispatchScheme/update",
del: service + "/dispatchScheme/delete",
upload: service + "/dispatchScheme/file/upload/singleSimple",
getOne:service + "/dispatchScheme/getById/"
},
ywgz: {
page: service + "/businessRule/pageByTm",
save:service + "/businessRule/add",
edit: service + "/businessRule/update",
del: service + "/businessRule/delete",
upload: service + "/businessRule/file/upload/singleSimple",
getOne:service + "/businessRule/getById/"
},
gcaq: {
page: service + "/projectSafety/pageByTm",
save:service + "/projectSafety/add",
edit: service + "/projectSafety/update",
del: service + "/projectSafety/delete",
upload: service + "/projectSafety/file/upload/singleSimple",
tree: service + "/projectSafety/listCategory",
saveTree: service + "/projectSafety/addCategory",
editTree: service + "/projectSafety/updateCategory",
deleteTree: service + "/projectSafety/delCategory",
getOne:service + "/projectSafety/getById/"
}
},
sy: { sy: {
sssyq: { sssyq: {
rain: service + '/screen/monitoring/rain', rain: service + '/screen/monitoring/rain',

View File

@ -11,26 +11,20 @@ export async function reservoirlist(params) {
return []; return [];
} }
const mapData = data.map(i=>({ return data||[];
...i,
lgtd : Number(i.lgtd)-1,
lttd : Number(i.lttd)-1.2,
}))
return mapData||[];
} }
//河道列表(地图上不显示此站点) //河道列表(地图上不显示此站点)
export async function riverlist(params) { // export async function riverlist(params) {
const {data, code, msg} = await httpget(apiurl.station.riverlist, params) || {}; // const {data, code, msg} = await httpget(apiurl.station.riverlist, params) || {};
if (code !== 200) { // if (code !== 200) {
message.error(msg || '请求失败'); // message.error(msg || '请求失败');
return []; // return [];
} // }
return data; // return data;
} // }
//雨情列表 //雨情列表
export async function rainlist(pam) { export async function rainlist(pam) {
@ -46,8 +40,6 @@ export async function rainlist(pam) {
const mapData = data.map(i=>({ const mapData = data.map(i=>({
...i, ...i,
id: i.stcd, id: i.stcd,
lgtd : Number(i.lgtd)-1,
lttd : Number(i.lttd)-1.2,
})) }))
return mapData||[]; return mapData||[];
@ -60,13 +52,8 @@ export async function flowlist(params) {
message.error(msg || '请求失败'); message.error(msg || '请求失败');
return []; return [];
} }
const mapData = data.map((i,index)=>({
...i,
lgtd : Number(i.lgtd||115.056389)-1+0.1*index,
lttd : Number(i.lttd||31.001944)-1.2+0.1*index,
}))
return mapData||[]; return data||[];
} }
//视频点 //视频点
@ -76,13 +63,8 @@ export async function videolist(params) {
message.error(msg || '请求失败'); message.error(msg || '请求失败');
return []; return [];
} }
const mapData = data.map(i=>({
...i,
lgtd : Number(i.lgtd)-1,
lttd : Number(i.lttd)-1.2,
}))
return mapData||[]; return data||[];
} }
//渗压站 //渗压站
@ -92,13 +74,7 @@ export async function sylist() {
message.error(msg || '请求失败'); message.error(msg || '请求失败');
return []; return [];
} }
const mapData = data.map(i=>({ return data||[];
...i,
lgtd : Number(i.lgtd)-1,
lttd : Number(i.lttd)-1.2,
}))
return mapData||[];
} }
//渗压站 //渗压站
@ -108,29 +84,18 @@ export async function sllist() {
message.error(msg || '请求失败'); message.error(msg || '请求失败');
return []; return [];
} }
const mapData = data.map(i=>({
...i,
lgtd : Number(i.lgtd)-1,
lttd : Number(i.lttd)-1.2,
}))
return mapData||[]; return data||[];
} }
//位移站 //位移站
export async function wylist(params) { export async function wylist(params) {
const { data, code, msg } = await httppost(apiurl.station.wylist, params) || {}; const { data, code, msg } = await httpget(apiurl.station.wylist, params) || {};
if (code !== 200) { if (code !== 200) {
message.error(msg || '请求失败'); message.error(msg || '请求失败');
return []; return [];
} }
const mapData = data?.map(i=>({ return data||[];
...i,
lgtd : Number(i.lgtd)-1,
lttd : Number(i.lttd)-1.2,
}))
return mapData||[];
} }
//安置点 //安置点
@ -187,33 +152,28 @@ export async function yhjmhlist(params) {
//基础设施-水库 //基础设施-水库
export async function sklist(params) { export async function sklist(params) {
const {data, code, msg} = await httppost(apiurl.station.sklist, params) || {}; // const {data, code, msg} = await httppost(apiurl.station.sklist, params) || {};
if (code !== 200) { // if (code !== 200) {
message.error(msg || '请求失败'); // message.error(msg || '请求失败');
return []; // return [];
} // }
const mapData = data.map(i=>({
...i, const mapData = [{
lgtd : Number(i.lgtd)-1.1, "stcd": "1795",
lttd : Number(i.lttd)-1.3, "stnm": "黑石咀水库雨量站(新站)",
})) "sttp": "PP",
"lgtd": 114.14752477,
"lttd": 29.735597138,
"status": 0,
"afsltdz": 0.7
}]
return mapData||[]; return mapData||[];
} }
//基础设施-水电站 //基础设施-水电站
export async function sdzlist(params) { export async function sdzlist(params) {
const {data, code, msg} = await httppost(apiurl.station.sdzlist, params) || {}; const data = await fetch(`${process.env.PUBLIC_URL}/data/json/sdz.json`)
if (code !== 200) { .then(resp => resp.json())
message.error(msg || '请求失败'); return data||[];
return [];
}
const mapData = data.map(i=>({
...i,
lgtd : Number(i.lgtd)-1.15,
lttd : Number(i.lttd)-1.35,
}))
return mapData||[];
} }

View File

@ -14,7 +14,6 @@ function renderMarker({ rzWarning, rzState }, { width }) {
<svg t="1616148185046" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4230" width="${width}"> <svg t="1616148185046" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4230" width="${width}">
</svg> </svg>
<img width="${width}" style="position:absolute;top:0;left:0" src="${process.env.PUBLIC_URL}/assets/mapicon/anzhidian2.png" alt="" className="panel-icon" /> <img width="${width}" style="position:absolute;top:0;left:0" src="${process.env.PUBLIC_URL}/assets/mapicon/anzhidian2.png" alt="" className="panel-icon" />
<div style="width:1px;height:50px;background:red;margin-left:9px"></div>
</div> </div>
` `
} }

View File

@ -0,0 +1,142 @@
import React, { useEffect, useMemo, useState } from 'react';
import { zindexmarker } from '../zindex';
import { getHeightPx } from '../utils';
const {
css,
physics,
} = window.popmotionXL;
function renderMarker({ status }, { width, zoom }) {
let color1, color2;
color1 = '#0f0';
color2 = '#17abe3';
if(status===0){
return `
<div style="position:relative">
<svg t="1616148185046" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4230" width="${width}">
</svg>
<img width="${width}" style="position:absolute;top:0;left:0" src="${process.env.PUBLIC_URL}/assets/mapicon/hdsw2.png" alt="" className="panel-icon" />
</div>
`;
}else if( status ===2 ){
return `
<div style="position:relative">
<svg t="1616148185046" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4230" width="${width}">
</svg>
<img width="${width+4}" style="position:absolute;top:0;left:0" src="${process.env.PUBLIC_URL}/assets/mapicon/hdsw.png" alt="" className="panel-icon" />
</div>
`;
}else{
return `
<div style="position:relative">
<svg t="1616148185046" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4230" width="${width}">
</svg>
<img width="${width+4}" style="position:absolute;top:0;left:0" src="${process.env.PUBLIC_URL}/assets/mapicon/hdsw.png" alt="" className="panel-icon" />
</div>
`;
}
}
function HdswMarker({ data, dispatch, setting, zoom }) {
const [ show, setShow ] = useState(true)
const [ status, setStatus ] = useState(0)
useEffect(() => {
const width = 20;
const placeholder = document.getElementById(`marker_hdsw_${data.id}`);
if (!placeholder) {
return;
}
let svgMarker = ''
const hdswDataItem = setting?.filter(o=>o.stcd===data.stcd)//当前Marker对应的data
if( Array.isArray(setting) && Array.isArray(hdswDataItem) && hdswDataItem.length === 0){
//不显示
placeholder.innerHTML = '';
setShow(false)
return
}else{
setShow(true)
//显示
if(setting===null){
svgMarker = renderMarker(data, { width: width });
setStatus(data?.status||0)
}else{
svgMarker = renderMarker(hdswDataItem[0], { width: width });
setStatus(hdswDataItem[0]?.status||0)
}
}
placeholder.innerHTML = svgMarker;
return () => {
placeholder.innerHTML = '';
}
}, [setting]);
const showPop = () => {
dispatch.runtime.setFeaturePop({
id: data.id,
type: 'hdsw',
data,
lgtd: data.lgtd,
lttd: data.lttd,
elev: data.elev,
})
}
return (
<>
<div
className='markerBoxDp'
style={{
zIndex: zindexmarker.hdsw
}}
>
<div
id={`marker_hdsw_${data.id}`}
style={{
transformOrigin: 'bottom center',
transform: 'translate(-50%,0) scale(1.5)',
lineHeight: 1,
cursor:'pointer',
zIndex: zindexmarker.hdsw
}}
onClick={showPop}
>
</div>
{
zoom > 14 && (
<div
className='markerLabel'
style={{
display: show?'block':'none',
transform: 'translate(20px,-7px)',
}}
>
{data?.stnm}
</div>
)
}
<div
className='markerLine'
style={{
display: show?'block':'none',
transform: 'translate(-50%,0)',
background: `linear-gradient(to top, rgb(${status===0?'170, 168, 168':'1,2,3'}, 1), rgba(${status===0?'170, 168, 168':'1,2,3'}, 0.2))`,//#77c3f5
height: `${getHeightPx(zoom)}px`
}}
>
</div>
</div>
</>
)
}
export default React.memo(HdswMarker);

View File

@ -20,8 +20,6 @@ export default class SLLayer extends BaseLayer {
.map((i,index)=>({ .map((i,index)=>({
...i, ...i,
id : i.stationCode, id : i.stationCode,
lgtd : 114.043389+0.001*index,
lttd : 29.77074+0.001*index
})) }))
this._dispatch.runtime.setMarkers({ this._dispatch.runtime.setMarkers({
[this.getLayerName()]: list || [] [this.getLayerName()]: list || []

View File

@ -20,8 +20,6 @@ export default class SYLayer extends BaseLayer {
.map((i,index)=>({ .map((i,index)=>({
...i, ...i,
id : i.stationCode, id : i.stationCode,
lgtd : 114.056389+0.001*index,
lttd : 29.70074+0.001*index
})); }));
this._dispatch.runtime.setMarkers({ this._dispatch.runtime.setMarkers({
[this.getLayerName()]: list || [] [this.getLayerName()]: list || []

View File

@ -20,8 +20,6 @@ export default class WYLayer extends BaseLayer {
.map((i,index)=>({ .map((i,index)=>({
...i, ...i,
id : i.stationCode, id : i.stationCode,
lgtd : 114.046389+0.001*index,
lttd : 29.80074+0.001*index
})); }));
this._dispatch.runtime.setMarkers({ this._dispatch.runtime.setMarkers({
[this.getLayerName()]: list || [] [this.getLayerName()]: list || []

View File

@ -42,7 +42,7 @@ function WYMarker({ data, dispatch, setting, zoom }) {
const [ show, setShow ] = useState(true) const [ show, setShow ] = useState(true)
useEffect(() => { useEffect(() => {
const width = 16; const width = 12;
const placeholder = document.getElementById(`marker_weiyi_${data.id}`); const placeholder = document.getElementById(`marker_weiyi_${data.id}`);
if (!placeholder) { if (!placeholder) {

View File

@ -1,6 +1,7 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Descriptions } from 'antd'; import { Descriptions } from 'antd';
import {CloseOutlined} from '@ant-design/icons'; import {CloseOutlined} from '@ant-design/icons';
import titleBg from '@/assets/images/modal/title.png';
import moment from "moment" import moment from "moment"
@ -14,17 +15,17 @@ function AnZhiDian({ id, data, dispatch }) {
return ( return (
<> <>
<div className="dp-popup" style={{ position: 'absolute', top: '10px', left: 0, width, lineHeight: 1, background:'#ffffff' ,transform: 'translateX(-50%)' }}> <div className="dp-popup" style={{ position: 'absolute', top: '10px', left: 0, width, lineHeight: 1,transform: 'translateX(-50%)' }}>
<div className="dp-popup-tip" style={{marginTop:'-10px',borderBottomColor:'#f7f7f7'}}></div> <div className="dp-popup-tip" style={{marginTop:'-10px',borderBottomColor:'#f7f7f7'}}></div>
<div className="dp-popup-content"> <div className="dp-popup-content">
<div className="content-body tyb" id='tyb'> <div className="content-body tyb" id='tyb'>
<div className="title"> <div className="title">
<div className="name flex flexac"> <div className="name flex flexac" style={{ backgroundImage: `url(${titleBg})` }}>
<div className='nameBorder'></div> <div className='nameBorder'></div>
{data.name} {data.name}
</div> </div>
<div className="extra"> <div className="extra">
<CloseOutlined onClick={closePop} style={{color:"#333"}}/> <CloseOutlined onClick={closePop} style={{color:"#eee"}}/>
</div> </div>
</div> </div>

View File

@ -1,6 +1,7 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Descriptions,Image } from 'antd'; import { Descriptions,Image } from 'antd';
import {CloseOutlined} from '@ant-design/icons'; import {CloseOutlined} from '@ant-design/icons';
import titleBg from '@/assets/images/modal/title.png';
import moment from "moment" import moment from "moment"
@ -15,17 +16,17 @@ function QSYDW({ id, data, dispatch }) {
return ( return (
<> <>
<div className="dp-popup" style={{ position: 'absolute', top: '10px', left: 0, width, lineHeight: 1, background:'#ffffff' ,transform: 'translateX(-50%)' }}> <div className="dp-popup" style={{ position: 'absolute', top: '10px', left: 0, width, lineHeight: 1, transform: 'translateX(-50%)' }}>
<div className="dp-popup-tip" style={{marginTop:'-10px',borderBottomColor:'#f7f7f7'}}></div> <div className="dp-popup-tip" style={{marginTop:'-10px',borderBottomColor:'#f7f7f7'}}></div>
<div className="dp-popup-content"> <div className="dp-popup-content">
<div className="content-body tyb" id='tyb'> <div className="content-body tyb" id='tyb'>
<div className="title"> <div className="title">
<div className="name flex flexac"> <div className="name flex flexac" style={{ backgroundImage: `url(${titleBg})` }}>
<div className='nameBorder'></div> <div className='nameBorder'></div>
{data.name} {data.name}
</div> </div>
<div className="extra"> <div className="extra">
<CloseOutlined onClick={closePop} style={{color:"#333"}}/> <CloseOutlined onClick={closePop} style={{color:"#eee"}}/>
</div> </div>
</div> </div>

View File

@ -42,6 +42,7 @@ export default function drpOption(data,yjData) {
show: true, show: true,
// 图例的位置 // 图例的位置
data: ["流量"], data: ["流量"],
textStyle: { color: '#fff' },
}, },
xAxis: [ xAxis: [
{ {
@ -53,13 +54,13 @@ export default function drpOption(data,yjData) {
}, },
axisLabel: { axisLabel: {
padding: [0, 0, 100, 0], padding: [0, 0, 100, 0],
color: '#333', color: '#ffffff',
fontSize: 12, fontSize: 12,
formatter: val => val.slice(0,10) formatter: val => val.slice(0,10)
}, },
axisLine: { axisLine: {
lineStyle: { lineStyle: {
color: '#d9d9d9', color: '#ffffff',
width: 1, width: 1,
} }
}, },
@ -76,7 +77,7 @@ export default function drpOption(data,yjData) {
name: "流量(L/s)", name: "流量(L/s)",
nameTextStyle: { nameTextStyle: {
padding: [0, 0, 10, 10], padding: [0, 0, 10, 10],
color:'#333333', color:'#ffffff',
fontSize: 14 fontSize: 14
}, },
splitLine: { splitLine: {
@ -88,7 +89,7 @@ export default function drpOption(data,yjData) {
} }
}, },
axisLabel: { axisLabel: {
color: '#333', color: '#ffffff',
fontSize: 12, fontSize: 12,
}, },
axisLine: { axisLine: {

View File

@ -44,6 +44,7 @@ export default function drpOption(data,yjData) {
show: true, show: true,
// 图例的位置 // 图例的位置
data: ["X方向","Y方向","H方向", "库水位"], data: ["X方向","Y方向","H方向", "库水位"],
textStyle: { color: '#fff' },
}, },
xAxis: [ xAxis: [
{ {

View File

@ -3,6 +3,8 @@ import { Descriptions } from 'antd';
import {CloseOutlined} from '@ant-design/icons'; import {CloseOutlined} from '@ant-design/icons';
import { httpget } from '../../../../utils/request'; import { httpget } from '../../../../utils/request';
import apiurl from '../../../../service/apiurl'; import apiurl from '../../../../service/apiurl';
import titleBg from '@/assets/images/modal/title.png';
function Wxq({ id, data, dispatch }) { function Wxq({ id, data, dispatch }) {
console.log(data); console.log(data);
@ -28,17 +30,30 @@ function Wxq({ id, data, dispatch }) {
return ( return (
<> <>
<div className="dp-popup" style={{ position: 'absolute', top: '10px', left: 0, width, lineHeight: 1, background:'#ffffff' ,transform: 'translateX(-50%)' }}> {/* <div className='shuikuPop'>
<div className="modal-header">
<div className="title-wrapper" style={{ backgroundImage: `url(${titleBg})` }}>
<span className="title-text">{data.stnm}</span>
</div>
<div className="close-btn" onClick={closePop}>
<CloseOutlined />
</div>
</div>
<div className="modal-body">
1
</div>
</div> */}
<div className="dp-popup" style={{ position: 'absolute', top: '10px', left: 0, width, lineHeight: 1,transform: 'translateX(-50%)' }}>
<div className="dp-popup-tip" style={{marginTop:'-10px',borderBottomColor:'#f7f7f7'}}></div> <div className="dp-popup-tip" style={{marginTop:'-10px',borderBottomColor:'#f7f7f7'}}></div>
<div className="dp-popup-content"> <div className="dp-popup-content">
<div className="content-body tyb" id='tyb'> <div className="content-body tyb" id='tyb'>
<div className="title"> <div className="title">
<div className="name flex flexac"> <div className="name flex flexac" style={{ backgroundImage: `url(${titleBg})` }}>
<div className='nameBorder'></div> <div className='nameBorder'></div>
{data.NAME || detail?.name} {data.NAME || detail?.name}
</div> </div>
<div className="extra"> <div className="extra">
<CloseOutlined onClick={closePop} style={{color:"#333"}}/> <CloseOutlined onClick={closePop} style={{color:"#fff"}}/>
</div> </div>
</div> </div>

View File

@ -1,6 +1,7 @@
import React, { useEffect, useState,} from 'react'; import React, { useEffect, useState,} from 'react';
import { Descriptions,Image } from 'antd'; import { Descriptions,Image } from 'antd';
import {CloseOutlined} from '@ant-design/icons'; import {CloseOutlined} from '@ant-design/icons';
import titleBg from '@/assets/images/modal/title.png';
import moment from "moment" import moment from "moment"
@ -14,17 +15,17 @@ function YHJMH({ id, data, dispatch }) {
return ( return (
<> <>
<div className="dp-popup" style={{ position: 'absolute', top: '10px', left: 0, width, lineHeight: 1, background:'#ffffff' ,transform: 'translateX(-50%)' }}> <div className="dp-popup" style={{ position: 'absolute', top: '10px', left: 0, width, lineHeight: 1 ,transform: 'translateX(-50%)' }}>
<div className="dp-popup-tip" style={{marginTop:'-10px',borderBottomColor:'#f7f7f7'}}></div> <div className="dp-popup-tip" style={{marginTop:'-10px',borderBottomColor:'#f7f7f7'}}></div>
<div className="dp-popup-content"> <div className="dp-popup-content">
<div className="content-body tyb" id='tyb'> <div className="content-body tyb" id='tyb'>
<div className="title"> <div className="title">
<div className="name flex flexac"> <div className="name flex flexac" style={{ backgroundImage: `url(${titleBg})` }}>
<div className='nameBorder'></div> <div className='nameBorder'></div>
{data.name} {data.name}
</div> </div>
<div className="extra"> <div className="extra">
<CloseOutlined onClick={closePop} style={{color:"#333"}}/> <CloseOutlined onClick={closePop} style={{color:"#eee"}}/>
</div> </div>
</div> </div>

View File

@ -20,15 +20,27 @@
box-shadow: 0 1px 2px rgba(0,0,0,.1); box-shadow: 0 1px 2px rgba(0,0,0,.1);
pointer-events: auto; pointer-events: auto;
//background: rgba(4, 8, 27, 0.9); //background: rgba(4, 8, 27, 0.9);
background: rgba(255, 255, 255, 0.9); // background: rgba(255, 255, 255, 0.9);
background: linear-gradient(135deg, rgba(10, 75, 150, 0.9), rgba(14, 17, 22, 0.8),rgba(14, 17, 22, 0.8),rgba(14, 17, 22, 0.8));
border-radius: 0px; border-radius: 0px;
padding: 0; padding: 0;
} }
.content-body { .content-body {
color: #333; // color: #333;
color: #fff;
// padding: 0.4rem 0.4rem 0.2rem 0.4rem; // padding: 0.4rem 0.4rem 0.2rem 0.4rem;
position: relative; position: relative;
//antd描述列表
.ant-descriptions{
.ant-descriptions-item-container{
.ant-descriptions-item-label,.ant-descriptions-item-content{
color: #ffffff;
}
}
}
.cursor-pointer1, .cursor-pointer2, .cursor-pointer3{ .cursor-pointer1, .cursor-pointer2, .cursor-pointer3{
position: absolute; position: absolute;
@ -50,7 +62,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
border-bottom: 1px solid rgba(36, 136, 223, 0.60); border-bottom: 1px solid rgba(36, 136, 223, 0.60);
padding: 0.2rem 0.6rem 0.4rem 0.6rem; padding: 0.2rem 0.6rem 0.4rem 0.2rem;
line-height:30px; line-height:30px;
font-size:16px; font-size:16px;
@ -62,6 +74,9 @@
} }
.name { .name {
margin: 7px 0 5px 0;
background-repeat: no-repeat;
padding-left: 20px;
flex-grow: 1; flex-grow: 1;
font-weight:bold; font-weight:bold;
} }

View File

@ -37,4 +37,29 @@
-0.8px 0.8px 0.3px white, -0.8px 0.8px 0.3px white,
-0.8px 0 0.3px white; -0.8px 0 0.3px white;
} }
.markerBoxDp{
position: absolute;
left: 0;
bottom: 0;
color: #fff;
.markerLine{
width: 2px;
// height: 100px;
transition: height 0.1s ease
}
.markerLabel{
position: absolute;
white-space:nowrap;
top: 0;
left: 0;
padding: 2px 8px;
font-size: 14px;
border-radius: 4px;
background: #142947;
border: 1px solid #295cad;
}
}
} }

View File

@ -38,3 +38,19 @@ export function getElev(val: string) {
} }
} }
//配置不同Marker的elev
export function getHeightPx(zoom: number) {
const maxH = 170
const minH = 0
if(zoom>20){
return maxH
}else if(zoom<=20 && zoom>14){
return (zoom - 14) / (20 - 14) * (maxH - minH) + minH
}else{
return minH
}
}

View File

@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { Table } from 'antd'; import { Table } from 'antd';
import CommonModal from '@/views/Home/components/UI/CommonModal'; import CommonModal from '@/views/Home/components/UI/CommonModal';
import arrowIcon from '@/assets/images/card/arrow.png'; import arrowIcon from '@/assets/images/card/arrow.png';
@ -14,6 +14,7 @@ import VideoList from '../ModalComponents/VideoList'
import UAVModal from '../ModalComponents/UAVModal'; import UAVModal from '../ModalComponents/UAVModal';
const AllWeatherControl = () => { const AllWeatherControl = () => {
const dispatch = useDispatch()
const isFullScreen = useSelector(s => s.runtime.isFullScreen); const isFullScreen = useSelector(s => s.runtime.isFullScreen);
const [reservoirItem, setReservoirItem] = useState({}) const [reservoirItem, setReservoirItem] = useState({})
const [rainList, setRainList] = useState([]) const [rainList, setRainList] = useState([])
@ -155,6 +156,21 @@ const AllWeatherControl = () => {
style={{ backgroundImage: `url(${smallCard})`, cursor: item.clickable ? 'pointer' : 'default' }} style={{ backgroundImage: `url(${smallCard})`, cursor: item.clickable ? 'pointer' : 'default' }}
onClick={() => { onClick={() => {
if (item.clickable) { if (item.clickable) {
const { label } = item
if(label==='主坝坝前'){
dispatch.runtime.setCameraTarget({
center: [114.15437134051429, 29.743689445729758],
zoom: 18,
pitch: 60
})
}
if(label==='副坝坝前'){
dispatch.runtime.setCameraTarget({
center: [114.18263599215172, 29.747020722346193],
zoom: 18,
pitch: 60
})
}
setReservoirVisible(true) setReservoirVisible(true)
} }
}} }}

View File

@ -1,11 +1,12 @@
import React,{useMemo} from 'react'; import React,{useMemo} from 'react';
import { useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import arrowIcon from '@/assets/images/card/arrow.png'; import arrowIcon from '@/assets/images/card/arrow.png';
import qysIcon from '@/assets/images/business/qys.png'; import qysIcon from '@/assets/images/business/qys.png';
import textBg from '@/assets/images/card/textbg.png'; import textBg from '@/assets/images/card/textbg.png';
import './index.less'; import './index.less';
const MonitoringElements = ({ data }) => { const MonitoringElements = ({ data }) => {
const dispatch = useDispatch()
const isFullScreen = useSelector(s => s.runtime.isFullScreen); const isFullScreen = useSelector(s => s.runtime.isFullScreen);
const reservoirInfo = [ const reservoirInfo = [
{ label: '总库容万m³', value: '', highlight: false,type:1 }, { label: '总库容万m³', value: '', highlight: false,type:1 },
@ -55,7 +56,17 @@ const MonitoringElements = ({ data }) => {
{newReservoirInfo.map((item, index) => ( {newReservoirInfo.map((item, index) => (
<div key={index} className="info-row" style={{ backgroundImage: `url(${textBg})` }}> <div key={index} className="info-row" style={{ backgroundImage: `url(${textBg})` }}>
<span className="label">{item.label}</span> <span className="label">{item.label}</span>
<span className={`value ${item.highlight ? 'highlight' : ''}`}>{item.value}</span> <span className={`value ${item.highlight ? 'highlight' : ''}`} onClick={()=>{
const {type} = item
if(type===2){
//点击承雨面积
dispatch.runtime.setCameraTarget({
center: [114.15437134051429, 29.744689445729758],
zoom: 14,
pitch: 60
})
}
}}>{item.value}</span>
</div> </div>
))} ))}
<div className="sub-info">(水库直接承雨面积<span>{data?.directCatchmentArea || '-'}</span><span>{data?.reservoirWaterSurfaceArea || '-'}</span>)</div> <div className="sub-info">(水库直接承雨面积<span>{data?.directCatchmentArea || '-'}</span><span>{data?.reservoirWaterSurfaceArea || '-'}</span>)</div>

View File

@ -13,14 +13,14 @@ export default function Btn({open, mode, layerVisible, setOpen, mapType, layerVi
const [ tableData, setTableData ] = useState([]) const [ tableData, setTableData ] = useState([])
const dispatch = useDispatch() const dispatch = useDispatch()
const columns = [ const columns = [
{ title: '名称', key: 'name', dataIndex: 'name',align: "center",width:150, ellipsis: true, }, { title: '名称', key: 'name', dataIndex: 'name',align: "center",width:'60%', ellipsis: true, },
{ title: '类型', key: 'type', dataIndex: 'type',align: "center",width: 50, ellipsis: true }, { title: '类型', key: 'type', dataIndex: 'type',align: "center",width:'40%', ellipsis: true },
]; ];
// const importMap = { const importMap = {
// '业务规则库': () => import('../../../sz/ywgz/form'), '业务规则库': () => import('../../sz/ywgz/form'),
// '调度方案库': () => import('../../../sz/ddfa/form'), '调度方案库': () => import('../../sz/ddfa/form'),
// '工程安全知识库': () => import('../../../sz/khzbgl/form') '工程安全知识库': () => import('../../sz/khzbgl/form')
// }; };
const onFinish = ({name}) => { const onFinish = ({name}) => {
if(name){ if(name){
@ -41,7 +41,7 @@ export default function Btn({open, mode, layerVisible, setOpen, mapType, layerVi
const clickItem = (item)=>{ const clickItem = (item)=>{
// 业务规则库 // 业务规则库
if (item.type == '业务规则库' || item.type == '调度方案库' || item.type == '工程安全知识库') { if (item.type == '业务规则库' || item.type == '调度方案库' || item.type == '工程安全知识库') {
// regularOpen(item) regularOpen(item)
return; // 添加return避免继续执行 return; // 添加return避免继续执行
} }
@ -215,45 +215,45 @@ export default function Btn({open, mode, layerVisible, setOpen, mapType, layerVi
} }
// 业务规则库弹框 // 业务规则库弹框
// const regularOpen = async (record) => { const regularOpen = async (record) => {
// const id = record?.unionCode const id = record?.unionCode
// const com = record.type == '业务规则库' ? const com = record.type == '业务规则库' ?
// { url: apiurl.zsk.ywgz.getOne } : { url: apiurl.zsk.ywgz.getOne } :
// record.type == '调度方案库' ? record.type == '调度方案库' ?
// { url: apiurl.zsk.ddfa.getOne } : { url: apiurl.zsk.ddfa.getOne } :
// { url: apiurl.zsk.gcaq.getOne }; { url: apiurl.zsk.gcaq.getOne };
// const res = await httpget(com.url + id) const res = await httpget(com.url + id)
// // 导入业务规则库的Modal组件 // 导入业务规则库的Modal组件
// // 使用映射函数进行导入 // 使用映射函数进行导入
// try { try {
// const ModalForm = await importMap[record.type](); const ModalForm = await importMap[record.type]();
// Modal.destroyAll(); // 先销毁可能存在的其他Modal Modal.destroyAll(); // 先销毁可能存在的其他Modal
// const modal = Modal.confirm({ const modal = Modal.confirm({
// title: <div style={{ width: '100%', padding: '16px 24px', color: '#3B4859', borderBottom: '1px solid #f0f0f0', position: "absolute", top: 0, left: 0 }}> title: <div style={{ width: '100%', padding: '16px 24px', color: '#3B4859', borderBottom: '2px solid #1f385c', position: "absolute", top: 0, left: 0 }}>
// <div style={{ fontSize: 16, fontWeight: 'bold' }}>{record.name}详情</div> <div style={{ fontSize: 16, fontWeight: 'bold',color:'#fff' }}>{record.name}详情</div>
// </div>, </div>,
// width: 1000, width: 1000,
// content: ( content: (
// <> <>
// <div style={{ marginTop: 45 }}></div> <div style={{ marginTop: 45 }}></div>
// <ModalForm.default <ModalForm.default
// mode="view" mode="view"
// record={res} record={res}
// /> />
// </> </>
// ), ),
// icon: null, icon: null,
// okButtonProps: { style: { display: 'none' } }, okButtonProps: { style: { display: 'none' } },
// cancelButtonProps: { style: { display: 'none' } }, cancelButtonProps: { style: { display: 'none' } },
// closable: true closable: true
// }); });
// } catch (error) { } catch (error) {
// console.error('模块导入失败:', error); console.error('模块导入失败:', error);
// message.error(`无法加载${record.type}详情,请稍后再试`); message.error(`无法加载${record.type}详情,请稍后再试`);
// } }
// return; return;
// } }
// 工程安全监测点 // 工程安全监测点
const renderGCaqModal = (record) => { const renderGCaqModal = (record) => {
@ -298,7 +298,7 @@ export default function Btn({open, mode, layerVisible, setOpen, mapType, layerVi
return ( return (
<div className={open?'mapToolSearch width260':'mapToolSearch width0'}> <div className={open?'mapToolSearch width300':'mapToolSearch width0'}>
<div className='mapToolSearchBox'> <div className='mapToolSearchBox'>
<div className='mapToolSearchBoxTitle'> <div className='mapToolSearchBoxTitle'>
搜索 搜索
@ -316,10 +316,11 @@ export default function Btn({open, mode, layerVisible, setOpen, mapType, layerVi
columns={columns} columns={columns}
pagination={false} pagination={false}
dataSource={tableData} dataSource={tableData}
scroll={{ y: "400px"}} scroll={{x:false, y: "430px"}}
onRow={ onRow={
(row)=>({ (row)=>({
// onClick:()=>clickItem(row) onClick:()=>clickItem(row),
style: { cursor: 'pointer' }
}) })
} }
/> />

View File

@ -131,7 +131,7 @@
position: absolute; position: absolute;
background: #1c3965f0; background: #1c3965f0;
border: 1px solid #2755a1; border: 1px solid #2755a1;
width: 260px; width: 300px;
height: 100%; height: 100%;
border-radius: 4px; border-radius: 4px;
top: 0; top: 0;
@ -177,8 +177,8 @@
} }
} }
.width260{ .width300{
width: 260px; width: 300px;
} }
.width160{ .width160{
width: 160px; width: 160px;

149
src/views/sz/ddfa/form.js Normal file
View File

@ -0,0 +1,149 @@
import React, { useEffect, useState } from 'react';
import { Form, Button, Input, Row, Col, DatePicker, Select } from 'antd';
import { formItemLayout, btnItemLayout } from '../../../components/crud/FormLayoutProps';
import apiurl from '../../../service/apiurl';
import FileUpload from '../../../components/Form/FileUpload'
import moment from 'moment';
import './index.less'
const opntios = [
{value:1,label:'防洪调度'},
{value:2,label:'兴利调度'},
{value:3,label:'生态调度'},
{value:4,label:'应急调度'},
{value:5,label:'其他'},
]
const opntios1 = [
{value:0,label:'已废弃'},
{value:1,label:'生效中'},
]
const ModalForm = ({ mode, record, onEdit, onSave, onSimilarSave }) => {
const [form] = Form.useForm();
const [loading, setLoading] = useState(false)
const [filesParams, setFilesParams] = useState([])
const [fileUploading, setFileUploading] = useState(false) // 新增文件上传状态
const onfinish = (values) => {
const userId = localStorage.getItem("userId");
const userName = localStorage.getItem("userName");
values.tm = moment(values.bzsj).format("YYYY-MM-DD")
if (mode === 'edit') {
onEdit(apiurl.zsk.ddfa.edit, {...record,...values,createUser:userName,files: filesParams})
}
if (mode === 'save') {
onSave(apiurl.zsk.ddfa.save, {...values,createUser:userName,files: filesParams})
}
}
useEffect(() => {
if (mode != 'save') {
const tm = record?.tm ? moment(record?.tm) : '';
form.setFieldValue('bzsj', tm)
if (record?.files.length > 0) {
setFilesParams(record?.files)
}
}
}, [mode])
return (
<>
<Form
form={form}
{...formItemLayout}
onFinish={onfinish}
initialValues={record}
className='ModalFormClass'
>
<Row>
<Col span={12}>
<Form.Item
label="方案名称"
name="name"
rules={[{ required: true }]}
>
<Input disabled={mode === 'view'} style={{ width: '100%' }} allowClear placeholder='请输入'/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="调度类型"
name="type"
rules={[{ required: true }]}
>
<Select allowClear disabled={mode === 'view'} style={{ width: '100%' }} options={opntios} placeholder='请选择' />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="编制时间"
name="bzsj"
rules={[{ required: true }]}
getValueFromEvent={(e, dateString) => dateString}
getValueProps={(value) => ({ value: value ? moment(value) : undefined })}
>
<DatePicker disabled={mode === 'view'} format={'YYYY-MM-DD'} style={{ width: '100%' }} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="状态"
name="status"
rules={[{ required: true }]}
>
<Select allowClear disabled={mode === 'view'} style={{ width: '100%' }} options={opntios1} placeholder='请选择' />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
label="简介"
name="content"
labelCol={{ span: 3 }}
wrapperCol={{ span: 19 }}
>
<Input.TextArea allowClear disabled={mode === 'view'} style={{ width: '100%',height:'15vh' }} placeholder='请输入'/>
</Form.Item>
</Col>
</Row>
<Row>
<Col span={24}>
<Form.Item
label="附件"
name="files"
labelCol={{ span: 3 }}
wrapperCol={{ span: 19 }}
>
<FileUpload
uploadUrl={apiurl.zsk.ddfa.upload}
mode={mode}
fileNum={999}
onChange={(v) => { setFilesParams(v); }}
onLoadingChange={(isLoading) => setFileUploading(isLoading)}
/>
</Form.Item>
</Col>
</Row>
{
mode === 'view' ? null : (
<>
<Form.Item {...btnItemLayout}>
<Button
type="primary"
htmlType="submit"
loading={loading}
disabled={fileUploading} // 文件上传中时禁用按钮
>
{fileUploading ? '文件上传中...' : (mode === 'save' ? '提交' : '修改')}
</Button>
</Form.Item>
</>
)
}
</Form>
</>
);
}
export default ModalForm;

View File

@ -0,0 +1,93 @@
import React, { Fragment, useRef, useMemo, useEffect, useState } from 'react';
import BasicCrudModal from '../../../components/crud/BasicCrudModal';
import { Table, Card } from 'antd';
import ToolBar from './toolbar';
import ModalForm from './form';
import apiurl from '../../../service/apiurl';
import usePageTable from '../../../components/crud/usePageTable';
import { createCrudService } from '../../../components/crud/_';
import { CrudOpRender_text } from '../../../components/crud/CrudOpRender';
const obj = { 1: "防洪调度", 2: "兴利调度", 3: "生态调度", 4: "应急调度", 5: "其他" }
const sobj = {0:'已废弃',1:'生效中'}
const Page = () => {
const refModal = useRef();
const [searchVal, setSearchVal] = useState(false)
const columns = [
{ title: '序号', key: 'inx', dataIndex: 'inx', width: 60, align: "center" },
{ title: '方案名称', key: 'name', dataIndex: 'name', ellipsis: true },
{ title: '调度类型', key: 'type', dataIndex: 'type',render:(v)=><>{obj[v]}</>},
{ title: '简介', key: 'content', dataIndex: 'content'},
{ title: '编制时间', key: 'tm', dataIndex: 'tm'},
{ title: '附件数', key: 'fileCount', dataIndex: 'fileCount'},
{ title: '状态', key: 'status', dataIndex: 'status',render:(v)=><>{sobj[v]}</>},
{ title: '创建人', key: 'createUser', dataIndex: 'createUser'},
{ title: '最后更新时间', key: 'updateTm', dataIndex: 'updateTm'},
{
title: '操作', key: 'operation', fixed: 'right', align: 'center',
render: (value, row, index) => (
<CrudOpRender_text
edit={true}
del={true}
view={true}
command={(cmd) => () => command(cmd)(row)}
/>
)
},
];
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.zsk.ddfa.del + `/${params.id}`);
}
}
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.zsk.ddfa.page).find);
useEffect(() => {
const params = {
search: {
...searchVal,
}
};
search(params)
}, [searchVal])
return (
<>
<div className='content-root clearFloat xybm' style={{ paddingRight: "0", paddingBottom: "0" }}>
<div className='lf CrudAdcdTreeTableBox' style={{ width: "100%", overflowY: "auto" }}>
<Card className='nonebox'>
<ToolBar
setSearchVal={setSearchVal}
onSave={command('save')}
/>
</Card>
<div className="ant-card-body" style={{ padding: "20px 0 0 0" }}>
<Table columns={columns} rowKey="inx" {...tableProps} />
</div>
</div>
<BasicCrudModal
width={1000}
ref={refModal}
title=""
component={ModalForm}
onCrudSuccess={refresh}
/>
</div>
</>
);
}
export default Page;

View File

@ -0,0 +1,8 @@
.ModalFormClass{
.ant-form-item-label{
label{
color: #fff;
}
}
}

View File

@ -0,0 +1,67 @@
import { Form, Input, Button, DatePicker, Select } from 'antd';
import moment from 'moment';
const { RangePicker } = DatePicker;
const ToolBar = ({ setSearchVal, onSave }) => {
const [form] = Form.useForm();
const onFinish = (values) => {
const {releaseDate,...ret} = values
if(releaseDate){
ret.stm = moment(values.releaseDate[0]).format('YYYY-MM-DD')
ret.etm = moment(values.releaseDate[1]).format('YYYY-MM-DD')
}
setSearchVal(ret);
}
const opntios = [
{value:1,label:'防洪调度'},
{value:2,label:'兴利调度'},
{value:3,label:'生态调度'},
{value:4,label:'应急调度'},
{value:5,label:'其他'},
]
const opntios1 = [
{value:0,label:'已废弃'},
{value:1,label:'生效中'},
]
return (
<>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<Form form={form} className='toolbarBox' layout="inline" onFinish={onFinish}>
<Form.Item label="方案名称" name="name">
<Input allowClear style={{ width: '150px' }} />
</Form.Item>
<Form.Item label="调度类型" name="type">
<Select allowClear style={{ width: '150px' }} options={opntios} />
</Form.Item>
<Form.Item label="编制时间" name="releaseDate">
<RangePicker allowClear />
</Form.Item>
<Form.Item label="状态" name="status">
<Select allowClear style={{ width: '150px' }} options={opntios1} />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">查询</Button>
</Form.Item>
<Form.Item>
<Button onClick={() => form.resetFields()}>重置</Button>
</Form.Item>
{
(onSave) ?
<Form.Item>
<Button onClick={onSave}>新增</Button>
</Form.Item>
: null
}
</Form>
</div>
</>
);
}
export default ToolBar;

View File

@ -0,0 +1,47 @@
li.ant-tree-treenode-disabled > span:not(.ant-tree-switcher),
li.ant-tree-treenode-disabled > .ant-tree-node-content-wrapper,
li.ant-tree-treenode-disabled > .ant-tree-node-content-wrapper span{
color: #000 !important;
font-weight: bold;
}
.treeBox1{
.ant-tree-node-content-wrapper{
position: static !important;
}
.hover-ele{
&:hover{
color:#259dff
}
}
}
.AdcdTreeSelectorStyle{
.ant-input-wrapper{
.ant-input-affix-wrapper{
width: 98%;
}
.ant-input-group-addon{
.ant-btn{
width: 34px;
height: 34px;
}
}
}
.treeTitle {
display: flex;
justify-content: space-between;
.treeBtn {
display: none;
}
}
.treeTitle:hover {
.treeBtn {
display: flex;
}
}
}
.no-matter{
opacity: 0.5;
}

View File

@ -0,0 +1,318 @@
import React, { useState, useEffect } from 'react';
import { Tree, Input, Spin,Modal,Form,Col,Row,message,Space } from 'antd';
import { EditOutlined, DeleteOutlined,ExclamationCircleOutlined} from '@ant-design/icons';
import './index.less';
import { formItemLayout } from '../../../../components/crud/FormLayoutProps';
import apiurl from '../../../../service/apiurl';
import { httppost, httpget } from '../../../../utils/request';
type IProps = {
onSelectFun?: any;
setAdcd?: any;
showCheckbox: any;
tableName?: any;
onChangeOpen?: any;
hasAlertBox?: boolean;//顶部是否有预警条
isFetch?: boolean;
}
const { confirm } = Modal;
const AdcdTreeSelector: React.FC<IProps> = ({ onSelectFun, setAdcd, showCheckbox, tableName, hasAlertBox }) => {
const [loading, setLoading] = useState(true);
const [treeData, setTreeData] = useState([]);
const [newTreeData, setNewTreeData] = useState([]);
const [isFiter, setIsFiter] = useState(false);
const [expandedKeys, setExpandedKeys] = useState([]);
const [checkedKeys, setCheckedKeys] = useState([]);
const [selectedKeys, setSelectedKeys] = useState<any>([]);
const [selectedItem, setSelectedItem] = useState({});
const [autoExpandParent, setAutoExpandParent] = useState(true);
const [treeBoxHeight, setTreeBoxHeight] = useState({});
const [jdOpen, setJdOpen] = useState(false)
const [form] = Form.useForm();
const [mode, setMode] = useState('')
const [itemDetail, setItemDetail] = useState<any>({})
const [orderMax, setOrderMax] = useState<any>(0)
useEffect(() => {
getCustomerTreeData();
}, []);
useEffect(() => {
if(tableName){
setSelectedKeys([]);
}
}, [tableName]);
useEffect(()=>{
//根据预警条计/多选框计算高度
if(hasAlertBox){
if(showCheckbox){
setTreeBoxHeight({height:"calc( 100vh - 240px )"})
}else{
setTreeBoxHeight({height:"calc( 100vh - 210px )"})
}
}else{
if(showCheckbox){
setTreeBoxHeight({height:"calc( 100vh - 224px )"})
}else{
setTreeBoxHeight({height:"calc( 100vh - 194px )"})
}
}
},[hasAlertBox])
const getCustomerTreeData = async () => {
const { data, code, msg} = await httpget(apiurl.zsk.gcaq.tree);
let adcdTreedata = []
if (code !== 200) {
message.error(msg || '请求失败');
}
adcdTreedata = data
const item:any = adcdTreedata
if (item) {
setSelectedKeys([item[0]?.id])
setAdcd(item[0]?.id)
}
if (adcdTreedata.length > 0) {
handelTreeData(adcdTreedata);
setTreeData(adcdTreedata);
setLoading(false);
setOrderMax(Math.max(...adcdTreedata.map((item:any) => item?.orderIndex)))
} else {
setLoading(false);
setTreeData([])
}
};
// @ts-ignore
const handelTreeData = (data) => {
if (data.length > 0) {
// @ts-ignore
data.forEach(item => {
item.title = item.name;
item.key = item.id;
if (item.children && item.children.length > 0) {
handelTreeData(item.children);
}
});
}
}
const onExpand = (expandedKeysValue:any) => {
setExpandedKeys(expandedKeysValue);
setAutoExpandParent(false);
};
const onSelect = (selectedKeysValue:any, info:any) => {
setSelectedKeys(selectedKeysValue);
setSelectedItem(info);
if (info.selectedNodes.length > 0) {
let selectData = info.selectedNodes[0];
let adcdVal = "";
adcdVal = selectData.id;
let params = { id: adcdVal };
if(onSelectFun){
onSelectFun(params);
}
if(setAdcd){
setAdcd(adcdVal)
}
} else {
let params = { id: "" };
if(onSelectFun){
onSelectFun(params);
}
if(setAdcd){
setAdcd("")
}
}
};
// 删除
const deleteJd = (v: any) => {
confirm({
title: '删除',
icon: <ExclamationCircleOutlined />,
content: '确认删除此数据',
okText: '确定',
okType: 'primary',
cancelText: '取消',
onOk: async() => {
try {
debugger
const res = await httpget(apiurl.zsk.gcaq.deleteTree + `/${v.id}`)
if (res.code === 200) {
message.success('删除成功');
getCustomerTreeData();
}
if (res.code === 400) {
message.error(res.description);
}
} catch (error) {
console.log(error);
}
},
onCancel() {
console.log('Cancel');
},
});
}
// 新增节点
const saveJd = (v: any) => {
if (v) {
// form.setFieldValue('name', v.title);
setItemDetail(v);
}
setJdOpen(true);
setMode("save");
}
// 编辑节点
const editJd = (v: any) => {
setJdOpen(true);
form.setFieldsValue(v);
setMode("edit");
setItemDetail(v);
}
const onOk = async () => {
const name = form.getFieldValue('name').replace(/\s/g,"");
if(!name) return
const url = mode == "save" ? apiurl.zsk.gcaq.saveTree : apiurl.zsk.gcaq.editTree;
let saveParams = {
name,
// parentId: itemDetail?.id || undefined,
// orderIndex:itemDetail?.orderIndex || orderMax
}
let editParams = {
...itemDetail,
name
}
try {
const res = mode != 'save' ? await httppost(url,editParams):await httpget(url, saveParams)
if (res.code == 200) {
message.success(mode == "save" ? '新增成功' : '编辑成功');
setJdOpen(false);
getCustomerTreeData();
form.resetFields();
} else if (res.code == 400) {
message.error(res.description);
}
} catch (error) {
console.log(error);
}
}
return (
<div className='AdcdTreeSelectorStyle'>
<div
style={{
padding: '10px',
color: "#409eff",
borderBottom: "1px solid #dfdfdf",
marginBottom: 20,
cursor: "pointer"
}}
onClick={saveJd}
></div>
{
loading?
<div style={{position:"absolute",top:"200px",left:"35%",background:"#fff",padding:"20px 30px",borderRadius:"10px"}}>
<Spin tip="正在加载..." size="large" spinning={loading} />
</div>:null
}
<div className="treeBox1" style={{...treeBoxHeight,marginTop:"10px"}}>
<div style={{ width: "300px"}}>
{
treeData.length > 0 &&
<Tree
defaultExpandAll={true}
blockNode={false}
onExpand={onExpand}
checkedKeys={checkedKeys}
onSelect={onSelect}
selectedKeys={selectedKeys}
treeData={isFiter ? newTreeData : treeData}
showLine={true}
titleRender={(v: any) => {
return (
<div
style={{width:200}}
className='treeTitle'
>
<span>{v.title}</span>
<Space
size={4}
className='treeBtn'
>
{/* <PlusCircleOutlined
style={{ fontSize: 15 }}
title='新增'
onClick={(e) => {
e.stopPropagation();
saveJd(v);
}}
className='hover-ele'
/> */}
<EditOutlined
title='编辑'
style={{ fontSize: 15 }}
onClick={(e) => {
e.stopPropagation();
editJd(v);
}}
className='hover-ele'
/>
<DeleteOutlined
title='删除'
style={{ fontSize: 15 }}
onClick={(e) => {
e.stopPropagation();
deleteJd(v);
}}
className='hover-ele'
/>
</Space>
</div>
)
}}
/>
}
</div>
</div>
<Modal
open={jdOpen}
title={mode == "save" ? "新增" : '编辑'}
destroyOnClose
onCancel={() => { setJdOpen(false); form.resetFields()}}
onOk={onOk}
>
<Form form={form} {...formItemLayout}>
<Row>
<Col span={24}>
<Form.Item
label="知识库类型"
name="name"
rules={[{required: true}]}
>
<Input allowClear/>
</Form.Item>
</Col>
</Row>
</Form>
</Modal>
</div>
);
};
export default AdcdTreeSelector;

136
src/views/sz/khzbgl/form.js Normal file
View File

@ -0,0 +1,136 @@
import React, { useEffect, useState, useMemo, useRef } from 'react';
import { Form, Button, Input, Row, Upload, Col, Table, DatePicker, InputNumber, message, Image, Modal, Typography, Select } from 'antd';
import { DeleteOutlined, FileWordOutlined, FilePdfOutlined, FileZipOutlined, FileExcelOutlined } from '@ant-design/icons';
import { formItemLayout, btnItemLayout } from '../../../components/crud/FormLayoutProps';
import apiurl from '../../../service/apiurl';
import NormalSelect from '../../../components/Form/NormalSelect';
import FileUpload from '../../../components/Form/FileUpload'
import './index.less'
// import "./index.less"
import moment from 'moment';
import TextArea from 'antd/lib/input/TextArea';
const opntios = [
{value:1,label:'水资源调度'},
{value:2,label:'防洪调度'},
{value:3,label:'工程安全'},
{value:4,label:'应急抢险'},
{value:5,label:'其他'},
]
const opntios1 = [
{value:0,label:'已废弃'},
{value:1,label:'生效中'},
]
const ModalForm = ({ mode, record, onEdit, onSave, onSimilarSave }) => {
const [form] = Form.useForm();
const [loading, setLoading] = useState(false)
const [filesParams, setFilesParams] = useState([])
const [fileUploading, setFileUploading] = useState(false) // 新增文件上传状态
const onfinish = (values) => {
const userId = localStorage.getItem("userId");
const userName = localStorage.getItem("userName");
values.tm = moment(values.bzsj).format("YYYY-MM-DD")
if (mode === 'edit') {
onEdit(apiurl.zsk.gcaq.edit, { ...record, ...values, createUser: userName, files: filesParams})
}
if (mode === 'save') {
onSave(apiurl.zsk.gcaq.save, {...values,createUser:userName,files:filesParams,type:record?.code})
}
}
useEffect(() => {
if (mode != 'save') {
const tm = record?.tm ? moment(record?.tm) : '';
form.setFieldValue('bzsj', tm)
if (record?.files.length > 0) {
setFilesParams(record?.files)
}
}
}, [mode,record])
return (
<>
<Form
form={form}
{...formItemLayout}
onFinish={onfinish}
initialValues={record}
className='ModalFormClass'
>
<Row>
<Col span={12}>
<Form.Item
label="标题"
name="name"
rules={[{ required: true }]}
>
<Input disabled={mode === 'view'} style={{ width: '100%' }} allowClear placeholder='请输入'/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="编制时间"
name="bzsj"
rules={[{ required: true }]}
getValueFromEvent={(e, dateString) => dateString}
getValueProps={(value) => ({ value: value ? moment(value) : undefined })}
>
<DatePicker disabled={mode === 'view'} format={'YYYY-MM-DD'} style={{ width: '100%' }} allowClear />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
label="简介"
name="content"
labelCol={{ span: 3 }}
wrapperCol={{ span: 19 }}
>
<Input.TextArea allowClear disabled={mode === 'view'} style={{ width: '100%',height:'15vh' }} placeholder='请输入'/>
</Form.Item>
</Col>
</Row>
<Row>
<Col span={24}>
<Form.Item
label="附件"
name="files"
labelCol={{ span: 3 }}
wrapperCol={{ span: 19 }}
>
<FileUpload
mode={mode}
fileNum={999}
uploadUrl={apiurl.zsk.gcaq.upload}
onChange={(v) => { setFilesParams(v)}}
value={filesParams}
onLoadingChange={(isLoading) => setFileUploading(isLoading)}
/>
</Form.Item>
</Col>
</Row>
{
mode === 'view' ? null : (
<>
<Form.Item {...btnItemLayout}>
<Button type="primary" htmlType="submit" loading={loading} disabled={fileUploading}>
{fileUploading ? '文件上传中...' : (mode === 'save' ? '提交' : '修改')}
</Button>
</Form.Item>
</>
)
}
</Form>
</>
);
}
export default ModalForm;

View File

@ -0,0 +1,112 @@
import React, { useRef, useMemo, useEffect, useState } from 'react';
import BasicCrudModal from '../../../components/crud/BasicCrudModal';
import { Table, Card } from 'antd';
import { useSelector } from 'react-redux';
import AdcdTreeSelector from "./AdcdTreeSelector";
import ToolBar from './toolbar';
import ModalForm from './form';
import apiurl from '../../../service/apiurl';
import usePageTable from '../../../components/crud/usePageTable';
import { createCrudService } from '../../../components/crud/_';
import { CrudOpRender_text } from '../../../components/crud/CrudOpRender';
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 delBtn = role?.rule?.find(item => item.menuName == "删除") || true;
const refModal = useRef();
const columns = [
{ title: '序号', key: 'inx', dataIndex: 'inx', width: 60, align: "center" },
{ title: '标题', key: 'name', dataIndex: 'name', width: 200 },
{ title: '简介', key: 'content', dataIndex: 'content' },
{ title: '编制时间', key: 'tm', dataIndex: 'tm' },
{ title: '附件数', key: 'fileCount', dataIndex: 'fileCount' },
{ title: '创建人', key: 'createUser', dataIndex: 'createUser' },
{ title: '最后更新时间', key: 'updateTm', dataIndex: 'updateTm' },
{
title: '操作', key: 'operation', width: 200, fixed: 'right', align: 'center',
render: (value, row, index) => (
<CrudOpRender_text
edit={(editBtn && !row?.isUsed) ? true : false}
del={(delBtn && !row?.isUsed) ? true : false}
view={true}
command={(cmd) => () => command(cmd)(row)} />)
},
];
const [code, setCode] = useState()
const [searchVal, setSearchVal] = useState(false)
const width = useMemo(() => columns.reduce((total, cur) => total + (cur.width), 0), [columns]);
const command = (type) => (params) => {
if (type === 'save') {
refModal.current.showSave({ code });
} else if (type === 'edit') {
refModal.current.showEdit({ ...params, code });
} else if (type === 'view') {
refModal.current.showView(params);
} else if (type === 'del') {
refModal.current.onDeleteGet(apiurl.zsk.gcaq.del + `/${params.id}`);
}
}
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.zsk.gcaq.page).find);
useEffect(() => {
if (code) {
let params = {
search: {
type: code,
...searchVal,
}
};
search(params)
}
}, [code, searchVal]);
return (
<>
<div className='content-box' style={{ backgroundColor: '#fff', height: '100%', display: 'flex', padding: '10px' }}>
<div className='lf adcdTreeSelectorBox' style={{ height: 'calc(100vh - 168px)', width: '340px' }}>
<AdcdTreeSelector hasAlertBox={false} setAdcd={setCode} />
</div>
<div className='AdcdTreeTableBox' style={{ flex: 1, overflowX: "auto" }}>
<Card className='nonebox'>
<ToolBar
onSave={command('save')}
setSearchVal={setSearchVal}
role={role}
/>
</Card>
<Table
columns={columns}
rowKey="id"
{...tableProps}
scroll={{ x: width, y: "calc( 100vh - 400px )" }}
/>
</div>
<BasicCrudModal
width={1000}
ref={refModal}
title=""
component={ModalForm}
onCrudSuccess={refresh}
/>
</div>
</>
);
}
export default Page;

View File

@ -0,0 +1,8 @@
.ModalFormClass{
.ant-form-item-label{
label{
color: #fff;
}
}
}

View File

@ -0,0 +1,54 @@
import React, { useEffect, useState } from 'react';
import { Form, Input, Button, DatePicker } from 'antd';
import moment from 'moment';
const { RangePicker } = DatePicker;
const ToolBar = ({ setSearchVal, onSave, storeData, role }) => {
console.log("role", role);
const addBtn = role?.rule?.find(item => item.menuName == "新增");
const [form] = Form.useForm();
const onFinish = (values) => {
debugger
const { releaseDate, ...ret } = values
if (releaseDate) {
ret.stm = moment(values.releaseDate[0]).format('YYYY-MM-DD')
ret.etm = moment(values.releaseDate[1]).format('YYYY-MM-DD')
}
setSearchVal(ret);
}
return (
<>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<Form form={form} className='toolbarBox' layout="inline" onFinish={onFinish}>
<Form.Item label="标题" name="name">
<Input allowClear style={{ width: '150px' }} />
</Form.Item>
<Form.Item label="编制时间" name="releaseDate">
<RangePicker allowClear />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">查询</Button>
</Form.Item>
<Form.Item>
<Button onClick={() => form.resetFields()}>重置</Button>
</Form.Item>
{
(onSave) ?
<Form.Item>
<Button onClick={onSave} >新增</Button>
</Form.Item>
: null
}
</Form>
</div>
</>
);
}
export default ToolBar;

147
src/views/sz/ywgz/form.js Normal file
View File

@ -0,0 +1,147 @@
import React, { useEffect, useState } from 'react';
import { Form, Button, Input, Row, Col, DatePicker, Select } from 'antd';
import { formItemLayout, btnItemLayout } from '../../../components/crud/FormLayoutProps';
import apiurl from '../../../service/apiurl';
import FileUpload from '../../../components/Form/FileUpload'
import moment from 'moment';
import './index.less'
const opntios = [
{value:1,label:'水资源调度'},
{value:2,label:'防洪调度'},
{value:3,label:'工程安全'},
{value:4,label:'应急抢险'},
{value:5,label:'其他'},
]
const opntios1 = [
{value:0,label:'已废弃'},
{value:1,label:'生效中'},
]
const ModalForm = ({ mode, record, onEdit, onSave, onSimilarSave }) => {
console.log('ccczx',record);
const [form] = Form.useForm();
const [loading, setLoading] = useState(false)
const [filesParams, setFilesParams] = useState([])
const [fileUploading, setFileUploading] = useState(false) // 新增文件上传状态
const onfinish = (values) => {
const userId = localStorage.getItem("userId");
const userName = localStorage.getItem("userName");
values.tm = moment(values.bzsj).format("YYYY-MM-DD")
if (mode === 'edit') {
onEdit(apiurl.zsk.ywgz.edit, { ...record, ...values, createUser: userName, files: filesParams})
}
if (mode === 'save') {
onSave(apiurl.zsk.ywgz.save, {...values,createUser:userName,files:filesParams})
}
}
useEffect(() => {
if (mode != 'save') {
const tm = record?.tm ? moment(record?.tm) : '';
form.setFieldValue('bzsj', tm)
if (record?.files.length > 0) {
setFilesParams(record?.files)
}
}
}, [mode,record])
return (
<>
<Form
form={form}
{...formItemLayout}
onFinish={onfinish}
initialValues={record}
className='ModalFormClass'
>
<Row>
<Col span={12}>
<Form.Item
label="规则名称"
name="name"
rules={[{ required: true }]}
>
<Input disabled={mode === 'view'} style={{ width: '100%' }} allowClear placeholder='请输入'/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="规则类型"
name="type"
rules={[{ required: true }]}
>
<Select allowClear disabled={mode === 'view'} style={{ width: '100%' }} options={opntios} placeholder='请选择' />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="编制时间"
name="bzsj"
rules={[{ required: true }]}
getValueFromEvent={(e, dateString) => dateString}
getValueProps={(value) => ({ value: value ? moment(value) : undefined })}
>
<DatePicker disabled={mode === 'view'} format={'YYYY-MM-DD'} style={{ width: '100%' }} allowClear />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="状态"
name="status"
rules={[{ required: true }]}
>
<Select allowClear disabled={mode === 'view'} style={{ width: '100%' }} options={opntios1} placeholder='请选择' />
</Form.Item>
</Col>
<Col span={24}>
<Form.Item
label="简介"
name="content"
labelCol={{ span: 3 }}
wrapperCol={{ span: 19 }}
>
<Input.TextArea allowClear disabled={mode === 'view'} style={{ width: '100%',height:'15vh' }} placeholder='请输入'/>
</Form.Item>
</Col>
</Row>
<Row>
<Col span={24}>
<Form.Item
label="附件"
name="files"
labelCol={{ span: 3 }}
wrapperCol={{ span: 19 }}
>
<FileUpload
mode={mode}
fileNum={999}
uploadUrl={apiurl.zsk.ywgz.upload}
onChange={(v) => { setFilesParams(v);console.log("vvvv",v);
}}
value={filesParams}
onLoadingChange={(isLoading) => setFileUploading(isLoading)}
/>
</Form.Item>
</Col>
</Row>
{
mode === 'view' ? null : (
<>
<Form.Item {...btnItemLayout}>
<Button type="primary" htmlType="submit" loading={loading} disabled={fileUploading}>
{fileUploading ? '文件上传中...' : (mode === 'save' ? '提交' : '修改')}
</Button>
</Form.Item>
</>
)
}
</Form>
</>
);
}
export default ModalForm;

View File

@ -0,0 +1,93 @@
import React, { useRef, useEffect, useState } from 'react';
import BasicCrudModal from '../../../components/crud/BasicCrudModal';
import { Table, Card } from 'antd';
import ToolBar from './toolbar';
import ModalForm from './form';
import apiurl from '../../../service/apiurl';
import usePageTable from '../../../components/crud/usePageTable';
import { createCrudService } from '../../../components/crud/_';
import { CrudOpRender_text } from '../../../components/crud/CrudOpRender';
const obj = { 1: "水资源调度", 2: "防洪调度", 3: "工程安全", 4: "应急抢险", 5: "其他" }
const sobj = {0:'已废弃',1:'生效中'}
const Page = () => {
const refModal = useRef();
const [searchVal, setSearchVal] = useState(false)
const columns = [
{ title: '序号', key: 'inx', dataIndex: 'inx', width: 60, align: "center" },
{ title: '规则名称', key: 'name', dataIndex: 'name', ellipsis: true },
{ title: '规则类型', key: 'type', dataIndex: 'type',render:(v)=><>{obj[v]}</>},
{ title: '简介', key: 'content', dataIndex: 'content'},
{ title: '编制时间', key: 'tm', dataIndex: 'tm'},
{ title: '附件数', key: 'fileCount', dataIndex: 'fileCount'},
{ title: '状态', key: 'status', dataIndex: 'status',render:(v)=><>{sobj[v]}</>},
{ title: '创建人', key: 'createUser', dataIndex: 'createUser'},
{ title: '最后更新时间', key: 'updateTm', dataIndex: 'updateTm'},
{
title: '操作', key: 'operation', fixed: 'right', align: 'center',
render: (value, row, index) => (
<CrudOpRender_text
edit={true}
del={true}
view={true}
command={(cmd) => () => command(cmd)(row)}
/>
)
},
];
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.zsk.ywgz.del + `/${params.id}`);
}
}
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.zsk.ywgz.page).find);
useEffect(() => {
const params = {
search: {
...searchVal,
}
};
search(params)
}, [searchVal])
return (
<>
<div className='content-root clearFloat xybm' style={{ paddingRight: "0", paddingBottom: "0" }}>
<div className='lf CrudAdcdTreeTableBox' style={{ width: "100%", overflowY: "auto" }}>
<Card className='nonebox'>
<ToolBar
setSearchVal={setSearchVal}
onSave={command('save')}
/>
</Card>
<div className="ant-card-body" style={{ padding: "20px 0 0 0" }}>
<Table columns={columns} rowKey="inx" {...tableProps} />
</div>
</div>
<BasicCrudModal
width={1000}
ref={refModal}
title=""
component={ModalForm}
onCrudSuccess={refresh}
/>
</div>
</>
);
}
export default Page;

View File

@ -0,0 +1,8 @@
.ModalFormClass{
.ant-form-item-label{
label{
color: #fff;
}
}
}

View File

@ -0,0 +1,67 @@
import { Form, Input, Button, DatePicker, Select } from 'antd';
import moment from 'moment';
const { RangePicker } = DatePicker;
const ToolBar = ({ setSearchVal, onSave }) => {
const [form] = Form.useForm();
const onFinish = (values) => {
const {releaseDate,...ret} = values
if(releaseDate){
ret.stm = moment(values.releaseDate[0]).format('YYYY-MM-DD')
ret.etm = moment(values.releaseDate[1]).format('YYYY-MM-DD')
}
setSearchVal(ret);
}
const opntios = [
{value:1,label:'水资源调度'},
{value:2,label:'防洪调度'},
{value:3,label:'工程安全'},
{value:4,label:'应急抢险'},
{value:5,label:'其他'},
]
const opntios1 = [
{value:0,label:'已废弃'},
{value:1,label:'生效中'},
]
return (
<>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<Form form={form} className='toolbarBox' layout="inline" onFinish={onFinish}>
<Form.Item label="规则名称" name="name">
<Input allowClear style={{ width: '150px' }} />
</Form.Item>
<Form.Item label="规则类型" name="type">
<Select allowClear style={{ width: '150px' }} options={opntios} />
</Form.Item>
<Form.Item label="编制时间" name="releaseDate">
<RangePicker allowClear />
</Form.Item>
<Form.Item label="状态" name="status">
<Select allowClear style={{ width: '150px' }} options={opntios1} />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">查询</Button>
</Form.Item>
<Form.Item>
<Button onClick={() => form.resetFields()}>重置</Button>
</Form.Item>
{
(onSave) ?
<Form.Item>
<Button onClick={onSave}>新增</Button>
</Form.Item>
: null
}
</Form>
</div>
</>
);
}
export default ToolBar;