feat: 监视端开发

master
JINGYJ 12 months ago
parent 60d8ac2afc
commit 19fa6ce2f0

@ -76,21 +76,21 @@ export default [
path: '/offline/alarm-list', path: '/offline/alarm-list',
component: './Offline/OfflineAlarmList', component: './Offline/OfflineAlarmList',
}, },
{ // {
name: 'offline-alarm-rules', // name: 'offline-alarm-rules',
path: '/offline/alarm-rules', // path: '/offline/alarm-rules',
component: './Offline/OfflineAlarmRules', // component: './Offline/OfflineAlarmRules',
}, // },
{ // {
name: 'offline-device-list', // name: 'offline-device-list',
path: '/offline/device-list', // path: '/offline/device-list',
component: './Offline/OfflineDeviceList', // component: './Offline/OfflineDeviceList',
}, // },
{ // {
name: 'offline-video-file', // name: 'offline-video-file',
path: '/offline/video-file', // path: '/offline/video-file',
component: './Offline/VideoFile', // component: './Offline/VideoFile',
}, // },
], ],
}, },
{ {

@ -48,15 +48,15 @@ export const mockGetMenuData = {
routes: [], routes: [],
title: '告警列表', title: '告警列表',
}, },
{ // {
component: 'RealTime/AlarmRules', // component: 'RealTime/AlarmRules',
icon: '', // icon: '',
key: '103', // key: '103',
name: 'realTime-alarm-rules', // name: 'realTime-alarm-rules',
path: '/realTime/alarm-rules', // path: '/realTime/alarm-rules',
routes: [], // routes: [],
title: '告警规则', // title: '告警规则',
}, // },
{ {
component: 'RealTime/DeviceList', component: 'RealTime/DeviceList',
icon: '', icon: '',
@ -64,7 +64,7 @@ export const mockGetMenuData = {
name: 'realTime-device-list', name: 'realTime-device-list',
path: '/realTime/device-list', path: '/realTime/device-list',
routes: [], routes: [],
title: '设备管理', title: '设备状态',
}, },
], ],
}, },
@ -94,33 +94,33 @@ export const mockGetMenuData = {
routes: [], routes: [],
title: '告警列表', title: '告警列表',
}, },
{ // {
component: 'Offline/OfflineAlarmRules', // component: 'Offline/OfflineAlarmRules',
icon: '', // icon: '',
key: '203', // key: '203',
name: 'offline-alarm-rules', // name: 'offline-alarm-rules',
path: '/offline/alarm-rules', // path: '/offline/alarm-rules',
routes: [], // routes: [],
title: '告警规则', // title: '告警规则',
}, // },
{ // {
component: 'Offline/OfflineDeviceList', // component: 'Offline/OfflineDeviceList',
icon: '', // icon: '',
key: '204', // key: '204',
name: 'offline-device-list', // name: 'offline-device-list',
path: '/offline/device-list', // path: '/offline/device-list',
routes: [], // routes: [],
title: '设备管理', // title: '设备管理',
}, // },
{ // {
component: 'Offline/VideoFile', // component: 'Offline/VideoFile',
icon: '', // icon: '',
key: '205', // key: '205',
name: 'offline-video-file', // name: 'offline-video-file',
path: '/offline/video-file', // path: '/offline/video-file',
routes: [], // routes: [],
title: '视频文件', // title: '视频文件',
}, // },
], ],
}, },
], ],

@ -46,3 +46,6 @@
padding-block: 0; padding-block: 0;
padding-inline: 0; padding-inline: 0;
} }
.ant-pro-setting-drawer-handle {
z-index: 10;
}

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/* /*
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2024-03-27 16:03:20 * @Date: 2024-03-27 16:03:20
@ -12,11 +13,11 @@ import type { MenuProps } from 'antd';
import { Menu } from 'antd'; import { Menu } from 'antd';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { postWarningStatistics } from '../../../src/services/realTime/alarmlist';
import './index.less';
import menuFooter from '/public/menuFooter.svg'; import menuFooter from '/public/menuFooter.svg';
import menuLogo from '/public/menuLogo.svg'; import menuLogo from '/public/menuLogo.svg';
import './index.less';
export type MenuBarProps = { export type MenuBarProps = {
menuData: any[]; menuData: any[];
}; };
@ -76,6 +77,27 @@ const MenuBar: React.FC<MenuBarProps> = ({ menuData }) => {
} }
return null; return null;
}; };
// 轮询告警信息
const [isHaveWarning, setIsHaveWarning] = useState(false);
const [totalResults, setTotalResults] = useState([]);
const pollServer = () => {
postWarningStatistics({})
.then((res) => {
let have_warning = res.data.have_warning;
console.log(res.data.have_warning, 'pollServer');
let totalResults = res.data.total_results;
setTotalResults(totalResults);
setIsHaveWarning(() => have_warning);
// setTimeout(pollServer, 5000);
})
.catch(() => {});
};
useEffect(() => {
pollServer();
}, []);
// useEffect(() => {
// console.log(isHaveWarning,'isHaveWarning');
// },[isHaveWarning])
// 当路由变化时更新当前选中菜单项 // 当路由变化时更新当前选中菜单项
useEffect(() => { useEffect(() => {
const pathname = history.location.pathname; const pathname = history.location.pathname;
@ -91,6 +113,9 @@ const MenuBar: React.FC<MenuBarProps> = ({ menuData }) => {
// Check if menuItem has route defined // Check if menuItem has route defined
if (menuItem && menuItem.path) { if (menuItem && menuItem.path) {
history.push(menuItem.path); history.push(menuItem.path);
// history.push(
// menuItem.path,
// {totalResults});
} }
// console.log('menuClick ', e.item.props.path); // console.log('menuClick ', e.item.props.path);
// const currRouteItem = e.item.props; // const currRouteItem = e.item.props;
@ -193,6 +218,17 @@ const MenuBar: React.FC<MenuBarProps> = ({ menuData }) => {
onClick={() => menuClick(childItem)} onClick={() => menuClick(childItem)}
> >
{childItem.title} {childItem.title}
{childItem.key === '102' && isHaveWarning && (
<span
style={{
display: 'inline-block',
width: 10,
height: 10,
background: '#E80D0D',
borderRadius: '50%',
}}
></span>
)}
</Menu.Item> </Menu.Item>
))} ))}
</Menu.SubMenu> </Menu.SubMenu>

@ -73,6 +73,9 @@ export const device_relation: { [key: string]: string } = {
export const interface_manage: { [key: string]: string } = { export const interface_manage: { [key: string]: string } = {
'device.interface_manage.table.list.id': 'ID', 'device.interface_manage.table.list.id': 'ID',
'device.interface_manage.table.list.name': '接口名称', 'device.interface_manage.table.list.name': '接口名称',
'device.interface_manage.table.list.platform_name': '设备名称',
'device.interface_manage.table.list.statusUpdate': '最近一次状态查询',
'device.interface_manage.table.list.rename': '重命名',
'device.interface_manage.table.list.address': '接口地址', 'device.interface_manage.table.list.address': '接口地址',
'device.interface_manage.table.list.ip': 'IP地址', 'device.interface_manage.table.list.ip': 'IP地址',
'device.interface_manage.table.list.createTime': '创建时间', 'device.interface_manage.table.list.createTime': '创建时间',

@ -283,7 +283,13 @@ const OfflineAlarmList: React.FC = () => {
</div> </div>
<div style={{ padding: '16px 0' }}> <div style={{ padding: '16px 0' }}>
<DatePicker locale={locale} value={importDate} onChange={onChange} allowClear /> <DatePicker
style={{ width: 280, borderRadius: 4 }}
locale={locale}
value={importDate}
onChange={onChange}
allowClear
/>
<Button <Button
type="primary" type="primary"
style={{ margin: '0 16px' }} style={{ margin: '0 16px' }}

@ -91,3 +91,8 @@
background: none; background: none;
} }
} }
.select_Bg {
.ant-select-selector {
border-radius: 4px;
}
}

@ -2,7 +2,7 @@ import { postIgnoringvents } from '@/services/realTime/alarmlist';
import { postRecognition } from '@/services/realTime/involved'; import { postRecognition } from '@/services/realTime/involved';
import { ModalForm } from '@ant-design/pro-components'; import { ModalForm } from '@ant-design/pro-components';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { Button, Form, message } from 'antd'; import { Form, message } from 'antd';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
// Import Swiper React components // Import Swiper React components
// import { Swiper, SwiperSlide } from 'swiper/react'; // import { Swiper, SwiperSlide } from 'swiper/react';
@ -109,55 +109,48 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
cancelText: intl.formatMessage({ id: 'common.no', defaultMessage: '取消' }), cancelText: intl.formatMessage({ id: 'common.no', defaultMessage: '取消' }),
className: 'alarmModalForm', className: 'alarmModalForm',
}} }}
submitter={{ // submitter={{
// resetButtonProps: { // render: (prop) => {
// style: { // return [
// display: 'none', // <Button
// }, // key="ok"
// }, // style={{ backgroundColor: '#E80D0D', color: '#FFF', borderBlockColor: '#E80D0D' }}
// searchConfig: { // onClick={() => {
// submitText: '忽略此事件', // prop.submit();
// }}
// >
// 忽略此事件
// </Button>,
// props.values?.person_list ? null : (
// <Button
// key="involved"
// style={{ backgroundColor: '#FAAD14', color: '#FFF', borderBlockColor: '#FAAD14' }}
// onClick={() => {
// // console.log(props.updateModalOpen);
// setInvolved(1);
// handlePostRecognition(props.values?.person_id, 1);
// }}
// >
// 加入重点关注
// </Button>
// ),
// props.values?.person_list ? null : (
// <Button
// key="noInvolved"
// style={{ background: '#FFF', color: '#E80D0D', borderColor: '#E80D0D' }}
// onClick={() => {
// // console.log(props.updateModalOpen);
// setInvolved(0);
// handlePostRecognition(props.values?.person_id, 0);
// }}
// >
// 移除重点关注
// </Button>
// ),
// ];
// }, // },
render: (prop) => { // }}
return [ submitter={false}
<Button
key="ok"
style={{ backgroundColor: '#E80D0D', color: '#FFF', borderBlockColor: '#E80D0D' }}
onClick={() => {
prop.submit();
}}
>
</Button>,
props.values?.person_list ? null : (
<Button
key="involved"
style={{ backgroundColor: '#FAAD14', color: '#FFF', borderBlockColor: '#FAAD14' }}
onClick={() => {
// console.log(props.updateModalOpen);
setInvolved(1);
handlePostRecognition(props.values?.person_id, 1);
}}
>
</Button>
),
props.values?.person_list ? null : (
<Button
key="noInvolved"
style={{ background: '#FFF', color: '#E80D0D', borderColor: '#E80D0D' }}
onClick={() => {
// console.log(props.updateModalOpen);
setInvolved(0);
handlePostRecognition(props.values?.person_id, 0);
}}
>
</Button>
),
];
},
}}
submitTimeout={2000} submitTimeout={2000}
onFinish={async (values) => { onFinish={async (values) => {
values.is_ignore = true; values.is_ignore = true;

@ -1,15 +1,17 @@
import { alarmRulesEnums } from '@/enums/status'; import { alarmRulesEnums } from '@/enums/status';
import { PageContainer, ProCard, ProList } from '@ant-design/pro-components'; import { PageContainer, ProCard, ProList } from '@ant-design/pro-components';
import { Button, Image } from 'antd'; import { Button, Image, Select } from 'antd';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { proTablePaginationOptions } from '../../../../config/defaultTable'; import { proTablePaginationOptions } from '../../../../config/defaultTable';
// import DeviceStatusCard from './components/DeviceStatusCard'; // import DeviceStatusCard from './components/DeviceStatusCard';
// import CreateForm from './components/CreateForm'; // import CreateForm from './components/CreateForm';
import { useMoment } from '@/hooks/useMoment'; import { useMoment } from '@/hooks/useMoment';
import { postAlarmList } from '@/services/realTime/alarmlist'; import { postAlarmList, postWarningStatistics } from '@/services/realTime/alarmlist';
import Alarm_list_bg from '../../../../public/Alarm_list_bg.png'; import Alarm_list_bg from '../../../../public/Alarm_list_bg.png';
import { ReactComponent as NoData } from '../../../../public/images/no_data.svg'; import { ReactComponent as NoData } from '../../../../public/images/no_data.svg';
import AlarmDetails from './components/AlarmDetails'; import AlarmDetails from './components/AlarmDetails';
// import { useLocation } from '@umijs/max';
import './components/AlarmDetails.less';
/** /**
* @ * @
@ -66,6 +68,46 @@ const AlarmList: React.FC = () => {
const [dataTestList, setdataTestList] = useState<any>([]); const [dataTestList, setdataTestList] = useState<any>([]);
const [tab, setTab] = useState<string>(alarmRulesEnums[0].key); const [tab, setTab] = useState<string>(alarmRulesEnums[0].key);
// const location = useLocation();
// const { state } = location;
const [selectOptions, setSelectOptions] = useState<any>([]);
const [selectValue, setSelectValue] = useState<number>();
const pollServer = () => {
postWarningStatistics({})
.then((res) => {
if (res && res.data.total_results) {
// 使用 state.totalResults 来设置 selectOptions
const newOptions = res.data.total_results.map((record: any) => ({
value: record.id,
label: (
<span>
{record.platform_name}
{record.have_warning && (
<span
style={{
display: 'inline-block',
width: '10px',
height: '10px',
background: '#E80D0D',
borderRadius: '50%',
}}
/>
)}
</span>
),
}));
setSelectValue(res.data.total_results[0].id);
setSelectOptions(newOptions);
}
console.log(selectValue, 'selectValue');
// setTimeout(pollServer, 5000);
})
.catch(() => {});
};
useEffect(() => {
pollServer();
console.log(selectOptions);
}, []);
// const [tabs, setTabs] = useState<any>([]); // const [tabs, setTabs] = useState<any>([]);
const changeProjectTab = (key: string) => { const changeProjectTab = (key: string) => {
setTab(key); setTab(key);
@ -73,23 +115,6 @@ const AlarmList: React.FC = () => {
// eslint-disable-next-line @typescript-eslint/no-use-before-define // eslint-disable-next-line @typescript-eslint/no-use-before-define
initList(key); initList(key);
}; };
// const getTabs = () => {
// // if (alarmRulesEnums.length) {
// // setTab(alarmRulesEnums[0].key);
// // }
// setTabs(alarmRulesEnums);
// };
// useEffect(() => {
// getTabs();
// }, []);
// const handleCreateModal = () => {
// if (createModalOpen) {
// setCreateModalOpen(false);
// setCurrentRow(undefined);
// } else {
// setCreateModalOpen(true);
// }
// };
const handleUpdateModal = () => { const handleUpdateModal = () => {
if (updateModalOpen) { if (updateModalOpen) {
@ -100,41 +125,6 @@ const AlarmList: React.FC = () => {
} }
}; };
// const handleDestroy = async () => {
// if (modalOpen) {
// setModalOpen(false);
// setCurrentRow(undefined);
// } else {
// setModalOpen(true);
// }
// // deleteBusinessImageDeleteBusinessImage({ id: selectedRow.id })
// // .then(() => {
// // message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '$$$' }));
// // actionRef.current?.reload();
// // })
// // .catch(() => {
// // message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' }));
// // });
// };
// const { confirm } = Modal;
// const showConfirm = (record: any) => {
// confirm({
// title: `确定删除${record.name}吗`,
// icon: <QuestionCircleFilled />,
// content: '确定删除服务器1吗删除后将找不到此服务器请谨慎操作.',
// okText: '确认',
// cancelText: '取消',
// width: 560,
// onOk() {
// console.log('OK');
// },
// onCancel() {
// console.log('Cancel');
// },
// });
// };
// 处理初始值 // 处理初始值
function initDataTestList(dataList: Record<string, any>[]) { function initDataTestList(dataList: Record<string, any>[]) {
console.log(dataList, 'initDataTestList'); console.log(dataList, 'initDataTestList');
@ -228,13 +218,17 @@ const AlarmList: React.FC = () => {
setdataTestList(() => [...finalList]); setdataTestList(() => [...finalList]);
} }
const handleChange = (value: any) => {
console.log(`selected ${value}`);
setSelectValue(value);
};
// 初始化加载 // 初始化加载
async function initList(tabId: string = tab) { async function initList(tabId: string = tab, selectValues: any = selectValue) {
const reqParams = { const reqParams = {
page: currentPage, page: currentPage,
pageSize: currentPageSize, pageSize: currentPageSize,
// desc: false, // desc: false,
platform_id: selectValues,
warning_type: tabId, warning_type: tabId,
// ...rest, // ...rest,
}; };
@ -313,6 +307,39 @@ const AlarmList: React.FC = () => {
changeProjectTab(key); changeProjectTab(key);
}} }}
></Tabs> */} ></Tabs> */}
<div style={{ marginBottom: 16 }}>
<Select
defaultValue={1}
className="select_Bg"
style={{ width: 280, borderRadius: 4 }}
onChange={handleChange}
options={selectOptions}
/>
<Button
type="primary"
style={{ margin: '0 12px', borderRadius: 4 }}
onClick={() => {
// setCreateModalOpen(true);
initList();
}}
>
</Button>
<Button
type="primary"
style={{ borderRadius: 4 }}
onClick={() => {
// setCreateModalOpen(true);
// setImportDate(null);
// setInnerDate(null);
setTab(alarmRulesEnums[0].key);
setSelectValue(1);
initList(alarmRulesEnums[0].key, 1);
}}
>
</Button>
</div>
<div style={{ marginBottom: 12 }}> <div style={{ marginBottom: 12 }}>
<Button <Button
style={{ height: 32, borderRadius: 20 }} style={{ height: 32, borderRadius: 20 }}

@ -1,4 +1,4 @@
import { postTestDevice } from '@/services/realTime/interfaces'; import { postTestDevice, postTestlPatform } from '@/services/realTime/interfaces';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { Button, Tag, message } from 'antd'; import { Button, Tag, message } from 'antd';
import moment from 'moment'; import moment from 'moment';
@ -15,6 +15,7 @@ const CaptureButton: React.FC<ImageSinglePopoverProps> = (props) => {
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
const connection = () => { const connection = () => {
setLoading(true); setLoading(true);
if (props.values.device_ip) {
postTestDevice({ postTestDevice({
device_ip: props.values.device_ip, device_ip: props.values.device_ip,
id: props.values.id, id: props.values.id,
@ -30,6 +31,23 @@ const CaptureButton: React.FC<ImageSinglePopoverProps> = (props) => {
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' })); message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
setLoading(false); setLoading(false);
}); });
} else {
postTestlPatform({
// device_ip: props.values.device_ip,
id: props.values.id,
})
.then((res) => {
if (res.success) {
message.success(res.msg);
}
props.reload();
setLoading(false);
})
.catch(() => {
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
setLoading(false);
});
}
}; };
return ( return (

@ -37,6 +37,12 @@
border-start-end-radius: 0; border-start-end-radius: 0;
} }
} }
.table_body_bg {
.ant-spin-container {
padding-left: 24px;
background: #fff;
}
}
.DeviceList { .DeviceList {
.ant-modal-content { .ant-modal-content {
background: linear-gradient(180deg, #e3ebfc 0%, #ffffff 23%); background: linear-gradient(180deg, #e3ebfc 0%, #ffffff 23%);

@ -6,11 +6,11 @@
* @FilePath: \general-ai-platform-web\src\pages\Device\DeviceCategoryList\components\UpdateForm.tsx * @FilePath: \general-ai-platform-web\src\pages\Device\DeviceCategoryList\components\UpdateForm.tsx
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/ */
import { postInterfaces, postTestDevice } from '@/services/realTime/interfaces'; import { postPlatform } from '@/services/realTime/interfaces';
import { ModalForm, ProForm, ProFormText, ProFormTextArea } from '@ant-design/pro-components'; import { ModalForm, ProForm, ProFormText } from '@ant-design/pro-components';
import { FormattedMessage, useIntl } from '@umijs/max'; import { FormattedMessage, useIntl } from '@umijs/max';
import { Button, Form, message } from 'antd'; import { Form, message } from 'antd';
import React, { useState } from 'react'; // import React, { useState } from 'react';
import { import {
proFormSmallItemStyleProps, proFormSmallItemStyleProps,
proFormSmallModelWidth, proFormSmallModelWidth,
@ -33,28 +33,28 @@ export type UpdateFormProps = {
const UpdateForm: React.FC<UpdateFormProps> = (props) => { const UpdateForm: React.FC<UpdateFormProps> = (props) => {
const intl = useIntl(); const intl = useIntl();
const [form] = Form.useForm<API.UpdateInterfacesParams>(); const [form] = Form.useForm<API.UpdateInterfacesParams>();
const [loading, setLoading] = useState<boolean>(false); // const [loading, setLoading] = useState<boolean>(false);
const connection = () => { // const connection = () => {
setLoading(true); // setLoading(true);
console.log(props.values); // console.log(props.values);
postTestDevice({ // postTestDevice({
device_ip: form.getFieldsValue().device_ip, // device_ip: form.getFieldsValue().device_ip,
id: props.values.id, // id: props.values.id,
}) // })
.then((res) => { // .then((res) => {
// message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '成功' })); // // message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '成功' }));
// props.reload(); // // props.reload();
console.log(res); // console.log(res);
if (res.success) { // if (res.success) {
message.success(res.msg); // message.success(res.msg);
} // }
setLoading(false); // setLoading(false);
}) // })
.catch(() => { // .catch(() => {
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' })); // message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
setLoading(false); // setLoading(false);
}); // });
}; // };
return ( return (
<ModalForm<any> <ModalForm<any>
@ -69,7 +69,7 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
modalProps={{ modalProps={{
destroyOnClose: true, destroyOnClose: true,
onCancel: () => { onCancel: () => {
setLoading(false); // setLoading(false);
props.handleModal(); props.handleModal();
}, },
okText: intl.formatMessage({ id: 'common.okText', defaultMessage: '确认' }), okText: intl.formatMessage({ id: 'common.okText', defaultMessage: '确认' }),
@ -80,7 +80,7 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
onFinish={async (values) => { onFinish={async (values) => {
console.log(values); console.log(values);
values.id = props.values.id; values.id = props.values.id;
postInterfaces(values) postPlatform(values)
.then(() => { .then(() => {
message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '成功' })); message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '成功' }));
props.reload(); props.reload();
@ -96,7 +96,7 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
<ProForm.Group> <ProForm.Group>
<ProFormText <ProFormText
width={proFormSmallItemStyleProps.width} width={proFormSmallItemStyleProps.width}
name="device_name" name="platform_name"
label={ label={
<span style={{ fontWeight: 'bold' }}> <span style={{ fontWeight: 'bold' }}>
<FormattedMessage <FormattedMessage
@ -113,7 +113,7 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
defaultMessage: '接口名称', defaultMessage: '接口名称',
})}`} })}`}
required={true} required={true}
initialValue={props.values.device_name} initialValue={props.values.platform_name}
rules={[ rules={[
{ {
required: true, required: true,
@ -126,7 +126,7 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
}, },
]} ]}
/> />
<ProFormText {/* <ProFormText
width={proFormSmallItemStyleProps.width} width={proFormSmallItemStyleProps.width}
name="device_address" name="device_address"
label={ label={
@ -259,7 +259,7 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
})}`} })}`}
initialValue={props.values.note} initialValue={props.values.note}
required={false} required={false}
/> /> */}
</ProForm.Group> </ProForm.Group>
</ModalForm> </ModalForm>
); );

@ -1,10 +1,9 @@
import TableActionCard from '@/components/TableActionCard'; import TableActionCard from '@/components/TableActionCard';
import IsDelete from '@/components/TableActionCard/isDelete'; import { getPlatform } from '@/services/realTime/interfaces';
import { getInterfaces, postInterfaces } from '@/services/realTime/interfaces';
import type { ActionType, ProColumns } from '@ant-design/pro-components'; import type { ActionType, ProColumns } from '@ant-design/pro-components';
import { PageContainer, ProCard, ProTable } from '@ant-design/pro-components'; import { PageContainer, ProCard, ProTable } from '@ant-design/pro-components';
import { FormattedMessage, useIntl } from '@umijs/max'; import { FormattedMessage } from '@umijs/max';
import { Button, message } from 'antd'; import { Button } from 'antd';
import React, { useRef, useState } from 'react'; import React, { useRef, useState } from 'react';
import { proTablePaginationOptions } from '../../../../config/defaultTable'; import { proTablePaginationOptions } from '../../../../config/defaultTable';
import CaptureButton from './components/CaptureButton'; import CaptureButton from './components/CaptureButton';
@ -13,29 +12,30 @@ import './components/CaptureForm.less';
import CreateForm from './components/CreateForm'; import CreateForm from './components/CreateForm';
import UpdateForm from './components/UpdateForm'; import UpdateForm from './components/UpdateForm';
// svg 转组件 // svg 转组件
import { ReactComponent as Details } from '../../../../public/images/icons/details.svg'; // import { ReactComponent as Details } from '../../../../public/images/icons/details.svg';
// import { ReactComponent as Delete } from '../../../../public/images/icons/delete.svg'; // import { ReactComponent as Delete } from '../../../../public/images/icons/delete.svg';
import { EditOutlined } from '@ant-design/icons';
import { ReactComponent as Capture } from '../../../../public/images/icons/capture.svg'; import { ReactComponent as Capture } from '../../../../public/images/icons/capture.svg';
const DeviceList: React.FC = () => { const DeviceList: React.FC = () => {
/** /**
* @en-US International configuration * @en-US International configuration
* @zh-CN * @zh-CN
* */ * */
const intl = useIntl(); // const intl = useIntl();
const actionRef = useRef<ActionType>(); const actionRef = useRef<ActionType>();
// 动态设置每页数量 // 动态设置每页数量
const [currentPageSize, setCurrentPageSize] = useState<number>(10); const [currentPageSize, setCurrentPageSize] = useState<number>(10);
const handleDestroy = async (selectedRow: API.UpdateInterfacesParams) => { // const handleDestroy = async (selectedRow: API.UpdateInterfacesParams) => {
postInterfaces({ id: selectedRow.id, device_status: '3' }) // postInterfaces({ id: selectedRow.id, device_status: '3' })
.then(() => { // .then(() => {
message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '成功' })); // message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '成功' }));
actionRef.current?.reload(); // actionRef.current?.reload();
}) // })
.catch(() => { // .catch(() => {
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' })); // message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
}); // });
}; // };
const [currentRow, setCurrentRow] = useState<API.UpdateInterfacesParams>(); const [currentRow, setCurrentRow] = useState<API.UpdateInterfacesParams>();
/** /**
@ -75,34 +75,40 @@ const DeviceList: React.FC = () => {
setCaptureModalOpen(true); setCaptureModalOpen(true);
} }
}; };
const columns: ProColumns<API.UpdateInterfacesParams>[] = [ const expandedRowRender = (record: any) => {
console.log(record, 'record');
const data = record.devices;
return (
<ProTable
className="table_body_bg"
cardProps={{
bodyStyle: {
margin: 0,
padding: 0,
},
}}
rowKey={(record) => record.id}
columns={[
{ {
title: ( title: (
<FormattedMessage id="device.interface_manage.table.list.name" defaultMessage="接口名称" /> <FormattedMessage
id="device.interface_manage.table.list.name"
defaultMessage="接口名称"
/>
), ),
dataIndex: 'device_name', dataIndex: 'device_name',
hideInSearch: true, hideInSearch: true,
// width: 150,
}, },
{ {
title: <FormattedMessage id="alarm_rules.page.status" defaultMessage="设备状态" />, title: <FormattedMessage id="alarm_rules.page.status" defaultMessage="设备状态" />,
dataIndex: 'test_result', dataIndex: 'test_result',
hideInSearch: true, hideInSearch: true,
// width: 280,
render: (dom, entity) => { render: (dom, entity) => {
return <CaptureButton values={entity || {}} reload={actionRef.current?.reload} />; return <CaptureButton values={entity || {}} reload={actionRef.current?.reload} />;
}, },
}, },
// {
// title: <FormattedMessage id="device.interface_manage.table.list.address" defaultMessage="接口地址" />,
// dataIndex: 'device_api',
// hideInSearch: true,
// },
// {
// title: <FormattedMessage id="device.interface_manage.table.list.testTime" defaultMessage="状态查询时间" />,
// dataIndex: 'test_time',
// sorter: true,
// hideInSearch: true,
// valueType: 'dateTime',
// },
{ {
title: ( title: (
<FormattedMessage <FormattedMessage
@ -110,6 +116,7 @@ const DeviceList: React.FC = () => {
defaultMessage="创建时间" defaultMessage="创建时间"
/> />
), ),
// width: 200,
dataIndex: 'create_time', dataIndex: 'create_time',
sorter: true, sorter: true,
hideInSearch: true, hideInSearch: true,
@ -120,7 +127,7 @@ const DeviceList: React.FC = () => {
title: <FormattedMessage id="pages.searchTable.titleOption" defaultMessage="操作" />, title: <FormattedMessage id="pages.searchTable.titleOption" defaultMessage="操作" />,
dataIndex: 'option', dataIndex: 'option',
valueType: 'option', valueType: 'option',
width: '260px', // width: 100,
fixed: 'right', fixed: 'right',
render: (_, record) => [ render: (_, record) => [
<TableActionCard <TableActionCard
@ -166,31 +173,116 @@ const DeviceList: React.FC = () => {
</Button> </Button>
), ),
}, },
]}
></TableActionCard>,
],
},
]}
headerTitle={false}
search={false}
options={false}
dataSource={data}
pagination={false}
showHeader={false}
/>
);
};
const columns: ProColumns<API.UpdateInterfacesParams>[] = [
{
title: (
<FormattedMessage
id="device.interface_manage.table.list.platform_name"
defaultMessage="设备名称"
/>
),
dataIndex: 'platform_name',
hideInSearch: true,
},
{
title: (
<FormattedMessage
id="device.interface_manage.table.list.statusUpdate"
defaultMessage="最近一次状态查询"
/>
),
dataIndex: 'test_result',
hideInSearch: true,
render: (dom, entity) => {
return <CaptureButton values={entity || {}} reload={actionRef.current?.reload} />;
},
},
{
title: (
<FormattedMessage
id="device.interface_manage.table.list.createTime"
defaultMessage="创建时间"
/>
),
dataIndex: 'create_time',
sorter: true,
hideInSearch: true,
valueType: 'dateTime',
},
{ {
key: 'update', title: <FormattedMessage id="pages.searchTable.titleOption" defaultMessage="操作" />,
dataIndex: 'option',
valueType: 'option',
width: '300px',
fixed: 'right',
render: (_, record) => [
<TableActionCard
key="TableActionCardRef"
renderActions={[
{
key: 'capture',
renderDom: ( renderDom: (
// <Button
// key="capture"
// type="link"
// size="small"
// style={{
// color: '#004FB2',
// }}
// icon={
// <Capture
// style={{
// marginRight: 3,
// display: 'inline-flex',
// alignItems: 'center',
// color: 'inherit',
// fontStyle: 'normal',
// lineHeight: 0,
// textAlign: 'center',
// textTransform: 'none',
// verticalAlign: '-0.2em',
// textRendering: 'optimizeLegibility',
// }}
// />
// }
// onClick={() => {
// console.log('11');
// setCaptureModalOpen(true);
// setCurrentRow(record);
// }}
// >
// {/* 最近拍摄 */}
// <FormattedMessage
// id="device.interface_manage.table.list.capture"
// defaultMessage="最近拍摄"
// />
// </Button>
<Button <Button
key="update" key="update"
type="link" type="link"
size="small" size="small"
style={{ style={{
color: '#004FB2', color: '#004FB2',
// display: 'flex',
alignItems: 'center',
}} }}
icon={ icon={
<Details <EditOutlined
style={{ style={{
marginRight: 3, marginRight: 3,
display: 'inline-flex',
alignItems: 'center',
color: 'inherit',
fontStyle: 'normal',
lineHeight: 0,
textAlign: 'center',
textTransform: 'none',
verticalAlign: '-0.2em',
textRendering: 'optimizeLegibility',
}} }}
/> />
} }
@ -199,20 +291,13 @@ const DeviceList: React.FC = () => {
setCurrentRow(record); setCurrentRow(record);
}} }}
> >
<FormattedMessage id="common.details" defaultMessage="详情" /> <FormattedMessage
id="device.interface_manage.table.list.rename"
defaultMessage="重命名"
/>
</Button> </Button>
), ),
}, },
{
key: 'destroy',
renderDom: (
<IsDelete
deleteApi={() => {
handleDestroy(record).then(() => {});
}}
></IsDelete>
),
},
]} ]}
></TableActionCard>, ></TableActionCard>,
], ],
@ -301,23 +386,23 @@ const DeviceList: React.FC = () => {
style={{ margin: 0, padding: 0, boxShadow: '0px 4px 8px 0px rgba(0,79,178,0.15)' }} style={{ margin: 0, padding: 0, boxShadow: '0px 4px 8px 0px rgba(0,79,178,0.15)' }}
bodyStyle={{ margin: 0, padding: 0 }} bodyStyle={{ margin: 0, padding: 0 }}
headerBordered headerBordered
title="设备列表" title="设备状态"
extra={ // extra={
<Button // <Button
type="primary" // type="primary"
style={{ // style={{
boxShadow: 'none', // boxShadow: 'none',
}} // }}
onClick={() => { // onClick={() => {
setCreateModalOpen(true); // setCreateModalOpen(true);
}} // }}
> // >
<FormattedMessage // <FormattedMessage
id="device.interface_manage.table.list.add" // id="device.interface_manage.table.list.add"
defaultMessage="新建设备/输入源" // defaultMessage="新建设备/输入源"
/> // />
</Button> // </Button>
} // }
> >
<ProTable<API.DeviceCategory> <ProTable<API.DeviceCategory>
cardProps={{ cardProps={{
@ -353,7 +438,7 @@ const DeviceList: React.FC = () => {
let sort_select = sort[reqParams.orderKey]; let sort_select = sort[reqParams.orderKey];
reqParams.desc = sort_select === 'descend'; reqParams.desc = sort_select === 'descend';
} }
let resp = await getInterfaces({ ...reqParams }); let resp = await getPlatform({ ...reqParams });
return { return {
data: resp.data.results.map((v: API.DeviceCategory) => { data: resp.data.results.map((v: API.DeviceCategory) => {
return { ...v, key: v.id }; return { ...v, key: v.id };
@ -365,6 +450,7 @@ const DeviceList: React.FC = () => {
}; };
}} }}
columns={columns} columns={columns}
expandable={{ expandedRowRender }}
/> />
</ProCard> </ProCard>
<CreateForm <CreateForm

@ -67,7 +67,7 @@ const ImageWithPopover: React.FC<ImageWithPopoverProps> = ({
preview={false} preview={false}
src={src} src={src}
/> />
{classify === 1 && ( {classify === 0 && (
<Popover <Popover
placement="right" placement="right"
content={content} content={content}

@ -59,3 +59,8 @@
padding-block-start: 0; padding-block-start: 0;
} }
} }
.select_Bg {
.ant-select-selector {
border-radius: 4px;
}
}

@ -1,10 +1,11 @@
// import { alarmRulesEnums } from '@/enums/status'; // import { alarmRulesEnums } from '@/enums/status';
import { PageContainer, ProCard, ProList } from '@ant-design/pro-components'; import { PageContainer, ProCard, ProList } from '@ant-design/pro-components';
import { Button, Checkbox, DatePicker } from 'antd'; import { Button, Checkbox, DatePicker, Select } from 'antd';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { proTablePaginationOptions } from '../../../../config/defaultTable'; import { proTablePaginationOptions } from '../../../../config/defaultTable';
// import DeviceStatusCard from './components/DeviceStatusCard'; // import DeviceStatusCard from './components/DeviceStatusCard';
// import CreateForm from './components/CreateForm'; // import CreateForm from './components/CreateForm';
import { postWarningStatistics } from '@/services/realTime/alarmlist';
import { getInvolvedList } from '@/services/realTime/involved'; import { getInvolvedList } from '@/services/realTime/involved';
import locale from 'antd/es/date-picker/locale/zh_CN'; import locale from 'antd/es/date-picker/locale/zh_CN';
import { CheckboxProps } from 'antd/lib/checkbox'; import { CheckboxProps } from 'antd/lib/checkbox';
@ -75,29 +76,44 @@ const InvolvedList: React.FC = () => {
const [importDate, setImportDate] = useState<any>(null); const [importDate, setImportDate] = useState<any>(null);
const [innerDate, setInnerDate] = useState<any>(null); const [innerDate, setInnerDate] = useState<any>(null);
const [classify, setClassify] = useState<string>('all'); const [classify, setClassify] = useState<string>('all');
// const changeProjectTab = (key: string) => {
// setTab(key); const [selectOptions, setSelectOptions] = useState<any>([]);
// console.log(key); const [selectValue, setSelectValue] = useState<number>();
// // eslint-disable-next-line @typescript-eslint/no-use-before-define const pollServer = () => {
// initList(key) postWarningStatistics({})
// }; .then((res) => {
// const getTabs = () => { if (res && res.data.total_results) {
// // if (alarmRulesEnums.length) { // 使用 state.totalResults 来设置 selectOptions
// // setTab(alarmRulesEnums[0].key); const newOptions = res.data.total_results.map((record: any) => ({
// // } value: record.id,
// setTabs(alarmRulesEnums); label: (
// }; <span>
// useEffect(() => { {record.platform_name}
// getTabs(); {record.have_warning && (
// }, []); <span
// const handleCreateModal = () => { style={{
// if (createModalOpen) { display: 'inline-block',
// setCreateModalOpen(false); width: '10px',
// setCurrentRow(undefined); height: '10px',
// } else { background: '#E80D0D',
// setCreateModalOpen(true); borderRadius: '50%',
// } }}
// }; />
)}
</span>
),
}));
setSelectValue(res.data.total_results[0].id);
setSelectOptions(newOptions);
}
// setTimeout(pollServer, 5000);
})
.catch(() => {});
};
useEffect(() => {
pollServer();
console.log(selectValue, 'selectValue');
}, []);
const handleUpdateModal = () => { const handleUpdateModal = () => {
if (updateModalOpen) { if (updateModalOpen) {
@ -270,13 +286,18 @@ const InvolvedList: React.FC = () => {
} }
// 初始化加载 // 初始化加载
async function initList(tabId: string = 'all', date: any = null) { async function initList(
tabId: string = 'all',
date: any = null,
selectValues: any = selectValue,
) {
const reqParams = { const reqParams = {
page: currentPage, page: currentPage,
pageSize: currentPageSize, pageSize: currentPageSize,
// desc: false, // desc: false,
classify: tabId, classify: tabId,
analyse_time: date, analyse_time: date,
platform_id: selectValues,
// ...rest, // ...rest,
}; };
const resp = await getInvolvedList({ ...reqParams }); const resp = await getInvolvedList({ ...reqParams });
@ -328,6 +349,10 @@ const InvolvedList: React.FC = () => {
initList('all', innerDate); initList('all', innerDate);
} }
}; };
const handleChange = (value: any) => {
console.log(`selected ${value}`);
setSelectValue(value);
};
// useEffect(() => { // useEffect(() => {
// // getTabs(); // // getTabs();
// // initList(); // // initList();
@ -373,6 +398,13 @@ const InvolvedList: React.FC = () => {
}} }}
> >
<div style={{ paddingBottom: 16 }}> <div style={{ paddingBottom: 16 }}>
<Select
defaultValue={1}
className="select_Bg"
style={{ width: 280, borderRadius: 4, marginRight: 12 }}
onChange={handleChange}
options={selectOptions}
/>
<DatePicker <DatePicker
style={{ width: 280, borderRadius: 4 }} style={{ width: 280, borderRadius: 4 }}
locale={locale} locale={locale}

@ -70,3 +70,18 @@ export async function postUploadIgnoringvents(
}, },
); );
} }
/**轮询告警信息 */
export async function postWarningStatistics(body: any, options?: { [key: string]: any }) {
return request<API.Response & { data?: API.PageResult; msg?: string }>(
`/api/poll_warning_statistics/`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
},
);
}

@ -122,3 +122,50 @@ export async function postAlgorithm(body: any, options?: { [key: string]: any })
}, },
); );
} }
/** 获取平台信息及接口信息 */
export async function getPlatform(
params: API.SearchAlarmRulesParams | any,
options?: { [key: string]: any },
) {
return request<API.Response & { data?: API.PageResult; msg?: string }>(`/api/platform/`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
params: {
...params,
},
...(options || {}),
});
}
/** 更新平台信息及接口信息 */
export async function postPlatform(
body: API.UpdateInterfacesParams | any,
options?: { [key: string]: any },
) {
return request<API.Response & { data?: API.PageResult; msg?: string }>(`/api/platform/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** 测试平台连通 */
export async function postTestlPatform(
body: API.UpdateInterfacesParams | any,
options?: { [key: string]: any },
) {
return request<API.Response & { data?: API.PageResult; msg?: string }>(`/api/test_platform/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}

@ -90,6 +90,7 @@ declare namespace API {
destination_directory?: string; destination_directory?: string;
operate_mode?: string; operate_mode?: string;
source_directory?: string; source_directory?: string;
platform_name?: string;
}; };
type UpdateVideoParams = { type UpdateVideoParams = {
create_time?: string; // 设备名称 create_time?: string; // 设备名称

@ -48,15 +48,15 @@ export const mockGetMenuData = {
routes: [], routes: [],
title: '告警列表', title: '告警列表',
}, },
{ // {
component: 'RealTime/AlarmRules', // component: 'RealTime/AlarmRules',
icon: '', // icon: '',
key: '103', // key: '103',
name: 'realTime-alarm-rules', // name: 'realTime-alarm-rules',
path: '/realTime/alarm-rules', // path: '/realTime/alarm-rules',
routes: [], // routes: [],
title: '告警规则', // title: '告警规则',
}, // },
{ {
component: 'RealTime/DeviceList', component: 'RealTime/DeviceList',
icon: '', icon: '',
@ -64,7 +64,7 @@ export const mockGetMenuData = {
name: 'realTime-device-list', name: 'realTime-device-list',
path: '/realTime/device-list', path: '/realTime/device-list',
routes: [], routes: [],
title: '设备管理', title: '设备状态',
}, },
], ],
}, },
@ -94,33 +94,33 @@ export const mockGetMenuData = {
routes: [], routes: [],
title: '告警列表', title: '告警列表',
}, },
{ // {
component: 'Offline/OfflineAlarmRules', // component: 'Offline/OfflineAlarmRules',
icon: '', // icon: '',
key: '203', // key: '203',
name: 'offline-alarm-rules', // name: 'offline-alarm-rules',
path: '/offline/alarm-rules', // path: '/offline/alarm-rules',
routes: [], // routes: [],
title: '告警规则', // title: '告警规则',
}, // },
{ // {
component: 'Offline/OfflineDeviceList', // component: 'Offline/OfflineDeviceList',
icon: '', // icon: '',
key: '204', // key: '204',
name: 'offline-device-list', // name: 'offline-device-list',
path: '/offline/device-list', // path: '/offline/device-list',
routes: [], // routes: [],
title: '设备管理', // title: '设备管理',
}, // },
{ // {
component: 'Offline/VideoFile', // component: 'Offline/VideoFile',
icon: '', // icon: '',
key: '205', // key: '205',
name: 'offline-video-file', // name: 'offline-video-file',
path: '/offline/video-file', // path: '/offline/video-file',
routes: [], // routes: [],
title: '视频文件', // title: '视频文件',
}, // },
], ],
}, },
], ],

Loading…
Cancel
Save