feat: 告警提示开发

master
JINGYJ 1 year ago
parent 19fa6ce2f0
commit 7d413768ef

@ -36,7 +36,7 @@ export const mockGetMenuData = {
name: 'realTime-involved-list', name: 'realTime-involved-list',
path: '/realTime/involved-list', path: '/realTime/involved-list',
routes: [], routes: [],
title: '告警汇总', title: '记录汇总',
access: 'canReadMenu', access: 'canReadMenu',
}, },
{ {
@ -83,7 +83,7 @@ export const mockGetMenuData = {
name: 'offline-involved-list-upload', name: 'offline-involved-list-upload',
path: '/offline/involved-list-upload', path: '/offline/involved-list-upload',
routes: [], routes: [],
title: '告警汇总', title: '记录汇总',
}, },
{ {
component: 'Offline/OfflineAlarmList', component: 'Offline/OfflineAlarmList',

@ -13,7 +13,10 @@ 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 {
postUploadWarningStatistics,
postWarningStatistics,
} from '../../../src/services/realTime/alarmlist';
import './index.less'; 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';
@ -79,18 +82,29 @@ const MenuBar: React.FC<MenuBarProps> = ({ menuData }) => {
}; };
// 轮询告警信息 // 轮询告警信息
const [isHaveWarning, setIsHaveWarning] = useState(false); const [isHaveWarning, setIsHaveWarning] = useState(false);
const [isUploadHaveWarning, setIsUploadHaveWarning] = useState(false);
const [totalResults, setTotalResults] = useState([]); const [totalResults, setTotalResults] = useState([]);
const pollServer = () => { const pollServer = () => {
postWarningStatistics({}) postWarningStatistics({})
.then((res) => { .then((res) => {
let have_warning = res.data.have_warning; let have_warning = res.data.have_warning;
console.log(res.data.have_warning, 'pollServer'); console.log(res.data.have_warning, 'pollServer');
let totalResults = res.data.total_results; // let totalResults = res.data.total_results;
setTotalResults(totalResults); // setTotalResults(totalResults);
setIsHaveWarning(() => have_warning); setIsHaveWarning(() => have_warning);
// setTimeout(pollServer, 5000); // setTimeout(pollServer, 5000);
}) })
.catch(() => {}); .catch(() => {});
postUploadWarningStatistics({})
.then((res) => {
let have_warning = res.data.have_warning;
console.log(res.data.have_warning, 'pollServer');
// let totalResults = res.data.total_results;
// setTotalResults(totalResults);
setIsUploadHaveWarning(() => have_warning);
setTimeout(pollServer, 50000);
})
.catch(() => {});
}; };
useEffect(() => { useEffect(() => {
pollServer(); pollServer();
@ -222,6 +236,7 @@ const MenuBar: React.FC<MenuBarProps> = ({ menuData }) => {
<span <span
style={{ style={{
display: 'inline-block', display: 'inline-block',
marginLeft: 8,
width: 10, width: 10,
height: 10, height: 10,
background: '#E80D0D', background: '#E80D0D',
@ -229,6 +244,18 @@ const MenuBar: React.FC<MenuBarProps> = ({ menuData }) => {
}} }}
></span> ></span>
)} )}
{childItem.key === '202' && isUploadHaveWarning && (
<span
style={{
display: 'inline-block',
marginLeft: 8,
width: 10,
height: 10,
background: '#E80D0D',
borderRadius: '50%',
}}
/>
)}
</Menu.Item> </Menu.Item>
))} ))}
</Menu.SubMenu> </Menu.SubMenu>

@ -254,6 +254,9 @@ a.ant-dropdown-trigger {
color: #E80D0D; color: #E80D0D;
background: rgba(232, 13, 13, 0.1); background: rgba(232, 13, 13, 0.1);
} }
.ant-table-wrapper .ant-table-row-expand-icon:focus, .ant-table-wrapper .ant-table-row-expand-icon:hover {
border-color: #004FB2;
}
.gn { .gn {
/* UI // update 使 /* UI // update 使

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

@ -386,7 +386,7 @@ const InvolvedUploadList: React.FC = () => {
</Button> </Button>
<Button <Button
type="primary" // type="primary"
style={{ borderRadius: 4 }} style={{ borderRadius: 4 }}
onClick={() => { onClick={() => {
// setCreateModalOpen(true); // setCreateModalOpen(true);

@ -2,7 +2,7 @@ import { postUploadIgnoringvents } from '@/services/realTime/alarmlist';
import { postUploadRecognition } from '@/services/realTime/involved'; import { postUploadRecognition } 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 moment from 'moment'; import moment from 'moment';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import styles from './AlarmDetails.less'; import styles from './AlarmDetails.less';
@ -111,55 +111,7 @@ 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={false}
// resetButtonProps: {
// style: {
// display: 'none',
// },
// },
// searchConfig: {
// submitText: '忽略此事件',
// },
render: (prop) => {
return [
<Button
key="ok"
style={{ backgroundColor: '#E80D0D', color: '#FFF', borderBlockColor: '#E80D0D' }}
onClick={() => {
prop.submit();
}}
>
</Button>,
props.warning_type === '2' ? null : (
<Button
key="involved"
style={{ backgroundColor: '#FAAD14', color: '#FFF', borderBlockColor: '#FAAD14' }}
onClick={() => {
// console.log(props.updateModalOpen);
setInvolved(1);
handlePostRecognition(props.values?.person_list[0][0], 1);
}}
>
</Button>
),
props.warning_type === '2' ? null : (
<Button
key="noInvolved"
style={{ background: '#FFF', color: '#E80D0D', borderColor: '#E80D0D' }}
onClick={() => {
// console.log(props.updateModalOpen);
setInvolved(0);
handlePostRecognition(props.values?.person_list[0][0], 0);
}}
>
</Button>
),
];
},
}}
submitTimeout={2000} submitTimeout={2000}
onFinish={async (values) => { onFinish={async (values) => {
values.is_ignore = true; values.is_ignore = true;

@ -119,6 +119,7 @@ const ImageWithPopover: React.FC<ImageWithPopoverProps> = ({
}} }}
src={src} src={src}
/> />
{false && (
<Popover <Popover
placement="right" placement="right"
content={content} content={content}
@ -133,10 +134,13 @@ const ImageWithPopover: React.FC<ImageWithPopoverProps> = ({
style={{ position: 'absolute', bottom: 30, right: 0 }} style={{ position: 'absolute', bottom: 30, right: 0 }}
type="text" type="text"
icon={ icon={
<EllipsisOutlined style={{ color: '#fff', fontSize: 24, transform: 'rotate(90deg)' }} /> <EllipsisOutlined
style={{ color: '#fff', fontSize: 24, transform: 'rotate(90deg)' }}
/>
} }
/> />
</Popover> </Popover>
)}
<div <div
style={{ style={{
height: 30, height: 30,

@ -5,7 +5,7 @@ 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 { postUploadAlarmList } from '@/services/realTime/alarmlist'; import { postUploadAlarmList, postUploadAlarmListIschecked } from '@/services/realTime/alarmlist';
import type { DatePickerProps } from 'antd'; import type { DatePickerProps } from 'antd';
import locale from 'antd/es/date-picker/locale/zh_CN'; import locale from 'antd/es/date-picker/locale/zh_CN';
import moment from 'moment'; import moment from 'moment';
@ -57,6 +57,8 @@ const OfflineAlarmList: React.FC = () => {
const changeProjectTab = (key: string) => { const changeProjectTab = (key: string) => {
setTab(key); setTab(key);
console.log(key); console.log(key);
setCurrentPage(1);
setCurrentPageSize(10);
// eslint-disable-next-line @typescript-eslint/no-use-before-define // eslint-disable-next-line @typescript-eslint/no-use-before-define
initList(key); initList(key);
}; };
@ -77,7 +79,7 @@ const OfflineAlarmList: React.FC = () => {
}; };
// 处理初始值 // 处理初始值
function initDataTestList(dataList: Record<string, any>[]) { function initDataTestList(dataList: Record<string, any>[], tabId: string) {
console.log(dataList, 'initDataTestList'); console.log(dataList, 'initDataTestList');
let finalList: { content: React.JSX.Element }[] = []; let finalList: { content: React.JSX.Element }[] = [];
if (Array.isArray(dataList) && dataList.length) { if (Array.isArray(dataList) && dataList.length) {
@ -103,6 +105,8 @@ const OfflineAlarmList: React.FC = () => {
}} }}
onClick={() => { onClick={() => {
console.log('11111111111111111'); console.log('11111111111111111');
// eslint-disable-next-line @typescript-eslint/no-use-before-define
initListRead(tabId, record.id, 1);
setUpdateModalOpen(true); setUpdateModalOpen(true);
setCurrentRow(record); setCurrentRow(record);
}} }}
@ -112,6 +116,7 @@ const OfflineAlarmList: React.FC = () => {
style={{ style={{
marginLeft: 16, marginLeft: 16,
height: 110, height: 110,
position: 'relative',
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
justifyContent: 'space-between', justifyContent: 'space-between',
@ -167,6 +172,20 @@ const OfflineAlarmList: React.FC = () => {
</span> </span>
</div> </div>
</div> </div>
{record.is_checked === 0 && (
<span
style={{
display: 'inline-block',
position: 'absolute',
top: '0px',
right: '-80px',
width: '10px',
height: '10px',
background: '#E80D0D',
borderRadius: '50%',
}}
/>
)}
</div> </div>
</ProCard> </ProCard>
), ),
@ -191,7 +210,24 @@ const OfflineAlarmList: React.FC = () => {
// console.log(resp,'resp'); // console.log(resp,'resp');
// setCurrentPageSize(resp?.data?.count) // setCurrentPageSize(resp?.data?.count)
setTotal(resp?.data?.count); setTotal(resp?.data?.count);
initDataTestList(resp?.data?.results); initDataTestList(resp?.data?.results, tabId);
}
// 初始化加载已读
async function initListRead(tabId: string = tab, id: any, is_checked: any) {
const reqParams = {
page: currentPage,
pageSize: currentPageSize,
// desc: false,
warning_type: tabId,
id: id,
is_checked: is_checked,
// ...rest,
};
await postUploadAlarmListIschecked({ ...reqParams }).then(() => {
initList(tabId);
});
// console.log(resp,'resp');
// setCurrentPageSize(resp?.data?.count)
} }
const onChange: DatePickerProps['onChange'] = (date, dateString) => { const onChange: DatePickerProps['onChange'] = (date, dateString) => {
@ -302,7 +338,7 @@ const OfflineAlarmList: React.FC = () => {
</Button> </Button>
<Button <Button
type="primary" // type="primary"
onClick={() => { onClick={() => {
// setCreateModalOpen(true); // setCreateModalOpen(true);
initList(tab, innerDate); initList(tab, innerDate);

@ -6,7 +6,11 @@ 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, postWarningStatistics } from '@/services/realTime/alarmlist'; import {
postAlarmList,
postAlarmListIschecked,
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';
@ -86,6 +90,7 @@ const AlarmList: React.FC = () => {
<span <span
style={{ style={{
display: 'inline-block', display: 'inline-block',
marginLeft: 5,
width: '10px', width: '10px',
height: '10px', height: '10px',
background: '#E80D0D', background: '#E80D0D',
@ -111,7 +116,10 @@ const AlarmList: React.FC = () => {
// const [tabs, setTabs] = useState<any>([]); // const [tabs, setTabs] = useState<any>([]);
const changeProjectTab = (key: string) => { const changeProjectTab = (key: string) => {
setTab(key); setTab(key);
console.log(key); console.log(key, 'setTab');
setCurrentPage(1);
setCurrentPageSize(10);
pollServer();
// eslint-disable-next-line @typescript-eslint/no-use-before-define // eslint-disable-next-line @typescript-eslint/no-use-before-define
initList(key); initList(key);
}; };
@ -126,7 +134,7 @@ const AlarmList: React.FC = () => {
}; };
// 处理初始值 // 处理初始值
function initDataTestList(dataList: Record<string, any>[]) { function initDataTestList(dataList: Record<string, any>[], tabId: string, selectValues: any) {
console.log(dataList, 'initDataTestList'); console.log(dataList, 'initDataTestList');
let finalList: { content: React.JSX.Element }[] = []; let finalList: { content: React.JSX.Element }[] = [];
if (Array.isArray(dataList) && dataList.length) { if (Array.isArray(dataList) && dataList.length) {
@ -152,6 +160,9 @@ const AlarmList: React.FC = () => {
}} }}
onClick={() => { onClick={() => {
console.log(index, 'index'); console.log(index, 'index');
console.log(tab, selectValue, record.id);
// eslint-disable-next-line @typescript-eslint/no-use-before-define
initListRead(tabId, selectValues, record.id, 1);
setUpdateModalOpen(true); setUpdateModalOpen(true);
setCurrentRow(record); setCurrentRow(record);
}} }}
@ -209,6 +220,20 @@ const AlarmList: React.FC = () => {
</span> </span>
</div> </div>
</div> </div>
{record.is_checked === 0 && (
<span
style={{
display: 'inline-block',
position: 'absolute',
top: '10px',
right: '10px',
width: '10px',
height: '10px',
background: '#E80D0D',
borderRadius: '50%',
}}
/>
)}
</div> </div>
</ProCard> </ProCard>
), ),
@ -236,34 +261,30 @@ const AlarmList: React.FC = () => {
// console.log(resp,'resp'); // console.log(resp,'resp');
// setCurrentPageSize(resp?.data?.count) // setCurrentPageSize(resp?.data?.count)
setTotal(resp?.data?.count); setTotal(resp?.data?.count);
initDataTestList(resp?.data?.results); initDataTestList(resp?.data?.results, tabId, selectValues);
// request={async (params = {}, sort) => { }
// const { current, ...rest } = params; // 初始化加载
// const reqParams = { async function initListRead(
// page: current, tabId: string = tab,
selectValues: any = selectValue,
id: any,
is_checked: any,
) {
const reqParams = {
page: currentPage,
pageSize: currentPageSize,
// desc: false, // desc: false,
// warning_type: tab, platform_id: selectValues,
warning_type: tabId,
id: id,
is_checked: is_checked,
// ...rest, // ...rest,
// }; };
// if (sort && Object.keys(sort).length) { await postAlarmListIschecked({ ...reqParams }).then(() => {
// reqParams.orderKey = Object.keys(sort)[0]; initList(tabId, selectValues);
// let sort_select = sort[reqParams.orderKey]; });
// reqParams.desc = sort_select === 'descend'; // console.log(resp,'resp');
// } // setCurrentPageSize(resp?.data?.count)
// // TODO 联调查询设备状态接口
// console.log(reqParams, 'reqParams');
// let resp = await postAlarmList({ ...reqParams });
// console.log(resp, 'postAlarmList_result');
// initDataTestList(resp.result);
// // return {
// // data: resp.result,
// // success: resp.success,
// // total: resp.count,
// // current: resp.count,
// // pageSize: resp.count,
// // };
// }}
} }
// useEffect(() => { // useEffect(() => {
// getTabs(); // getTabs();
@ -326,7 +347,6 @@ const AlarmList: React.FC = () => {
</Button> </Button>
<Button <Button
type="primary"
style={{ borderRadius: 4 }} style={{ borderRadius: 4 }}
onClick={() => { onClick={() => {
// setCreateModalOpen(true); // setCreateModalOpen(true);

@ -98,7 +98,7 @@ const DeviceList: React.FC = () => {
), ),
dataIndex: 'device_name', dataIndex: 'device_name',
hideInSearch: true, hideInSearch: true,
// width: 150, // width: 240,
}, },
{ {
title: <FormattedMessage id="alarm_rules.page.status" defaultMessage="设备状态" />, title: <FormattedMessage id="alarm_rules.page.status" defaultMessage="设备状态" />,
@ -196,6 +196,7 @@ const DeviceList: React.FC = () => {
/> />
), ),
dataIndex: 'platform_name', dataIndex: 'platform_name',
// width: 240,
hideInSearch: true, hideInSearch: true,
}, },
{ {
@ -228,7 +229,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: '300px', // width: '300px',
fixed: 'right', fixed: 'right',
render: (_, record) => [ render: (_, record) => [
<TableActionCard <TableActionCard

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

@ -93,6 +93,7 @@ const InvolvedList: React.FC = () => {
<span <span
style={{ style={{
display: 'inline-block', display: 'inline-block',
marginLeft: 5,
width: '10px', width: '10px',
height: '10px', height: '10px',
background: '#E80D0D', background: '#E80D0D',
@ -423,7 +424,7 @@ const InvolvedList: React.FC = () => {
</Button> </Button>
<Button <Button
type="primary" // type="primary"
style={{ borderRadius: 4 }} style={{ borderRadius: 4 }}
onClick={() => { onClick={() => {
// setCreateModalOpen(true); // setCreateModalOpen(true);

@ -18,6 +18,17 @@ export async function postAlarmList(
...(options || {}), ...(options || {}),
}); });
} }
/** 告警列表已读 */
export async function postAlarmListIschecked(body: any, options?: { [key: string]: any }) {
return request<API.Response & { data?: API.PageResult; msg?: string }>(`/api/warning_info/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
});
}
/** 忽略事件 */ /** 忽略事件 */
export async function postIgnoringvents( export async function postIgnoringvents(
body: API.IgnoringventsParams, body: API.IgnoringventsParams,
@ -53,6 +64,21 @@ export async function postUploadAlarmList(
); );
} }
/** 上传告警列表 */
export async function postUploadAlarmListIschecked(body: any, options?: { [key: string]: any }) {
return request<API.Response & { data?: API.PageResult; msg?: string }>(
`/api/upload_warning_info/`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
},
);
}
/** 上传忽略事件 */ /** 上传忽略事件 */
export async function postUploadIgnoringvents( export async function postUploadIgnoringvents(
body: API.UploadIgnoringventsParams, body: API.UploadIgnoringventsParams,
@ -85,3 +111,18 @@ export async function postWarningStatistics(body: any, options?: { [key: string]
}, },
); );
} }
/**离线轮询告警信息 */
export async function postUploadWarningStatistics(body: any, options?: { [key: string]: any }) {
return request<API.Response & { data?: API.PageResult; msg?: string }>(
`/api/upload_poll_warning_statistics/`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: body,
...(options || {}),
},
);
}

@ -36,7 +36,7 @@ export const mockGetMenuData = {
name: 'realTime-involved-list', name: 'realTime-involved-list',
path: '/realTime/involved-list', path: '/realTime/involved-list',
routes: [], routes: [],
title: '告警汇总', title: '记录汇总',
access: 'canReadMenu', access: 'canReadMenu',
}, },
{ {
@ -83,7 +83,7 @@ export const mockGetMenuData = {
name: 'offline-involved-list-upload', name: 'offline-involved-list-upload',
path: '/offline/involved-list-upload', path: '/offline/involved-list-upload',
routes: [], routes: [],
title: '告警汇总', title: '记录汇总',
}, },
{ {
component: 'Offline/OfflineAlarmList', component: 'Offline/OfflineAlarmList',

Loading…
Cancel
Save