feat(): 知识库开发

qzc-dev
李神峰 2025-07-31 09:50:04 +08:00
parent 50f69efe07
commit 1b55cb5435
22 changed files with 1583 additions and 246 deletions

View File

@ -10,7 +10,7 @@ const { RangePicker } = DatePicker
const { Dragger } = Upload;
const url = "http://223.75.53.141:9100/gs-tsg"
const FileUpload = ({mode, fileNum=1, value, onChange}) => {
const FileUpload = ({mode, fileNum=1, value, onChange,uploadUrl}) => {
const [fileList, setFileList] = useState([]) //上传文件列表
const [loading, setLoading] = useState(false)
console.log(1111111,fileList);
@ -47,8 +47,8 @@ const FileUpload = ({mode, fileNum=1, value, onChange}) => {
useEffect(()=>{
if(onChange && fileList){
let oldFiles = fileList.map(item => (item.response?.data??item))
onChange(oldFiles)
let oldFiles = fileList.map(item => (item.response?.data.fileId))
onChange(oldFiles.join(','))
}
},[fileList])
@ -59,7 +59,7 @@ const FileUpload = ({mode, fileNum=1, value, onChange}) => {
mode!=='view' &&
<Dragger
name='file'
action={apiurl.file.upload}
action={uploadUrl}
onChange={fileChange}
onDrop={(info) => { console.log(info.dataTransfer.files); }}
fileList={fileList}
@ -73,7 +73,7 @@ const FileUpload = ({mode, fileNum=1, value, onChange}) => {
</p>
</Dragger>
}
<FileView fileList={fileList} setFileList={setFileList}/>
<FileView fileList={fileList} setFileList={setFileList} mode={mode} />
</>
)
}

View File

@ -300,6 +300,12 @@ export async function loadMenu(): Promise<MenuItem[]> {
{
id: id(), title: '调度方案库', path: '/mgr/sz/zsk/ddfa',
},
{
id: id(), title: '业务规则库', path: '/mgr/sz/zsk/ywgz',
},
{
id: id(), title: '工程安全知识库', path: '/mgr/sz/zsk/gcaq',
},
]
},

View File

@ -126,6 +126,28 @@ export const map = createModel<RootModel>()({
state: initState() as MapCtrlState,
reducers: {
// 新增只关闭业务图层的方法(保留基础底图)
closeBusinessLayers(state): MapCtrlState{
const s = { ...state };
const businessLayersClosed: Record<string, boolean> = {};
// 关闭特定的业务图层
const businessLayers = [
"HdswLayer", "RealDrpLayer", "SYLayer", "TuRangLayer", "PicStLayer", 'AZDLayer', "QSYDWLayer", 'YHJMHLayer',
"ShuiKuLayer"
];
businessLayers.forEach(layer => {
businessLayersClosed[layer] = false;
});
s.layerVisible = {
...s.layerVisible,
...businessLayersClosed,
};
return s;
},
setMap(state, map) {
return {
...state,
@ -248,6 +270,10 @@ export const map = createModel<RootModel>()({
}).filter(Boolean);
dispatch.runtime.setLayerSetting({ highlight: records })
},
// 新增只关闭业务图层的effect方法
closeBusinessLayersEffect() {
dispatch.map.closeBusinessLayers();
},
resetMap() {
dispatch.map.reset();

View File

@ -25,7 +25,7 @@ export const runtime = createModel<RootModel>()({
layerSetting: {},
layerSettingLoop: {},
hasRightPanel: true,
showGlobalSearch: false,
showGlobalSearch: true,
leftActiveTab: '',
rainLayerTm: '2022070108',
hasAlertBox: false,

View File

@ -10,6 +10,33 @@ const service_fxdd = '/gunshiApp/tsg'
const service_xyt = '/gunshiApp/tsg'//登陆先用小玉潭
const service_shzh = '/shzh'
const apiurl = {
zsk: {
ddfa: {
page: service_fxdd + "/dispatchScheme/pageByTm",
save:service_fxdd + "/dispatchScheme/add",
edit: service_fxdd + "/dispatchScheme/update",
del: service_fxdd + "/dispatchScheme/delete",
upload:service_fxdd + "/dispatchScheme/file/upload/singleSimple",
},
ywgz: {
page: service_fxdd + "/businessRule/pageByTm",
save:service_fxdd + "/businessRule/add",
edit: service_fxdd + "/businessRule/update",
del: service_fxdd + "/businessRule/delete",
upload:service_fxdd + "/businessRule/file/upload/singleSimple",
},
gcaq: {
page: service_fxdd + "/projectSafety/pageByTm",
save:service_fxdd + "/projectSafety/add",
edit: service_fxdd + "/projectSafety/update",
del: service_fxdd + "/projectSafety/delete",
upload: service_fxdd + "/projectSafety/file/upload/singleSimple",
tree: service_fxdd + "/projectSafety/listCategory",
saveTree: service_fxdd + "/projectSafety/addCategory",
editTree: service_fxdd + "/projectSafety/updateCategory",
deleteTree: service_fxdd + "/projectSafety/delCategory",
}
},
file:{
upload:baseFileUpLoad,
download:baseFileDownLoad,

View File

@ -44,6 +44,15 @@ export async function getjdTreeData(params = {}) {
}
return data;
}
export async function getGcaqTreeData(params = {}) {
const { data, code, msg } = await httpget(apiurl.zsk.gcaq.tree) || {};
if (code !== 200) {
message.error(msg || '请求失败');
return [];
}
return data;
}
//获取行政区划树下拉 中电科接口
export async function getAdcdTreeData() {
const { data, code, msg } = await httpget(apiurl.getTreeData);

View File

@ -116,7 +116,8 @@ import Ddfa from './sz/ddfa'
import Krgl from './KrLine'
import Gsnlfx from './gxsl/gsnlfx'
import Ddjl from './szydd/ddjl'
import Ywgz from './sz/ywgz'
import Gcaq from './sz/khzbgl'
const HomePage = lazy(() => import('./Home'))
@ -284,10 +285,9 @@ const AppRouters: React.FC = () => {
{ path: 'sz/szzf/clyj', element: <Clyj /> },
{ path: 'sz/zsk/ddfa', element: <Ddfa /> },
{ path: 'sz/zsk/ywgz', element: <Ywgz /> },
{ path: 'sz/zsk/gcaq', element: <Gcaq /> },
],
},
{ path: '/login', element: <LoginPage /> },

View File

@ -0,0 +1,46 @@
import React from 'react';
import './index.less';
import appconsts from '../../../../service/appconsts';
/**
* 搜索结果列表组件
* @param {Array} data - 搜索结果数据数组每个项目应包含 name type 属性
* @param {Function} onItemClick - 点击列表项的回调函数
* @param {String} title - 可选的标题默认为"搜索结果"
*/
const SearchResultList = ({ data = [], onItemClick, title = "搜索结果" }) => {
return (
<div className="search-result-list">
{/* <div className="search-result-header">
<div className="search-result-title">{title}</div>
<div className="search-result-count"> {data.length} </div>
</div> */}
<div className="search-result-table">
<div className="search-result-table-header">
<div className="search-result-table-cell name-cell">名称</div>
<div className="search-result-table-cell type-cell">类型</div>
</div>
<div className="search-result-table-body">
{data.length > 0 ? (
data.map((item, index) => (
<div
key={item.id || index}
className="search-result-table-row"
onClick={() => onItemClick && onItemClick(item)}
>
<div className="search-result-table-cell name-cell">{item.name}</div>
<div className="search-result-table-cell type-cell">
{appconsts.GlobalSearch_Type[item.type] || item.type}
</div>
</div>
))
) : (
<div className="search-result-empty">暂无搜索结果</div>
)}
</div>
</div>
</div>
);
};
export default SearchResultList;

View File

@ -0,0 +1,104 @@
.search-result-list {
width: 100%;
background-color: #fff;
border-radius: 4px;
overflow: hidden;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
height: 100%;
}
.search-result-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
border-bottom: 1px solid #f0f0f0;
flex-shrink: 0; /* 防止头部被压缩 */
}
.search-result-title {
font-size: 16px;
font-weight: 500;
color: #333;
}
.search-result-count {
font-size: 14px;
color: #999;
}
.search-result-table {
width: 100%;
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden; /* 确保内容不溢出 */
}
.search-result-table-header {
display: flex;
background-color: #f0f5ff;
font-weight: 500;
flex-shrink: 0; /* 防止表头被压缩 */
}
.search-result-table-body {
flex: 1;
overflow-y: auto; /* 添加垂直滚动 */
scrollbar-width: thin; /* Firefox 滚动条样式 */
}
/* 自定义滚动条样式 */
.search-result-table-body::-webkit-scrollbar {
width: 6px;
}
.search-result-table-body::-webkit-scrollbar-thumb {
background-color: #d9d9d9;
border-radius: 3px;
}
.search-result-table-body::-webkit-scrollbar-track {
background-color: #f5f5f5;
}
.search-result-table-row {
display: flex;
border-bottom: 1px solid #f0f0f0;
cursor: pointer;
transition: background-color 0.3s;
&:hover {
background-color: #f5f5f5;
}
&:last-child {
border-bottom: none;
}
}
.search-result-table-cell {
padding: 12px 16px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.name-cell {
flex: 1;
text-align: left;
}
.type-cell {
width: 120px;
text-align: right;
}
.search-result-empty {
padding: 40px 0;
text-align: center;
color: #999;
font-size: 14px;
}

View File

@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react'
import { useLocation } from 'react-router'
import { useDispatch, useSelector } from 'react-redux'
import { Collapse, DatePicker } from 'antd';
import { Collapse, DatePicker, Input } from 'antd';
import './index.less'
import Yujing from './item_yujing/index.js'
import Yuqing from './item_yuqing'
@ -30,222 +30,337 @@ import Tuli2 from '../TuLi/Tuli2.js';
import Tuli3 from '../TuLi/Tuli3.js'
import Tuli4 from '../TuLi/Tuli4.js'
import Tuli5 from '../TuLi/Tuli5.js'
import SearchResultList from './SearchResultList';
import moment from 'moment';
const { Panel } = Collapse;
const { RangePicker } = DatePicker;
const { Search } = Input;
const items = [
{ key:'1', label:'综合监视', children:[
{ key:'11', label:'预警', labelRight:'预警', icon:'yujing' },
{ key:'12', label:'雨情', labelRight:'统计', icon:'yuqing' },
{ key:'13', label:'水库水情', labelRight:'实时水情', icon:'shuikushuiqing' },
{ key:'19', label:'土壤墒情', labelRight:'土壤墒情', icon:'turangshangqing' },
{ key:'15', label:'工程安全', labelRight:'工程安全监测', icon:'gongchenganquan' },
{ key:'16', label:'监测设备状态', labelRight:'监测设备运行', icon:'jianceshebeizhuangtai' },
// { key:'17', label:'水质', labelRight:'水质', icon:'shuizhi' },
{ key:'18', label:'视频点', labelRight:'视频点', icon:'shipindian' },
] },
{ key:'2', label:'巡查巡检', children:[
{ key:'21', label:'巡查巡检', labelRight:'工程巡检', icon:'jianceshebeizhuangtai' },
// { key:'22', label:'大坝', labelRight:'基本信息', icon:'daba' },
// { key:'23', label:'溢洪道', labelRight:'基本信息', icon:'yihongdao' },
] },
{ key:'3', label:'洪水防御', children:[
{ key:'31', label:'危险区', labelRight:'危险区列表', icon:'weixianqu' },
{ key:'32', label:'安置点', labelRight:'安置点列表', icon:'anzhidian' },
{ key:'33', label:'企事业单位', labelRight:'企事业单位列表', icon:'qishiyedanwei' },
{ key:'34', label:'沿河居民户', labelRight:'沿河居民户列表', icon:'yanhejuminhu' },
] },
{ key:'4', label:'水资源调度', children:[
{ key:'41', label:'供水', labelRight:'今日供水实况', icon:'gongshui' },
] },
{ key:'5', label:'水库工程', children:[
{ key:'51', label:'水库', labelRight:'基本信息', icon:'shuiku' },
{ key:'52', label:'大坝', labelRight:'基本信息', icon:'daba' },
{ key:'53', label:'溢洪道', labelRight:'基本信息', icon:'yihongdao' },
] },
{
key: '1', label: '综合监视', children: [
{ key: '11', label: '预警', labelRight: '预警', icon: 'yujing' },
{ key: '12', label: '雨情', labelRight: '统计', icon: 'yuqing' },
{ key: '13', label: '水库水情', labelRight: '实时水情', icon: 'shuikushuiqing' },
{ key: '19', label: '土壤墒情', labelRight: '土壤墒情', icon: 'turangshangqing' },
{ key: '15', label: '工程安全', labelRight: '工程安全监测', icon: 'gongchenganquan' },
{ key: '16', label: '监测设备状态', labelRight: '监测设备运行', icon: 'jianceshebeizhuangtai' },
// { key:'17', label:'水质', labelRight:'水质', icon:'shuizhi' },
{ key: '18', label: '视频点', labelRight: '视频点', icon: 'shipindian' },
]
},
{
key: '2', label: '巡查巡检', children: [
{ key: '21', label: '巡查巡检', labelRight: '工程巡检', icon: 'jianceshebeizhuangtai' },
// { key:'22', label:'大坝', labelRight:'基本信息', icon:'daba' },
// { key:'23', label:'溢洪道', labelRight:'基本信息', icon:'yihongdao' },
]
},
{
key: '3', label: '洪水防御', children: [
{ key: '31', label: '危险区', labelRight: '危险区列表', icon: 'weixianqu' },
{ key: '32', label: '安置点', labelRight: '安置点列表', icon: 'anzhidian' },
{ key: '33', label: '企事业单位', labelRight: '企事业单位列表', icon: 'qishiyedanwei' },
{ key: '34', label: '沿河居民户', labelRight: '沿河居民户列表', icon: 'yanhejuminhu' },
]
},
{
key: '4', label: '水资源调度', children: [
{ key: '41', label: '供水', labelRight: '今日供水实况', icon: 'gongshui' },
]
},
{
key: '5', label: '水库工程', children: [
{ key: '51', label: '水库', labelRight: '基本信息', icon: 'shuiku' },
{ key: '52', label: '大坝', labelRight: '基本信息', icon: 'daba' },
{ key: '53', label: '溢洪道', labelRight: '基本信息', icon: 'yihongdao' },
]
},
]
const HomePage = ({showPanels}) => {
const HomePage = ({ showPanels }) => {
const dispatch = useDispatch();
const [ checkedObj, setCheckedObj ] = useState({})
const [ showTable, setShowTable ] = useState(false)
const [ tms , setTms ] = useState([
moment(moment().add(-1,'days').format('YYYY-MM-DD 08:00:00')),
moment(moment().format('YYYY-MM-DD 08:00:00')),
])
const dispatch = useDispatch();
const [checkedObj, setCheckedObj] = useState({})
const [showTable, setShowTable] = useState(false)
const [tms, setTms] = useState([
moment(moment().add(-1, 'days').format('YYYY-MM-DD 08:00:00')),
moment(moment().format('YYYY-MM-DD 08:00:00')),
])
// 在 globalSearch 函数中添加搜索结果状态
const [searchResults, setSearchResults] = useState([]);
const globalSearch = (e) => {
if (e && e.trim() !== '') {
// 设置为空白状态
setShowTable(true);
// 创建一个新的空对象,只保留必要的属性用于显示
setCheckedObj({
key: 'search',
label: '搜索结果',
labelRight: `搜索:${e}`,
icon: 'search'
});
// 模拟数据
setTimeout(() => {
const mockResults = [
{ id: '1', name: '檀树岗水情站', type: 'swst', lgtd: 114.75, lttd: 31.493 },
{ id: '2', name: '檀树岗雨情站', type: 'qxst', lgtd: 114.76, lttd: 31.495 },
{ id: '3', name: '檀树岗渗压站', type: 'shst', lgtd: 114.77, lttd: 31.497 },
{ id: '4', name: '檀树岗位移站', type: 'shst', lgtd: 114.78, lttd: 31.499 },
{ id: '5', name: '檀树岗渗流站', type: 'shst', lgtd: 114.79, lttd: 31.501 },
{ id: '6', name: '檀树岗土壤墒情站', type: 'stinfo', lgtd: 114.80, lttd: 31.503 },
{ id: '7', name: '檀树岗流量站', type: 'swst', lgtd: 114.81, lttd: 31.505 },
{ id: '8', name: '檀树岗视频站', type: 'picst', lgtd: 114.82, lttd: 31.507 },
{ id: '9', name: '檀树岗湾', type: 'danad', lgtd: 114.83, lttd: 31.509 },
{ id: '10', name: '檀树湾', type: 'placement', lgtd: 114.84, lttd: 31.511 },
{ id: '11', name: '七里坪镇檀树中学', type: 'bsnssinfo', lgtd: 114.85, lttd: 31.513 },
{ id: '12', name: '檀某某', type: 'flrvvlg', lgtd: 114.86, lttd: 31.515 },
{ id: '13', name: '檀树岗调度方案', type: 'reservoir', lgtd: 114.87, lttd: 31.517 },
{ id: '14', name: '檀树岗调度规则', type: 'reservoir', lgtd: 114.88, lttd: 31.519 },
{ id: '15', name: '檀树岗工程安全知识', type: 'daminfo', lgtd: 114.89, lttd: 31.521 },
];
setSearchResults(mockResults);
}, 500);
}
}
const clickItem = (item) => {
// 判断是否为知识库或安全监测站类型
const isKnowledgeOrMonitoringStation = item.type === 'daminfo' || item.type === 'stinfo';
// 如果有经纬度信息,则进行处理
if (item.lgtd && item.lttd) {
// 关闭所有已打开的弹窗
dispatch.runtime.closeFeaturePopAll();
// 关闭所有业务图层
// dispatch.map.closeBusinessLayersEffect();
// 根据类型确定弹窗类型
let popType = item.type;
// 对特定类型进行映射
if (item.type === 'swst') popType = 'hdsw'; // 水文站映射到河道水位
if (item.type === 'qxst') popType = 'drp'; // 气象站映射到雨情
if (item.type === 'picst') popType = 'picst'; // 视频站
// 然后根据类型打开对应图层
if (item.type === 'swst' || item.type === 'hdsw') {
dispatch.map.setLayerVisible({ HdswLayer: true });
} else if (item.type === 'qxst' || item.type === 'drp') {
dispatch.map.setLayerVisible({ RealDrpLayer: true });
} else if (item.type === 'picst') {
dispatch.map.setLayerVisible({ PicStLayer: true });
}
// 显示弹窗
dispatch.runtime.setFeaturePop({
type: popType,
data: item,
lgtd: item.lgtd,
lttd: item.lttd,
id: item.id
});
// 如果不是知识库或安全监测站类型,则进行地图定位
if (!isKnowledgeOrMonitoringStation) {
dispatch.runtime.setCameraTarget({
center: [item.lgtd, item.lttd],
zoom: 15,
pitch: 60
});
}
}
}
useEffect(() => {
dispatch.runtime.closeFeaturePopAll()
// 如果是搜索结果,不要关闭图层
if (checkedObj.label === '搜索结果') {
// 可以选择保持当前图层状态,或者显示某些默认图层
return;
}
if (checkedObj.label === '水库' || checkedObj.label === '大坝' || checkedObj.label === '溢洪道' || checkedObj.label === '视频点') {
dispatch.map.setLayerVisible({ PicStLayer: true })
} else {
dispatch.map.setLayerVisible({ PicStLayer: false })
}
if (checkedObj.label === '危险区' || checkedObj.label === '安置点' || checkedObj.label === '企事业单位' || checkedObj.label === '沿河居民户') {
dispatch.map.setLayerVisible({ AZDLayer: true })
dispatch.map.setLayerVisible({ QSYDWLayer: true })
dispatch.map.setLayerVisible({ YHJMHLayer: true })
} else {
dispatch.map.setLayerVisible({ AZDLayer: false })
dispatch.map.setLayerVisible({ QSYDWLayer: false })
dispatch.map.setLayerVisible({ YHJMHLayer: false })
}
return () => {
dispatch.runtime.closeFeaturePopAll()
dispatch.map.setLayerVisible({ PicStLayer: false })
dispatch.map.setLayerVisible({ AZDLayer: false })
dispatch.map.setLayerVisible({ QSYDWLayer: false })
dispatch.map.setLayerVisible({ YHJMHLayer: false })
}
}, [checkedObj])
useEffect(() => {
setCheckedObj({ key: '12', label: '雨情', labelRight: '统计', icon: 'yuqing' })
}, [])
useEffect(()=>{
dispatch.runtime.closeFeaturePopAll()
if(checkedObj.label==='水库'||checkedObj.label==='大坝'||checkedObj.label==='溢洪道'||checkedObj.label==='视频点'){
dispatch.map.setLayerVisible({ PicStLayer: true })
}else{
dispatch.map.setLayerVisible({ PicStLayer: false })
}
if(checkedObj.label==='危险区'||checkedObj.label==='安置点'||checkedObj.label==='企事业单位'||checkedObj.label==='沿河居民户'){
dispatch.map.setLayerVisible({ AZDLayer: true })
dispatch.map.setLayerVisible({ QSYDWLayer: true })
dispatch.map.setLayerVisible({ YHJMHLayer: true })
}else{
dispatch.map.setLayerVisible({ AZDLayer: false })
dispatch.map.setLayerVisible({ QSYDWLayer: false })
dispatch.map.setLayerVisible({ YHJMHLayer: false })
}
return ()=>{
dispatch.runtime.closeFeaturePopAll()
dispatch.map.setLayerVisible({ PicStLayer: false })
dispatch.map.setLayerVisible({ AZDLayer: false })
dispatch.map.setLayerVisible({ QSYDWLayer: false })
dispatch.map.setLayerVisible({ YHJMHLayer: false })
}
},[checkedObj])
useEffect(()=>{
setCheckedObj({ key:'12', label:'雨情', labelRight:'统计', icon:'yuqing' })
},[])
return (
<div className='homePage' style={{display:!showPanels?'none':'block'}}>
<div className='homePage_leftBox'>
<div className='homePage_head'>综合展示</div>
<Collapse ghost onChange={(a)=>{
dispatch.runtime.closeFeaturePopAll()
if(a===undefined){
setCheckedObj({ key:'12', label:'雨情', labelRight:'统计', icon:'yuqing' })
setShowTable(false)
}else if(a==='1'){
setShowTable(true)
dispatch.runtime.setHome()
setCheckedObj({ key:'11', label:'预警', labelRight:'预警', icon:'yujing' })
}else if(a==='2'){
setShowTable(true)
// dispatch.runtime.setHome()
setCheckedObj({ key:'21', label:'巡查巡检', labelRight:'工程巡检', icon:'shuiku' })
}else if(a==='3'){
dispatch.runtime.setCameraTarget({
center: [114.75, 31.493],
zoom: 13.5,
pitch: 60
})
setShowTable(true)
setCheckedObj({ key:'31', label:'危险区', labelRight:'危险区列表', icon:'weixianqu' })
}else if(a==='4'){
setCheckedObj({ key:'41', label:'供水', labelRight:'今日供水实况', icon:'gongshui' })
}else if(a==='5'){
setCheckedObj({ key:'51', label:'水库', labelRight:'基本信息', icon:'shuiku' })
setShowTable(true)
}else{
}
}} expandIconPosition="end" accordion={true} bordered={false}>
{
items.map((item,index)=>
<Panel
key={item.key}
header={
<>
<div className='homePage_Panel'>
<div className='homePage_Panel_icon'></div>
{item.label}
</div>
</>
}
>
{
item.children.map((item)=>
<dit className='homePage_Panel_item' style={(checkedObj.key===item.key&&showTable)?{color:'#409eff'}:{}} onClick={()=>{
setCheckedObj(item)
setShowTable(true)
}}>
<img src={`${process.env.PUBLIC_URL}/assets/xyt/homeImg/${item.icon}.png`} width="20" height="20" alt="" style={{marginRight:'10px'}} />
{item.label}
{
(checkedObj.key===item.key&&showTable)?
<div style={{flex:1,display:'flex',flexDirection:'row-reverse'}}>
<div style={{width:"3px",height:'40px',background:'rgba(64, 158, 255, 1)'}}></div>
</div>
:null
}
</dit>
)
}
</Panel>
)
}
</Collapse>
</div>
return (
<div className='homePage' style={{ display: !showPanels ? 'none' : 'block' }}>
<div className='homePage_leftBox'>
<Search placeholder="请输入" onSearch={globalSearch} enterButton />
<div className='homePage_head' style={{ marginTop: 10 }}>综合展示</div>
<Collapse ghost onChange={(a) => {
dispatch.runtime.closeFeaturePopAll()
if (a === undefined) {
setCheckedObj({ key: '12', label: '雨情', labelRight: '统计', icon: 'yuqing' })
setShowTable(false)
} else if (a === '1') {
setShowTable(true)
dispatch.runtime.setHome()
setCheckedObj({ key: '11', label: '预警', labelRight: '预警', icon: 'yujing' })
} else if (a === '2') {
setShowTable(true)
// dispatch.runtime.setHome()
setCheckedObj({ key: '21', label: '巡查巡检', labelRight: '工程巡检', icon: 'shuiku' })
} else if (a === '3') {
dispatch.runtime.setCameraTarget({
center: [114.75, 31.493],
zoom: 13.5,
pitch: 60
})
setShowTable(true)
setCheckedObj({ key: '31', label: '危险区', labelRight: '危险区列表', icon: 'weixianqu' })
} else if (a === '4') {
setCheckedObj({ key: '41', label: '供水', labelRight: '今日供水实况', icon: 'gongshui' })
} else if (a === '5') {
setCheckedObj({ key: '51', label: '水库', labelRight: '基本信息', icon: 'shuiku' })
setShowTable(true)
} else {
}
}} expandIconPosition="end" accordion={true} bordered={false}>
{
items.map((item, index) =>
<Panel
key={item.key}
header={
<>
<div className='homePage_Panel'>
<div className='homePage_Panel_icon'></div>
{item.label}
</div>
</>
}
>
{
item.children.map((item) =>
<dit className='homePage_Panel_item' style={(checkedObj.key === item.key && showTable) ? { color: '#409eff' } : {}} onClick={() => {
setCheckedObj(item)
setShowTable(true)
}}>
<img src={`${process.env.PUBLIC_URL}/assets/xyt/homeImg/${item.icon}.png`} width="20" height="20" alt="" style={{ marginRight: '10px' }} />
{item.label}
{
(checkedObj.key === item.key && showTable) ?
<div style={{ flex: 1, display: 'flex', flexDirection: 'row-reverse' }}>
<div style={{ width: "3px", height: '40px', background: 'rgba(64, 158, 255, 1)' }}></div>
</div>
: null
}
</dit>
)
}
</Panel>
)
}
</Collapse>
</div>
{
(checkedObj.label === '预警' || checkedObj.label === '雨情') ?
<div className='homePage_centerBox'><RangePicker showTime value={tms} disabled /></div>
: null
}
{
checkedObj.labelRight ?
<div className='homePage_rightBox' style={{ display: !showPanels ? 'none' : 'block', padding: showTable ? '10px' : '0px' }}>
{
(checkedObj.label === '预警'||checkedObj.label === '雨情')?
<div className='homePage_centerBox'><RangePicker showTime value={tms} disabled/></div>
:null
showTable ?
<div className='homePage_head2'>
{
checkedObj.key != 'search' ?
<div className='homePage_head2_Bg'>
<img src={`${process.env.PUBLIC_URL}/assets/xyt/homeImg/titleBg2.png`} width="14" height="14" alt="" style={{ margin: '0 10px' }} />
{checkedObj.labelRight}
</div> :
<div style={{ width: '100%', display: 'flex', alignItems: 'center', padding: "10px 0", borderBottom: '1px solid #02a7f0' }}>
<div style={{ width: 6, height: 20, background: '#02a7f0', marginRight: 10 }}></div>
<div>{checkedObj.labelRight}</div>
</div>
}
<div style={{ display: 'flex', alignItems: 'center' }}>
{/* <img src={`${process.env.PUBLIC_URL}/assets/xyt/homeImg/x.svg`} width="12" height="12" alt="" style={{margin:'0 10px'}} /> */}
</div>
</div> : null
}
{
checkedObj.labelRight?
<div className='homePage_rightBox' style={{display:!showPanels?'none':'block',padding:showTable?'10px':'0px'}}>
{
showTable?
<div className='homePage_head2'>
<div className='homePage_head2_Bg'>
<img src={`${process.env.PUBLIC_URL}/assets/xyt/homeImg/titleBg2.png`} width="14" height="14" alt="" style={{margin:'0 10px'}} />
{checkedObj.labelRight}
</div>
<div style={{display:'flex',alignItems:'center'}}>
{/* <img src={`${process.env.PUBLIC_URL}/assets/xyt/homeImg/x.svg`} width="12" height="12" alt="" style={{margin:'0 10px'}} /> */}
</div>
</div>:null
}
{ checkedObj.label === '预警' ? <><Yujing mySetTms={setTms}/><Yuqing mySetTms={setTms} show={false}/></>:null }
{ checkedObj.label === '雨情' ? <Yuqing mySetTms={setTms} show={showTable}/>:null }
{ checkedObj.label === '水库水情' ? <ShuiKu/>:null }
{ checkedObj.label === '土壤墒情' ? <TuRangShangQing/>:null }
{ checkedObj.label === '供水' ? <GongShui/>:null }
{ checkedObj.label === '工程安全' ? <GongCheng/>:null }
{ checkedObj.label === '监测设备状态' ? <JianCe/>:null }
{/* { checkedObj.label === '水质' ? <ShuiZhi/>:null } */}
{ checkedObj.label === '视频点' ? <ShiPinDian/>:null }
{checkedObj.label === '搜索结果' ? <div className="search-result-container" style={{
marginTop: '10px', maxHeight: 'calc(100vh - 150px)', /* 设置一个合适的高度,可以根据实际情况调整 */
display: 'flex',
flexDirection: 'column'
}}>
<SearchResultList
data={searchResults}
title={checkedObj.labelRight}
onItemClick={(item) => clickItem(item)}
/>
</div> : null}
{checkedObj.label === '预警' ? <><Yujing mySetTms={setTms} /><Yuqing mySetTms={setTms} show={false} /></> : null}
{checkedObj.label === '雨情' ? <Yuqing mySetTms={setTms} show={showTable} /> : null}
{checkedObj.label === '水库水情' ? <ShuiKu /> : null}
{checkedObj.label === '土壤墒情' ? <TuRangShangQing /> : null}
{checkedObj.label === '供水' ? <GongShui /> : null}
{checkedObj.label === '工程安全' ? <GongCheng /> : null}
{checkedObj.label === '监测设备状态' ? <JianCe /> : null}
{/* { checkedObj.label === '水质' ? <ShuiZhi/>:null } */}
{checkedObj.label === '视频点' ? <ShiPinDian /> : null}
{ checkedObj.label === '巡查巡检' ? <XunChaXunJian/>:null }
{checkedObj.label === '巡查巡检' ? <XunChaXunJian /> : null}
{ checkedObj.label === '水库' ? <GCShuiKu/>:null }
{ checkedObj.label === '大坝' ? <DaBa/>:null }
{ checkedObj.label === '溢洪道' ? <YiHongDao/>:null }
{checkedObj.label === '水库' ? <GCShuiKu /> : null}
{checkedObj.label === '大坝' ? <DaBa /> : null}
{checkedObj.label === '溢洪道' ? <YiHongDao /> : null}
{ checkedObj.label === '危险区' ? <WeiXianQx/>:null }
{ checkedObj.label === '安置点' ? <AnZhiDian/>:null }
{ checkedObj.label === '企事业单位' ? <QSYDW/>:null }
{ checkedObj.label === '沿河居民户' ? <YHJMH/>:null }
{checkedObj.label === '危险区' ? <WeiXianQx /> : null}
{checkedObj.label === '安置点' ? <AnZhiDian /> : null}
{checkedObj.label === '企事业单位' ? <QSYDW /> : null}
{checkedObj.label === '沿河居民户' ? <YHJMH /> : null}
{ checkedObj.label === '危险区' || checkedObj.label === '安置点' || checkedObj.label === '企事业单位' || checkedObj.label === '沿河居民户'?<SetWxqStation/>:null }
</div>
:null
}
{checkedObj.label === '危险区' || checkedObj.label === '安置点' || checkedObj.label === '企事业单位' || checkedObj.label === '沿河居民户' ? <SetWxqStation /> : null}
</div>
: null
}
{
checkedObj.label === '工程安全' ?<div className='homePage_bztBox'>
<Bzt isHome={true}/>
</div>:null
}
{
checkedObj.label === '工程安全' ? <div className='homePage_bztBox'>
<Bzt isHome={true} />
</div> : null
}
<div className='homePage_leftBottomBox'>
{ checkedObj.label==='雨情'?<Tuli/>:null }
{ checkedObj.label==='水库水情'?<Tuli2/>:null }
{ checkedObj.label==='供水'?<Tuli3/>:null }
{ (checkedObj.label==='水库'||checkedObj.label==='大坝'||checkedObj.label==='溢洪道'||checkedObj.label==='视频点')?<Tuli4/>:null }
{ (checkedObj.label==='危险区'||checkedObj.label==='安置点'||checkedObj.label==='企事业单位'||checkedObj.label==='沿河居民户')?<Tuli5/>:null }
</div>
</div>
)
<div className='homePage_leftBottomBox'>
{checkedObj.label === '雨情' ? <Tuli /> : null}
{checkedObj.label === '水库水情' ? <Tuli2 /> : null}
{checkedObj.label === '供水' ? <Tuli3 /> : null}
{(checkedObj.label === '水库' || checkedObj.label === '大坝' || checkedObj.label === '溢洪道' || checkedObj.label === '视频点') ? <Tuli4 /> : null}
{(checkedObj.label === '危险区' || checkedObj.label === '安置点' || checkedObj.label === '企事业单位' || checkedObj.label === '沿河居民户') ? <Tuli5 /> : null}
</div>
</div>
)
}
export default HomePage

View File

@ -184,7 +184,6 @@ const HomePage = () => {
{/* 地图 */}
<MapCtrl />
{/*首页面板*/}
{pathname === '/mgr/home' ? (
<HomePanelsLayoutPage showPanels={showPanels} />

View File

@ -8,30 +8,46 @@ import FileUpload from '../../../components/Form/FileUpload'
// import "./index.less"
import moment from 'moment';
import TextArea from 'antd/lib/input/TextArea';
const opntios=[
{value:0,label:'党支部工作制度'},
{value:1,label:'行政工作制度'},
{value:2,label:'部门工作制度'},
{value:3,label:'安全管理制度'},
{value:4,label:'工程管理制度'},
{value:5,label:'技术规程'},
{value:6,label:'岗位责任制'}
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 onfinish = (values) => {
debugger
const userId = localStorage.getItem("userId");
const userName = localStorage.getItem("userName");
values.tm = moment(values.bzsj).format("YYYY-MM-DD")
if (mode === 'edit') {
// onEdit(apiurl.zdgl.edit, {...record,...values})
onEdit(apiurl.zsk.ddfa.edit, {...record,...values,createUser:userName,fileIds: filesParams, files:undefined})
}
if (mode === 'save') {
// onSave(apiurl.zdgl.add, values)
onSave(apiurl.zsk.ddfa.save, {...values,createUser:userName,fileIds: filesParams, files:undefined})
}
}
useEffect(() => {
if (mode != 'save') {
const tm = record?.tm ? moment(record?.tm) : '';
form.setFieldValue('bzsj', tm)
if (record?.files.length > 0) {
setFilesParams(record?.files.split(','))
}
}
}, [mode])
@ -43,30 +59,30 @@ const ModalForm = ({ mode, record, onEdit, onSave, onSimilarSave }) => {
onFinish={onfinish}
initialValues={record}
>
<Form.Item name="id"><Input type="hidden" /></Form.Item>
<Row>
<Col span={12}>
<Form.Item
label="方案名称"
name="famc"
name="name"
rules={[{ required: true }]}
>
<Input disabled={mode === 'view'} style={{ width: '100%' }} allowClear />
<Input disabled={mode === 'view'} style={{ width: '100%' }} allowClear placeholder='请输入'/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="调度类型"
name="ddlx"
name="type"
rules={[{ required: true }]}
>
<Select allowClear style={{ width: '100%' }} options={opntios} />
<Select allowClear 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 })}
>
@ -76,9 +92,20 @@ const ModalForm = ({ mode, record, onEdit, onSave, onSimilarSave }) => {
<Col span={12}>
<Form.Item
label="状态"
name="zt"
name="status"
rules={[{ required: true }]}
>
<Select allowClear style={{ width: '100%' }} options={opntios} />
<Select allowClear 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>
@ -90,7 +117,8 @@ const ModalForm = ({ mode, record, onEdit, onSave, onSimilarSave }) => {
labelCol={{ span: 3 }}
wrapperCol={{ span: 19 }}
>
<FileUpload
<FileUpload
uploadUrl={apiurl.zsk.ddfa.upload}
mode={mode}
fileNum={3}
/>

View File

@ -13,7 +13,8 @@ import { httpgetExport } from '../../../utils/request';
import { exportFile } from '../../../utils/tools';
import dayjs from 'dayjs';
const obj={0:"党支部工作制度",1:"行政工作制度",2:"部门工作制度",3:"安全管理制度",4:"工程管理制度",5:"技术规程",6:"岗位责任制"}
const obj = { 1: "防洪调度", 2: "兴利调度", 3: "生态调度", 4: "应急调度", 5: "其他" }
const sobj = {0:'已废弃',1:'生效中'}
const Page = () => {
const refModal = useRef();
@ -22,12 +23,12 @@ const Page = () => {
{ 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: 'releaseDate', dataIndex: 'releaseDate', render: (value) => <span>{value ? dayjs(value).format('YYYY-MM-DD') : ''}</span>},
{ title: '编制时间', key: 'fillUnit', dataIndex: 'fillUnit'},
{ title: '附件数', key: 'minUpTime', dataIndex: 'minUpTime'},
{ title: '状态', key: 'minUpTime', dataIndex: 'minUpTime'},
{ title: '创建人', key: 'minUpTime', dataIndex: 'minUpTime'},
{ title: '最后更新时间', key: 'minUpTime', dataIndex: 'minUpTime'},
{ 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) => (
@ -49,12 +50,12 @@ const Page = () => {
} else if (type === 'view') {
refModal.current.showView(params);
} else if (type === 'del') {
refModal.current.onDeleteGet(apiurl.zdgl.del + `/${params.id}`);
refModal.current.onDeleteGet(apiurl.zsk.ddfa.del + `/${params.id}`);
}
}
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.zdgl.list).find_noCode);
const { tableProps, search, refresh } = usePageTable(createCrudService(apiurl.zsk.ddfa.page).find_noCode);
useEffect(() => {

View File

@ -9,20 +9,23 @@ const ToolBar = ({ setSearchVal, onSave }) => {
const onFinish = (values) => {
const {releaseDate,...ret} = values
if(releaseDate){
ret.stm = moment(values.releaseDate[0]).format('YYYY-MM-DD HH:mm:ss')
ret.etm = moment(values.releaseDate[1]).format('YYYY-MM-DD HH:mm:ss')
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:0,label:'党支部工作制度'},
{value:1,label:'行政工作制度'},
{value:2,label:'部门工作制度'},
{value:3,label:'安全管理制度'},
{value:4,label:'工程管理制度'},
{value:5,label:'技术规程'},
{value:6,label:'岗位责任制'}
{value:1,label:'防洪调度'},
{value:2,label:'兴利调度'},
{value:3,label:'生态调度'},
{value:4,label:'应急调度'},
{value:5,label:'其他'},
]
const opntios1 = [
{value:0,label:'已废弃'},
{value:1,label:'生效中'},
]
return (
@ -38,8 +41,8 @@ const ToolBar = ({ setSearchVal, onSave }) => {
<Form.Item label="编制时间" name="releaseDate">
<RangePicker allowClear />
</Form.Item>
<Form.Item label="状态" name="fillUnit">
<Input allowClear style={{ width: '150px' }} />
<Form.Item label="状态" name="status">
<Select allowClear style={{ width: '150px' }} options={opntios1} />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">查询</Button>

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,311 @@
import React, { useState, useEffect } from 'react';
import { Tree, Input, Checkbox, Spin,Modal,Form,Col,Row,message,Space } from 'antd';
import { EditOutlined,PlusCircleOutlined, DeleteOutlined,ExclamationCircleOutlined} from '@ant-design/icons';
import './index.less';
import { formItemLayout, btnItemLayout } from '../../../../components/crud/FormLayoutProps';
import { getGcaqTreeData } from '../../../../service/warn';
import apiurl from '../../../../service/apiurl';
import { httppost3,httpget6, httpget } from '../../../../utils/request';
const { Search } = Input;
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 adcdTreedata: any = await getGcaqTreeData();
const item:any = adcdTreedata
if (item) {
setSelectedKeys([item[0]?.id])
setAdcd(item[0]?.name)
}
if (adcdTreedata.length > 0) {
handelTreeData(adcdTreedata);
setTreeData(adcdTreedata);
setLoading(false);
setOrderMax(Math.max(...adcdTreedata.map((item:any) => item?.orderIndex)))
}
};
// @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.title;
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 {
const res = await httpget6(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 httppost3(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;

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

@ -0,0 +1,130 @@
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 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 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, fileIds: filesParams, files:undefined})
}
if (mode === 'save') {
onSave(apiurl.zsk.gcaq.save, {...values,createUser:userName,fileIds:filesParams,files:undefined,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}
>
<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={3}
uploadUrl={apiurl.zsk.gcaq.upload}
onChange={(v) => { setFilesParams(v)}}
value={filesParams}
/>
</Form.Item>
</Col>
</Row>
{
mode === 'view' ? null : (
<>
<Form.Item {...btnItemLayout}>
<Button type="primary" htmlType="submit" loading={loading}>
{mode === 'save' ? '提交' : '修改'}
</Button>
</Form.Item>
</>
)
}
</Form>
</>
);
}
export default ModalForm;

View File

@ -0,0 +1,120 @@
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, Switch } from 'antd';
import { FileWordOutlined, FilePdfOutlined, FileZipOutlined, FileExcelOutlined } from '@ant-design/icons';
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/usePageTable2';
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_noCode);
const onEdit = (path, values) => {
createCrudService(path).edit(values).then((result) => {
if (result?.code === 200) {
refresh()
}
})
}
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,51 @@
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>
{
(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, 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 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 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, fileIds: filesParams, files:undefined})
}
if (mode === 'save') {
onSave(apiurl.zsk.ywgz.save, {...values,createUser:userName,fileIds:filesParams,files:undefined})
}
}
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}
>
<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 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 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={3}
uploadUrl={apiurl.zsk.ywgz.upload}
onChange={(v) => { setFilesParams(v);console.log("vvvv",v);
}}
value={filesParams}
/>
</Form.Item>
</Col>
</Row>
{
mode === 'view' ? null : (
<>
<Form.Item {...btnItemLayout}>
<Button type="primary" htmlType="submit" loading={loading}>
{mode === 'save' ? '提交' : '修改'}
</Button>
</Form.Item>
</>
)
}
</Form>
</>
);
}
export default ModalForm;

View File

@ -0,0 +1,98 @@
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, PaperClipOutlined } 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 { httpgetExport } from '../../../utils/request';
import { exportFile } from '../../../utils/tools';
import dayjs from 'dayjs';
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_noCode);
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,69 @@
import React, { useEffect, useState } from 'react';
import { Form, Input, Button, DatePicker, Select } from 'antd';
import { DownOutlined, UpOutlined } from '@ant-design/icons'
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;