feat: 完成内层layout构建
parent
0b8f2759bc
commit
c86d2b7a9e
@ -0,0 +1,9 @@
|
||||
<svg t="1713774734546" class="icon" viewBox="0 0 1024 1024" version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg" p-id="2346" width="200" height="200">
|
||||
<path
|
||||
d="M535.872 328.992v163.36l129.664 74.816a24 24 0 1 1-24 41.6l-129.632-74.848-129.44 74.816a24 24 0 1 1-24.032-41.568l129.44-74.816v-163.36a24 24 0 0 1 48 0z"
|
||||
fill="#333333" p-id="2347"></path>
|
||||
<path
|
||||
d="M512.8 213.376c-3.2 0-6.336 0.832-9.088 2.432l-237.696 137.344a17.984 17.984 0 0 0-9.216 15.744v274.496a17.984 17.984 0 0 0 9.216 15.744l118.72 68.672 113.056 65.216 5.92 3.456a18.176 18.176 0 0 0 18.176 0l237.728-137.344a17.952 17.952 0 0 0 9.184-15.744v-274.496a17.952 17.952 0 0 0-9.184-15.744L667.616 299.84l-26.752-15.328-118.976-68.672a18.208 18.208 0 0 0-9.088-2.432z m130.88 128.032l77.12 44.736v240l-207.936 120.16-208.064-120.16v-240l208-120.16 104.064 60.064 26.816 15.36z"
|
||||
fill="#333333" p-id="2348"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 926 B |
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2024-04-22 15:23:36
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2024-04-22 15:37:39
|
||||
* @FilePath: \general-ai-platform-web\src\pages\Node\BusinessModel\index.tsx
|
||||
* @Description: 业务模型
|
||||
* @交互说明
|
||||
*/
|
||||
const BusinessModel: React.FC = () => {
|
||||
return <div className="businessModel_page">业务模型</div>;
|
||||
};
|
||||
|
||||
export default BusinessModel;
|
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2024-04-22 15:23:36
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2024-04-22 15:34:36
|
||||
* @FilePath: \general-ai-platform-web\src\pages\Node\NodeSetting\index.tsx
|
||||
* @Description: 节点设置
|
||||
* @交互说明
|
||||
*/
|
||||
const NodeSetting: React.FC = () => {
|
||||
return <div className="nodeSetting_page">节点设置</div>;
|
||||
};
|
||||
|
||||
export default NodeSetting;
|
@ -1,100 +0,0 @@
|
||||
import { postUploadRecognition } from '@/services/realTime/involved';
|
||||
import { CloseCircleOutlined, EllipsisOutlined } from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, Image, Popover, message } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
interface ImageWithPopoverProps {
|
||||
src: string;
|
||||
reload: any;
|
||||
person_id: any;
|
||||
}
|
||||
|
||||
const ImageWithPopover: React.FC<ImageWithPopoverProps> = ({ src, person_id, reload }) => {
|
||||
const intl = useIntl();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const content = (
|
||||
<div
|
||||
style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}
|
||||
>
|
||||
{/* <div>选项1</div>
|
||||
<div>选项2</div> */}
|
||||
<Button
|
||||
type="text"
|
||||
style={{ height: 22, padding: 0, fontSize: 12, color: '#FFF' }}
|
||||
icon={<CloseCircleOutlined style={{ color: '#E80D0D', fontSize: 12 }} />}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
postUploadRecognition({
|
||||
person_id: person_id,
|
||||
classify: '0',
|
||||
})
|
||||
.then(() => {
|
||||
message.success('此人已被移除重点关注');
|
||||
reload();
|
||||
})
|
||||
.catch(() => {
|
||||
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
|
||||
});
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
移除重点关注
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
const handleOpenChange = (value: boolean) => {
|
||||
setOpen(value);
|
||||
};
|
||||
const handleButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
event.stopPropagation(); // 阻止事件冒泡到父组件并阻止默认事件触发
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ position: 'relative', boxSizing: 'border-box', width: 96, height: 96 }}>
|
||||
<Image style={{ borderRadius: 4 }} width={96} height={96} preview={false} src={src} />
|
||||
<Popover
|
||||
placement="right"
|
||||
content={content}
|
||||
trigger="click"
|
||||
style={{ width: 104, height: 32 }}
|
||||
color="rgba(0, 0, 0, 0.6)"
|
||||
overlayInnerStyle={{ width: 104, height: 32, padding: 4, borderRadius: 2 }}
|
||||
open={open}
|
||||
onOpenChange={handleOpenChange}
|
||||
>
|
||||
<Button
|
||||
style={{ position: 'absolute', bottom: 0, right: -4 }}
|
||||
type="text"
|
||||
icon={
|
||||
<EllipsisOutlined style={{ color: '#fff', fontSize: 24, transform: 'rotate(90deg)' }} />
|
||||
}
|
||||
onClick={handleButtonClick}
|
||||
/>
|
||||
</Popover>
|
||||
{/* {involved.state && (
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
right: 0,
|
||||
width: 64,
|
||||
height: 24,
|
||||
background: '#FAAD14',
|
||||
borderRadius: '0px 4px 0px 4px',
|
||||
color: '#FFF',
|
||||
fontSize: 12,
|
||||
textAlign: 'center',
|
||||
lineHeight: '24px'
|
||||
}}
|
||||
>
|
||||
重点关注
|
||||
</div>
|
||||
)} */}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageWithPopover;
|
@ -1,26 +0,0 @@
|
||||
.InvolvedImgBox {
|
||||
box-sizing: border-box;
|
||||
// display: flex;
|
||||
// justify-content: flex-start;
|
||||
padding: 16px 32px;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
.involvedImgList {
|
||||
position: relative;
|
||||
span {
|
||||
position: absolute;
|
||||
bottom: -30px;
|
||||
left: 15px;
|
||||
width: 2px;
|
||||
height: 30px;
|
||||
border-left: 2px dashed #081fa8;
|
||||
}
|
||||
}
|
||||
}
|
||||
.myButtonDisabled {
|
||||
visibility: hidden;
|
||||
}
|
||||
.involvedModalForm {
|
||||
.ant-modal .ant-modal-content {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
@ -1,318 +0,0 @@
|
||||
import { getUploadInvolvedTravelList, postUploadRecognition } from '@/services/realTime/involved';
|
||||
import { CloseCircleOutlined, EllipsisOutlined } from '@ant-design/icons';
|
||||
import { ModalForm } from '@ant-design/pro-components';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, Form, Image, List, Popover, message } from 'antd';
|
||||
import moment from 'moment';
|
||||
import VirtualList from 'rc-virtual-list';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import trajectoryBottom from '../../../../../public/images/involved/trajectoryBottom.png';
|
||||
import './InvolvedDetails.less';
|
||||
import styles from './InvolvedDetails.less';
|
||||
export type FormValueType = {
|
||||
target?: string;
|
||||
template?: string;
|
||||
type?: string;
|
||||
time?: string;
|
||||
frequency?: string;
|
||||
} & Partial<API.InvolvedDetailsParams>;
|
||||
|
||||
export type UpdateFormProps = {
|
||||
updateModalOpen: boolean;
|
||||
handleModal: () => void;
|
||||
values: Partial<API.InvolvedDetailsParams>;
|
||||
reload: any;
|
||||
};
|
||||
const InvolvedDetails: React.FC<UpdateFormProps> = (props) => {
|
||||
const intl = useIntl();
|
||||
const [form] = Form.useForm<API.InvolvedDetailsParams>();
|
||||
const [dataFlag, setDataFlag] = useState(false);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [trajectoryData, setTrajectoryData] = useState([]);
|
||||
// 动态设置每页数量
|
||||
const [currentPageSize, setCurrentPageSize] = useState<number>(10);
|
||||
const [currentPage, setCurrentPage] = useState<number>(1);
|
||||
const [total, setTotal] = useState<number>(0);
|
||||
const ContainerHeight = 630;
|
||||
const content = (
|
||||
<div
|
||||
style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}
|
||||
>
|
||||
{/* <div>选项1</div>
|
||||
<div>选项2</div> */}
|
||||
<Button
|
||||
type="text"
|
||||
style={{ height: 22, padding: 0, fontSize: 12, color: '#FFF' }}
|
||||
icon={<CloseCircleOutlined style={{ color: '#E80D0D', fontSize: 12 }} />}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
postUploadRecognition({
|
||||
person_id: props.values.person_id,
|
||||
classify: '0',
|
||||
})
|
||||
.then(() => {
|
||||
message.success('此人已被移除重点关注');
|
||||
props.reload();
|
||||
})
|
||||
.catch(() => {
|
||||
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
|
||||
});
|
||||
setOpen(false);
|
||||
props.handleModal();
|
||||
}}
|
||||
>
|
||||
移除重点关注
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
const handleOpenChange = (value: boolean) => {
|
||||
setOpen(value);
|
||||
};
|
||||
|
||||
const appendData = (page: any, pageSize: any) => {
|
||||
const reqParams = {
|
||||
page: page,
|
||||
pageSize: pageSize,
|
||||
// desc: false,
|
||||
person_id: props.values.person_id,
|
||||
// ...rest,
|
||||
};
|
||||
getUploadInvolvedTravelList(reqParams)
|
||||
.then((res) => {
|
||||
console.log(res);
|
||||
if (res.data.results) {
|
||||
setTrajectoryData(trajectoryData.concat(res.data.results));
|
||||
setTotal(res.data.count);
|
||||
if (res.data.next) {
|
||||
setDataFlag(true);
|
||||
} else {
|
||||
setDataFlag(false);
|
||||
// setTrajectoryData([]); // 重置trajectoryData数据为空数组
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// setLoading(false);
|
||||
setDataFlag(false);
|
||||
// setTrajectoryData([]); // 重置trajectoryData数据为空数组
|
||||
});
|
||||
};
|
||||
const onScroll = (e: React.UIEvent<HTMLElement, UIEvent>) => {
|
||||
// Refer to: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#problems_and_solutions
|
||||
console.log(e.currentTarget.scrollHeight - e.currentTarget.scrollTop - ContainerHeight);
|
||||
|
||||
if (Math.abs(e.currentTarget.scrollHeight - e.currentTarget.scrollTop - ContainerHeight) <= 1) {
|
||||
if (dataFlag) {
|
||||
const nextPage = currentPage + 1;
|
||||
setCurrentPage(nextPage);
|
||||
appendData(nextPage, 10);
|
||||
}
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
if (props.updateModalOpen) {
|
||||
// 调用接口获取数据
|
||||
setTrajectoryData([]); // 重置trajectoryData数据为空数组
|
||||
setCurrentPage(1);
|
||||
setCurrentPageSize(10);
|
||||
appendData(currentPage, currentPageSize);
|
||||
}
|
||||
}, [props.updateModalOpen]);
|
||||
return (
|
||||
<ModalForm<any>
|
||||
width={615}
|
||||
title={
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
padding: '24px 32px 0px',
|
||||
justifyContent: 'flex-start',
|
||||
}}
|
||||
>
|
||||
<div style={{ position: 'relative', boxSizing: 'border-box', width: 120, height: 120 }}>
|
||||
<Image
|
||||
style={{ borderRadius: 4 }}
|
||||
width={120}
|
||||
height={120}
|
||||
preview={false}
|
||||
src={props?.values?.picture_path}
|
||||
/>
|
||||
<Popover
|
||||
placement="right"
|
||||
content={content}
|
||||
trigger="click"
|
||||
style={{ width: 104, height: 32 }}
|
||||
color="rgba(0, 0, 0, 0.6)"
|
||||
overlayInnerStyle={{ width: 104, height: 32, padding: 4, borderRadius: 2 }}
|
||||
open={open}
|
||||
onOpenChange={handleOpenChange}
|
||||
>
|
||||
<Button
|
||||
style={{ position: 'absolute', bottom: 0, right: -4 }}
|
||||
type="text"
|
||||
icon={
|
||||
<EllipsisOutlined
|
||||
style={{ color: '#fff', fontSize: 24, transform: 'rotate(90deg)' }}
|
||||
/>
|
||||
}
|
||||
// onClick={handleButtonClick}
|
||||
/>
|
||||
</Popover>
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
right: 0,
|
||||
width: 64,
|
||||
height: 24,
|
||||
background: '#FAAD14',
|
||||
borderRadius: '0px 4px 0px 4px',
|
||||
color: '#FFF',
|
||||
fontSize: 12,
|
||||
textAlign: 'center',
|
||||
lineHeight: '24px',
|
||||
fontWeight: 400,
|
||||
}}
|
||||
>
|
||||
重点关注
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
marginLeft: 12,
|
||||
height: 98,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'flex-start',
|
||||
color: '#666',
|
||||
fontSize: 14,
|
||||
fontWeight: 400,
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
关注时间:{' '}
|
||||
<span
|
||||
style={{
|
||||
color: '#333',
|
||||
}}
|
||||
>
|
||||
{moment(props?.values?.classify_time).format('YYYY-MM-DD hh:mm:ss')}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
最近发现:{' '}
|
||||
<span
|
||||
style={{
|
||||
color: '#333',
|
||||
}}
|
||||
>
|
||||
{moment(props?.values?.appear_time).format('YYYY-MM-DD hh:mm:ss')}
|
||||
</span>
|
||||
</div>
|
||||
{/* <div>
|
||||
来源设备:{' '}
|
||||
<span
|
||||
style={{
|
||||
color: '#333',
|
||||
}}
|
||||
>
|
||||
{props?.values?.device_name}
|
||||
</span>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
open={props.updateModalOpen}
|
||||
form={form}
|
||||
autoFocusFirstInput
|
||||
modalProps={{
|
||||
destroyOnClose: true,
|
||||
onCancel: () => {
|
||||
setTrajectoryData([]);
|
||||
setCurrentPage(1);
|
||||
setCurrentPageSize(10);
|
||||
props.handleModal();
|
||||
},
|
||||
wrapClassName: 'involvedModalForm',
|
||||
}}
|
||||
submitter={false}
|
||||
submitTimeout={2000}
|
||||
onFinish={async (values) => {
|
||||
values.is_ignore = true;
|
||||
values.person_id = props.values.person_id;
|
||||
// console.log(values);
|
||||
// postIgnoringvents(values)
|
||||
// .then(() => {
|
||||
// message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '成功' }));
|
||||
// props.reload();
|
||||
// })
|
||||
// .catch(() => {
|
||||
// message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
|
||||
// });
|
||||
setTrajectoryData([]);
|
||||
setCurrentPage(1);
|
||||
setCurrentPageSize(10);
|
||||
props.handleModal();
|
||||
return true;
|
||||
}}
|
||||
>
|
||||
{/* <ProForm.Group> */}
|
||||
{/* <div className={styles.alarmDetails}>
|
||||
告警名称: <span className={styles.alarmSpan}>单人徘徊告警</span>来源设备: <span className={styles.alarmSpan}>北广场检票口1#摄像头</span>触发时间: <span className={styles.alarmSpan}>2023-01-15 22:00:03</span>
|
||||
</div> */}
|
||||
<div className={styles.InvolvedImgBox}>
|
||||
<List>
|
||||
<VirtualList
|
||||
data={trajectoryData}
|
||||
height={ContainerHeight}
|
||||
itemHeight={64}
|
||||
itemKey="id"
|
||||
onScroll={onScroll}
|
||||
>
|
||||
{(item: any, index: any) => (
|
||||
<div key={item.person_id + index}>
|
||||
<List.Item style={{ borderBottom: 0, height: 64, padding: 0 }}>
|
||||
<List.Item.Meta
|
||||
avatar={
|
||||
<div className={styles.involvedImgList}>
|
||||
<img style={{ width: 32, height: 32 }} src={trajectoryBottom} />
|
||||
{index + 1 !== total && <span />}
|
||||
</div>
|
||||
}
|
||||
title={
|
||||
<div style={{ lineHeight: '30px', color: '#666' }}>
|
||||
时间定位:{' '}
|
||||
<span style={{ color: '#333', marginRight: 16 }}>
|
||||
{moment(item.create_time).format('YYYY-MM-DD hh:mm:ss')}
|
||||
</span>{' '}
|
||||
来源视频: <span style={{ color: '#333' }}>{item.video_name}</span>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
<div>
|
||||
<Image
|
||||
style={{ borderRadius: 4 }}
|
||||
width={48}
|
||||
height={48}
|
||||
preview={{
|
||||
mask: '',
|
||||
}}
|
||||
src={item.picture_path}
|
||||
/>
|
||||
</div>
|
||||
</List.Item>
|
||||
{index === total - 1 && (
|
||||
<div style={{ textAlign: 'center', color: '#999' }}>已无更多数据~</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</VirtualList>
|
||||
</List>
|
||||
</div>
|
||||
|
||||
{/* </ProForm.Group> */}
|
||||
</ModalForm>
|
||||
);
|
||||
};
|
||||
export default InvolvedDetails;
|
@ -1,85 +0,0 @@
|
||||
.alarmImgBox {
|
||||
// display: flex;
|
||||
// justify-content: flex-start;
|
||||
.alarmImgLeft {
|
||||
position: relative;
|
||||
width: 120px;
|
||||
margin-right: 32px;
|
||||
// height: 600px;
|
||||
.alarmImgLeftBox {
|
||||
width: 112px;
|
||||
height: 112px;
|
||||
border-radius: 4px;
|
||||
// background: skyblue;
|
||||
}
|
||||
.alarmImgLeftBoxActive {
|
||||
width: 112px;
|
||||
height: 112px;
|
||||
border: 1.5px solid #081fa8;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.shadowBox {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
left: 0;
|
||||
z-index: 999;
|
||||
width: 112px;
|
||||
height: 20px;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
.alarmImgRight {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
.alarmImgRightTopBox {
|
||||
width: 640px;
|
||||
height: 640px;
|
||||
background: skyblue;
|
||||
}
|
||||
.alarmDetails {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 38px;
|
||||
margin-bottom: 16px;
|
||||
padding-left: 24px;
|
||||
color: #ffffff;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
font-family: PingFang SC;
|
||||
line-height: 38px;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
.alarmSpan {
|
||||
// color: #333;
|
||||
margin-right: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.alarmImgDescribe {
|
||||
margin-bottom: 12px;
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
font-family: PingFang SC;
|
||||
span {
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
.alarmImgContent {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
box-sizing: border-box;
|
||||
width: 784px;
|
||||
margin-bottom: 24px;
|
||||
padding: 16px 0 16px 16px;
|
||||
// height: 172px;
|
||||
background: #f7f7f7;
|
||||
border: 1px dashed #dcdcdc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
.myButtonDisabled {
|
||||
visibility: hidden;
|
||||
}
|
@ -1,297 +0,0 @@
|
||||
import { postUploadIgnoringvents } from '@/services/realTime/alarmlist';
|
||||
import { postUploadRecognition } from '@/services/realTime/involved';
|
||||
import { ModalForm } from '@ant-design/pro-components';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, Form, message } from 'antd';
|
||||
import moment from 'moment';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import styles from './AlarmDetails.less';
|
||||
import ImageSinglePopover from './ImageSinglePopover';
|
||||
import ImageWithPopover from './ImageWithPopover';
|
||||
export type FormValueType = {
|
||||
target?: string;
|
||||
template?: string;
|
||||
type?: string;
|
||||
time?: string;
|
||||
frequency?: string;
|
||||
} & Partial<API.AlarmDetailsParams>;
|
||||
|
||||
export type UpdateFormProps = {
|
||||
updateModalOpen: boolean;
|
||||
handleModal: () => void;
|
||||
values: Partial<API.AlarmDetailsParams>;
|
||||
reload: any;
|
||||
warning_type: any;
|
||||
};
|
||||
const UpdateForm: React.FC<UpdateFormProps> = (props) => {
|
||||
const intl = useIntl();
|
||||
const [form] = Form.useForm<API.AlarmDetailsParams>();
|
||||
// const [isActive, setIsActive] = useState(0);
|
||||
// const [visible, setVisible] = useState(false);
|
||||
const [involved, setInvolved] = useState(0);
|
||||
// const [involvedInfo, setInvolvedInfo] = useState([...(props?.values?.person_list || [])]);
|
||||
const [involvedInfo, setInvolvedInfo] = useState<any[]>([]);
|
||||
// useEffect(() => {
|
||||
// if (props.values?.person_list) {
|
||||
// setInvolvedInfo([...props.values.person_list]);
|
||||
// }
|
||||
// }, [props.values?.person_list]);
|
||||
// console.log(object);
|
||||
// if(props.warning_type === '1') {
|
||||
// console.log('props.values?.warning_type1');
|
||||
// setInvolved(props.values.person_list[0][2]);
|
||||
// }else {
|
||||
// console.log('props.values?.warning_type2');
|
||||
// // setInvolvedInfo([...props.values.person_list]);
|
||||
// }
|
||||
const handlePostRecognition = (person_id: any, classify: any) => {
|
||||
postUploadRecognition({
|
||||
person_id: person_id,
|
||||
classify: classify,
|
||||
})
|
||||
.then((res) => {
|
||||
console.log(res.data.classify, 'res.data.classify');
|
||||
if (res.data.classify === 1) {
|
||||
message.success('此人已被设为重点关注');
|
||||
} else {
|
||||
message.success('此人已被移除重点关注');
|
||||
}
|
||||
props.reload();
|
||||
})
|
||||
.catch(() => {
|
||||
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
|
||||
});
|
||||
};
|
||||
/** 多人告警组件 */
|
||||
const handleInvolved = (value: any, index: any) => {
|
||||
const updatedInvolvedInfo = [...involvedInfo];
|
||||
console.log(updatedInvolvedInfo);
|
||||
updatedInvolvedInfo[index][2] = value;
|
||||
setInvolvedInfo(updatedInvolvedInfo);
|
||||
handlePostRecognition(updatedInvolvedInfo[index][0], value);
|
||||
};
|
||||
/** 单人告警组件 */
|
||||
// const handleSingleInvolved = () => {
|
||||
// if (involved === 1) {
|
||||
// setInvolved(0);
|
||||
// handlePostRecognition(props.values?.person_id, 0)
|
||||
// } else {
|
||||
// setInvolved(1);
|
||||
// handlePostRecognition(props.values?.person_id, 1)
|
||||
// }
|
||||
// }
|
||||
|
||||
// const [open, setOpen] = useState(false);
|
||||
useEffect(() => {
|
||||
// console.log(Array.isArray(props.values?.person_id),'Array.isArray(props.values?.person_id)');
|
||||
if (props.updateModalOpen) {
|
||||
if (props.warning_type === '1') {
|
||||
console.log('props.values?.warning_type1');
|
||||
setInvolved(props.values.person_list[0][2]);
|
||||
} else {
|
||||
console.log('props.values?.warning_type2');
|
||||
setInvolvedInfo([...props.values.person_list]);
|
||||
}
|
||||
}
|
||||
}, [props.updateModalOpen]);
|
||||
return (
|
||||
<ModalForm<any>
|
||||
width={832}
|
||||
title={`${props.values.warning_name}告警`}
|
||||
open={props.updateModalOpen}
|
||||
form={form}
|
||||
autoFocusFirstInput
|
||||
modalProps={{
|
||||
destroyOnClose: true,
|
||||
onCancel: () => {
|
||||
setInvolved(0);
|
||||
props.handleModal();
|
||||
},
|
||||
okText: intl.formatMessage({ id: 'common.yes', defaultMessage: '确认' }),
|
||||
cancelText: intl.formatMessage({ id: 'common.no', defaultMessage: '取消' }),
|
||||
}}
|
||||
submitter={{
|
||||
// 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}
|
||||
onFinish={async (values) => {
|
||||
values.is_ignore = true;
|
||||
values.id = props.values.id;
|
||||
// console.log(props.values);
|
||||
postUploadIgnoringvents(values)
|
||||
.then(() => {
|
||||
message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '成功' }));
|
||||
props.reload();
|
||||
})
|
||||
.catch(() => {
|
||||
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
|
||||
});
|
||||
|
||||
props.handleModal();
|
||||
return true;
|
||||
}}
|
||||
>
|
||||
{/* <ProForm.Group> */}
|
||||
<div className={styles.alarmImgBox}>
|
||||
<div className={styles.alarmImgDescribe}>
|
||||
来源: <span>{props.values.origin}</span>
|
||||
</div>
|
||||
<div className={styles.alarmImgDescribe}>
|
||||
触发时间:{' '}
|
||||
<span className={styles.alarmSpan}>
|
||||
{moment(props.values.trigger_time).format('YYYY-MM-DD hh:mm:ss')}
|
||||
</span>
|
||||
</div>
|
||||
<div className={styles.alarmImgContent}>
|
||||
{Array.isArray(props.values?.person_id_list)}
|
||||
{props.warning_type === '2'
|
||||
? Array.isArray(involvedInfo) && involvedInfo.length
|
||||
? involvedInfo.map((item: any, index: any) => {
|
||||
return (
|
||||
<ImageWithPopover
|
||||
src={item?.[1]}
|
||||
involved={involvedInfo[index][2]}
|
||||
key={index}
|
||||
indexId={index}
|
||||
handleInvolved={handleInvolved}
|
||||
time={props.values.trigger_time}
|
||||
></ImageWithPopover>
|
||||
);
|
||||
})
|
||||
: Array.isArray(props?.values?.picture_path) && props?.values?.picture_path.length
|
||||
? props.values.picture_path.map((item: any, index: any) => {
|
||||
return (
|
||||
<ImageSinglePopover
|
||||
src={item}
|
||||
involved={involved}
|
||||
key={index}
|
||||
// handleInvolved={handleSingleInvolved}
|
||||
reload={props.reload} // 将reload方法作为prop传递给ImageSinglePopover组件
|
||||
time={props.values.trigger_time}
|
||||
></ImageSinglePopover>
|
||||
);
|
||||
})
|
||||
: null
|
||||
: Array.isArray(props?.values?.picture_path) && props?.values?.picture_path.length
|
||||
? props.values.picture_path.map((item: any, index: any) => {
|
||||
return (
|
||||
<ImageSinglePopover
|
||||
src={item}
|
||||
involved={involved}
|
||||
key={index}
|
||||
// handleInvolved={handleSingleInvolved}
|
||||
reload={props.reload} // 将reload方法作为prop传递给ImageSinglePopover组件
|
||||
time={props.values.trigger_time}
|
||||
></ImageSinglePopover>
|
||||
);
|
||||
})
|
||||
: null}
|
||||
{/* { Array.isArray(involvedInfo) && involvedInfo.length && involvedInfo.map((item: any, index: any) => {
|
||||
console.log(involvedInfo,'item');
|
||||
return(<ImageWithPopover src={item?.[1]} involved={involvedInfo[index][2]} key={index} indexId={index} handleInvolved={handleInvolved}></ImageWithPopover>)
|
||||
})} */}
|
||||
</div>
|
||||
{/* <div className={styles.alarmImgLeft}>
|
||||
<Swiper
|
||||
style={{height:660}}
|
||||
slidesPerView={5}
|
||||
spaceBetween={20}
|
||||
direction='vertical'
|
||||
mousewheel={true}
|
||||
modules={[Mousewheel]}
|
||||
onSlideChange={() => {
|
||||
console.log(111);
|
||||
}}
|
||||
// pagination={{
|
||||
// clickable: true,
|
||||
// }}
|
||||
// modules={[Pagination]}
|
||||
>
|
||||
{ Array.isArray(props?.values?.picture_path) && props?.values?.picture_path.length && props?.values?.picture_path.map((item: any, index: any) => {
|
||||
return (<SwiperSlide key={index} virtualIndex={index} onClick={() => {
|
||||
console.log(index);
|
||||
setIsActive(index)
|
||||
setImageSrc(item)
|
||||
}}>
|
||||
<div className={ styles.alarmImgLeftBox }>
|
||||
<Image
|
||||
style={{
|
||||
width: 112,
|
||||
height: 112,
|
||||
borderRadius: 4
|
||||
}}
|
||||
className={ index === isActive ? styles.alarmImgLeftBoxActive : '' }
|
||||
preview={false}
|
||||
src={item}
|
||||
/>
|
||||
</div>
|
||||
</SwiperSlide>)
|
||||
})}
|
||||
</Swiper>
|
||||
<div className={styles.shadowBox}></div>
|
||||
</div>
|
||||
<div className={styles.alarmImgRight}>
|
||||
<div className={styles.alarmImgRightTopBox}>
|
||||
<Image
|
||||
width={640}
|
||||
height={640}
|
||||
preview={false}
|
||||
src={imageSrc}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.alarmDetails}>
|
||||
来源: <span className={styles.alarmSpan}>{props.values.device_name}</span>触发时间: <span className={styles.alarmSpan}>{moment(props.values.trigger_time).format('YYYY-MM-DD hh:mm:ss')}</span>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
{/* </ProForm.Group> */}
|
||||
</ModalForm>
|
||||
);
|
||||
};
|
||||
export default UpdateForm;
|
@ -1,146 +0,0 @@
|
||||
import { EyeOutlined } from '@ant-design/icons';
|
||||
import { Image } from 'antd';
|
||||
import moment from 'moment';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
interface ImageSinglePopoverProps {
|
||||
src: string;
|
||||
involved: any;
|
||||
// handleInvolved: () => void;
|
||||
reload: any;
|
||||
time: any;
|
||||
}
|
||||
|
||||
const ImageSinglePopover: React.FC<ImageSinglePopoverProps> = ({ src, involved, time }) => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
// const [open, setOpen] = useState(false);
|
||||
// 定义一个方法,用于生成自定义的遮罩层
|
||||
const generateMask = (text: any) => (
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
color: '#fff',
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', fontSize: 12 }}>
|
||||
<EyeOutlined style={{ marginRight: 8, fontSize: 12 }} />
|
||||
<div>{text}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
// const content = (
|
||||
// <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center',alignItems: 'center', height: 56}}>
|
||||
// {/* <div>选项1</div>
|
||||
// <div>选项2</div> */}
|
||||
// <Button
|
||||
// type="text"
|
||||
// style={{ height:22, padding: 0,fontSize: 12,color: '#FFF' }}
|
||||
// icon={<InfoCircleOutlined style={{ color: '#FAAD14',fontSize: 12}} />}
|
||||
// onClick={()=>{
|
||||
// // setInvolved(true)
|
||||
// // handleInvolved();
|
||||
// // reload()
|
||||
// setOpen(false)
|
||||
// }}
|
||||
// >加入重点关注</Button>
|
||||
// <Button
|
||||
// type="text"
|
||||
// style={{ height:22, padding: 0,fontSize: 12,color: '#FFF' }}
|
||||
// icon={<CloseCircleOutlined style={{ color: '#E80D0D',fontSize: 12}} />}
|
||||
// onClick={()=>{
|
||||
// // setInvolved(false)
|
||||
// // handleInvolved();
|
||||
// // reload()
|
||||
// setOpen(false)
|
||||
// }}
|
||||
// >移除重点关注</Button>
|
||||
// </div>
|
||||
// );
|
||||
const handleVisibleChange = (value: boolean) => {
|
||||
setVisible(value);
|
||||
};
|
||||
|
||||
// const handleOpenChange = (value: boolean) => {
|
||||
// setOpen(value);
|
||||
// };
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
boxSizing: 'border-box',
|
||||
width: 140,
|
||||
height: 170,
|
||||
marginRight: 12,
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
style={{ borderRadius: 4 }}
|
||||
width={140}
|
||||
height={140}
|
||||
preview={{
|
||||
visible,
|
||||
src,
|
||||
onVisibleChange: handleVisibleChange,
|
||||
mask: generateMask('点击可预览大图'),
|
||||
}}
|
||||
src={src}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
height: 30,
|
||||
textAlign: 'center',
|
||||
lineHeight: '30px',
|
||||
fontWeight: 500,
|
||||
color: '#333',
|
||||
}}
|
||||
>
|
||||
{moment(time).format('YYYY-MM-DD hh:mm:ss')}
|
||||
</div>
|
||||
{/* <Popover
|
||||
placement="right"
|
||||
content={content}
|
||||
trigger="click"
|
||||
style={{ width: 104, height: 64 }}
|
||||
color="rgba(0, 0, 0, 0.6)"
|
||||
overlayInnerStyle={{ width: 104, height: 64, padding: 4, borderRadius: 2 }}
|
||||
open={open}
|
||||
onOpenChange={handleOpenChange}
|
||||
>
|
||||
<Button
|
||||
style={{ position: 'absolute', bottom: 8, right: 0 }}
|
||||
type="text"
|
||||
icon={<EllipsisOutlined style={{ color: '#fff', fontSize: 24, transform: 'rotate(90deg)' }} />}
|
||||
/>
|
||||
</Popover> */}
|
||||
{involved === 1 && (
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
right: 0,
|
||||
width: 64,
|
||||
height: 24,
|
||||
background: '#FAAD14',
|
||||
borderRadius: '0px 4px 0px 4px',
|
||||
color: '#FFF',
|
||||
fontSize: 12,
|
||||
textAlign: 'center',
|
||||
lineHeight: '24px',
|
||||
}}
|
||||
>
|
||||
重点关注
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageSinglePopover;
|
@ -1,170 +0,0 @@
|
||||
import {
|
||||
CloseCircleOutlined,
|
||||
EllipsisOutlined,
|
||||
EyeOutlined,
|
||||
InfoCircleOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { Button, Image, Popover } from 'antd';
|
||||
import moment from 'moment';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
interface ImageWithPopoverProps {
|
||||
src: string;
|
||||
involved: any;
|
||||
indexId: any;
|
||||
handleInvolved: (value: any, index: any) => void;
|
||||
time: any;
|
||||
}
|
||||
|
||||
const ImageWithPopover: React.FC<ImageWithPopoverProps> = ({
|
||||
src,
|
||||
involved,
|
||||
indexId,
|
||||
handleInvolved,
|
||||
time,
|
||||
}) => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
// 定义一个方法,用于生成自定义的遮罩层
|
||||
const generateMask = (text: any) => (
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
color: '#fff',
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', fontSize: 12 }}>
|
||||
<EyeOutlined style={{ marginRight: 8, fontSize: 12 }} />
|
||||
<div>{text}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
const content = (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
height: 56,
|
||||
}}
|
||||
>
|
||||
{/* <div>选项1</div>
|
||||
<div>选项2</div> */}
|
||||
<Button
|
||||
type="text"
|
||||
style={{ height: 22, padding: 0, fontSize: 12, color: '#FFF', marginBottom: 4 }}
|
||||
icon={<InfoCircleOutlined style={{ color: '#FAAD14', fontSize: 12 }} />}
|
||||
onClick={() => {
|
||||
// setInvolved(true)
|
||||
handleInvolved(1, indexId);
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
加入重点关注
|
||||
</Button>
|
||||
<Button
|
||||
type="text"
|
||||
style={{ height: 22, padding: 0, fontSize: 12, color: '#FFF' }}
|
||||
icon={<CloseCircleOutlined style={{ color: '#E80D0D', fontSize: 12 }} />}
|
||||
onClick={() => {
|
||||
// setInvolved(false)
|
||||
handleInvolved(0, indexId);
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
移除重点关注
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
const handleVisibleChange = (value: boolean) => {
|
||||
setVisible(value);
|
||||
};
|
||||
|
||||
const handleOpenChange = (value: boolean) => {
|
||||
setOpen(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
boxSizing: 'border-box',
|
||||
width: 140,
|
||||
height: 170,
|
||||
marginRight: 12,
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
style={{ borderRadius: 4 }}
|
||||
width={140}
|
||||
height={140}
|
||||
preview={{
|
||||
visible,
|
||||
src,
|
||||
onVisibleChange: handleVisibleChange,
|
||||
mask: generateMask('点击可预览大图'),
|
||||
}}
|
||||
src={src}
|
||||
/>
|
||||
<Popover
|
||||
placement="right"
|
||||
content={content}
|
||||
trigger="click"
|
||||
style={{ width: 104, height: 64 }}
|
||||
color="rgba(0, 0, 0, 0.6)"
|
||||
overlayInnerStyle={{ width: 104, height: 68, padding: 4, borderRadius: 2 }}
|
||||
open={open}
|
||||
onOpenChange={handleOpenChange}
|
||||
>
|
||||
<Button
|
||||
style={{ position: 'absolute', bottom: 30, right: 0 }}
|
||||
type="text"
|
||||
icon={
|
||||
<EllipsisOutlined style={{ color: '#fff', fontSize: 24, transform: 'rotate(90deg)' }} />
|
||||
}
|
||||
/>
|
||||
</Popover>
|
||||
<div
|
||||
style={{
|
||||
height: 30,
|
||||
textAlign: 'center',
|
||||
lineHeight: '30px',
|
||||
fontWeight: 500,
|
||||
color: '#333',
|
||||
}}
|
||||
>
|
||||
{moment(time).format('YYYY-MM-DD hh:mm:ss')}
|
||||
</div>
|
||||
{involved === 1 && (
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
right: 0,
|
||||
width: 64,
|
||||
height: 24,
|
||||
background: '#FAAD14',
|
||||
borderRadius: '0px 4px 0px 4px',
|
||||
color: '#FFF',
|
||||
fontSize: 12,
|
||||
textAlign: 'center',
|
||||
lineHeight: '24px',
|
||||
}}
|
||||
>
|
||||
重点关注
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageWithPopover;
|
@ -1,7 +0,0 @@
|
||||
:global {
|
||||
.ant-form-item-control-input-content {
|
||||
.ant-space-gap-col-small {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,212 +0,0 @@
|
||||
import TableActionCard from '@/components/TableActionCard';
|
||||
import { getOfflineAlarmRules } from '@/services/realTime/alarmRules';
|
||||
import { EditOutlined } from '@ant-design/icons';
|
||||
import type { ActionType, ProColumns } from '@ant-design/pro-components';
|
||||
import { PageContainer, ProTable } from '@ant-design/pro-components';
|
||||
import { FormattedMessage } from '@umijs/max';
|
||||
import { Button, Tag } from 'antd';
|
||||
import React, { useRef, useState } from 'react';
|
||||
import { proTablePaginationOptions } from '../../../../config/defaultTable';
|
||||
import UpdateForm from './components/UpdateForm';
|
||||
import UpdateMultiForm from './components/UpdateMultiForm';
|
||||
import UpdateTimeForm from './components/UpdateTimeForm';
|
||||
const OfflineAlarmRules: React.FC = () => {
|
||||
/**
|
||||
* @en-US International configuration
|
||||
* @zh-CN 国际化配置
|
||||
* */
|
||||
const actionRef = useRef<ActionType>();
|
||||
// 动态设置每页数量
|
||||
const [currentPageSize, setCurrentPageSize] = useState<number>(10);
|
||||
|
||||
const [currentRow, setCurrentRow] = useState<API.DeviceCategory>();
|
||||
// 编辑弹框
|
||||
const [updateModalOpen, setUpdateModalOpen] = useState<boolean>(false);
|
||||
const [updateMultiModalOpen, setUpdateMultiModalOpen] = useState<boolean>(false);
|
||||
const [updateTimeModalOpen, setUpdateTimeModalOpen] = useState<boolean>(false);
|
||||
|
||||
const handleUpdateModal = () => {
|
||||
if (updateModalOpen) {
|
||||
setUpdateModalOpen(false);
|
||||
setCurrentRow(undefined);
|
||||
} else {
|
||||
setUpdateModalOpen(true);
|
||||
}
|
||||
};
|
||||
const handleUpdateMultiModal = () => {
|
||||
if (updateMultiModalOpen) {
|
||||
setUpdateMultiModalOpen(false);
|
||||
setCurrentRow(undefined);
|
||||
} else {
|
||||
setUpdateMultiModalOpen(true);
|
||||
}
|
||||
};
|
||||
const handleUpdateTimeModal = () => {
|
||||
setCurrentRow(undefined);
|
||||
|
||||
if (updateTimeModalOpen) {
|
||||
setUpdateTimeModalOpen(false);
|
||||
} else {
|
||||
setUpdateTimeModalOpen(true);
|
||||
}
|
||||
};
|
||||
|
||||
const columns: ProColumns<API.DeviceCategory>[] = [
|
||||
{
|
||||
title: <FormattedMessage id="alarm_rules.page.name" defaultMessage="告警规则" />,
|
||||
dataIndex: 'warning_name',
|
||||
hideInSearch: true,
|
||||
},
|
||||
|
||||
{
|
||||
title: <FormattedMessage id="alarm_rules.page.id" defaultMessage="规则ID" />,
|
||||
dataIndex: 'id',
|
||||
hideInSearch: true,
|
||||
},
|
||||
{
|
||||
title: <FormattedMessage id="alarm_rules.page.status" defaultMessage="规则状态" />,
|
||||
dataIndex: 'is_use',
|
||||
hideInSearch: true,
|
||||
render: (dom) => {
|
||||
return (
|
||||
<Tag
|
||||
bordered={false}
|
||||
color={dom === 1 ? 'success' : ''}
|
||||
style={{
|
||||
// fontSize:14,
|
||||
color: dom === 1 ? '#52C41A' : '#999',
|
||||
}}
|
||||
>
|
||||
{dom === 1 ? '已启用' : '未启用'}
|
||||
</Tag>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: <FormattedMessage id="alarm_rules.page.updateTime" defaultMessage="修改时间" />,
|
||||
dataIndex: 'update_time',
|
||||
sorter: true,
|
||||
hideInSearch: true,
|
||||
valueType: 'dateTime',
|
||||
},
|
||||
|
||||
{
|
||||
title: <FormattedMessage id="pages.searchTable.titleOption" defaultMessage="操作" />,
|
||||
dataIndex: 'option',
|
||||
valueType: 'option',
|
||||
fixed: 'right',
|
||||
render: (_, record) => [
|
||||
<TableActionCard
|
||||
key="TableActionCardRef"
|
||||
renderActions={[
|
||||
{
|
||||
key: 'update',
|
||||
renderDom: (
|
||||
<Button
|
||||
key="update"
|
||||
type="link"
|
||||
size="small"
|
||||
style={{
|
||||
color: '#081FA8',
|
||||
}}
|
||||
icon={
|
||||
<EditOutlined
|
||||
style={{
|
||||
marginRight: 3,
|
||||
}}
|
||||
/>
|
||||
}
|
||||
onClick={() => {
|
||||
console.log(record);
|
||||
if (record.id === 1) {
|
||||
setUpdateModalOpen(true);
|
||||
} else if (record.id === 2) {
|
||||
setUpdateMultiModalOpen(true);
|
||||
} else {
|
||||
setUpdateTimeModalOpen(true);
|
||||
}
|
||||
setCurrentRow(record);
|
||||
}}
|
||||
>
|
||||
<FormattedMessage id="common.edit" defaultMessage="编辑" />
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
]}
|
||||
></TableActionCard>,
|
||||
],
|
||||
},
|
||||
];
|
||||
return (
|
||||
<PageContainer>
|
||||
<ProTable<API.DeviceCategory>
|
||||
cardProps={{
|
||||
bodyStyle: {
|
||||
padding: 20,
|
||||
},
|
||||
}}
|
||||
options={{ fullScreen: false, setting: false, density: false, reload: false }}
|
||||
actionRef={actionRef}
|
||||
rowKey="key"
|
||||
search={false}
|
||||
showSorterTooltip={false}
|
||||
pagination={{
|
||||
...proTablePaginationOptions,
|
||||
pageSize: currentPageSize,
|
||||
onChange: (page, pageSize) => setCurrentPageSize(pageSize),
|
||||
}}
|
||||
columnsState={{
|
||||
persistenceKey: 'device_category_list',
|
||||
persistenceType: 'localStorage',
|
||||
}}
|
||||
request={async (params = {}, sort) => {
|
||||
const { current, ...rest } = params;
|
||||
const reqParams = {
|
||||
page: current,
|
||||
desc: false,
|
||||
orderKey: '',
|
||||
...rest,
|
||||
};
|
||||
if (sort && Object.keys(sort).length) {
|
||||
reqParams.orderKey = Object.keys(sort)[0];
|
||||
let sort_select = sort[reqParams.orderKey];
|
||||
reqParams.desc = sort_select === 'descend';
|
||||
}
|
||||
// let resp = await postDeviceCategoryGetDeviceCategoryList({ ...reqParams });
|
||||
let resp = await getOfflineAlarmRules(reqParams);
|
||||
console.log(resp);
|
||||
return {
|
||||
data: resp.data.results.map((v: API.DeviceCategory) => {
|
||||
return { ...v, key: v.id };
|
||||
}),
|
||||
success: resp.success,
|
||||
total: resp.data.count,
|
||||
current: resp.data.page,
|
||||
pageSize: resp.data.pageSize,
|
||||
};
|
||||
}}
|
||||
columns={columns}
|
||||
/>
|
||||
<UpdateForm
|
||||
updateModalOpen={updateModalOpen}
|
||||
values={currentRow || {}}
|
||||
handleModal={handleUpdateModal}
|
||||
reload={actionRef.current?.reload}
|
||||
/>
|
||||
<UpdateMultiForm
|
||||
updateModalOpen={updateMultiModalOpen}
|
||||
values={currentRow || {}}
|
||||
handleModal={handleUpdateMultiModal}
|
||||
reload={actionRef.current?.reload}
|
||||
/>
|
||||
<UpdateTimeForm
|
||||
updateModalOpen={updateTimeModalOpen}
|
||||
values={currentRow || {}}
|
||||
handleModal={handleUpdateTimeModal}
|
||||
reload={actionRef.current?.reload}
|
||||
/>
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default OfflineAlarmRules;
|
@ -1,60 +0,0 @@
|
||||
import { postTestDevice } from '@/services/realTime/interfaces';
|
||||
import { RedoOutlined } from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, Tag, message } from 'antd';
|
||||
import moment from 'moment';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
interface ImageSinglePopoverProps {
|
||||
values: any;
|
||||
reload: any;
|
||||
}
|
||||
|
||||
const CaptureButton: React.FC<ImageSinglePopoverProps> = (props) => {
|
||||
const intl = useIntl();
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const connection = () => {
|
||||
setLoading(true);
|
||||
postTestDevice({
|
||||
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 (
|
||||
<div>
|
||||
<Tag
|
||||
bordered={false}
|
||||
color={props.values.test_result === 1 ? 'success' : ''}
|
||||
style={{
|
||||
// fontSize:14,
|
||||
color: props.values.test_result === 1 ? '#52C41A' : '#999',
|
||||
}}
|
||||
>
|
||||
{props.values.test_result === 1 ? '在线' : '离线'}
|
||||
</Tag>
|
||||
<span>{moment(props.values.test_time).format('YYYY-MM-DD hh:mm:ss')}</span>
|
||||
<Button
|
||||
type="link"
|
||||
icon={<RedoOutlined />}
|
||||
loading={loading}
|
||||
onClick={() => {
|
||||
connection();
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CaptureButton;
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2024-04-02 17:41:57
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2024-04-02 17:46:32
|
||||
* @FilePath: \uighur-recognition-web2\src\pages\Offline\OfflineDeviceList\components\CaptureForm.tsx
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
import { postInterfaces } from '@/services/realTime/interfaces';
|
||||
import { ModalForm } from '@ant-design/pro-components';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Form, Image, message } from 'antd';
|
||||
import moment from 'moment';
|
||||
import React from 'react';
|
||||
import { proFormSmallModelWidth } from '../../../../../config/defaultForm';
|
||||
export type FormValueType = {
|
||||
target?: string;
|
||||
template?: string;
|
||||
type?: string;
|
||||
time?: string;
|
||||
frequency?: string;
|
||||
} & Partial<API.UpdateInterfacesParams>;
|
||||
|
||||
export type UpdateFormProps = {
|
||||
captureModalOpen: boolean;
|
||||
handleModal: () => void;
|
||||
values: Partial<API.UpdateInterfacesParams>;
|
||||
reload: any;
|
||||
};
|
||||
const CaptureForm: React.FC<UpdateFormProps> = (props) => {
|
||||
const intl = useIntl();
|
||||
const [form] = Form.useForm<API.UpdateInterfacesParams>();
|
||||
|
||||
return (
|
||||
<ModalForm<any>
|
||||
width={proFormSmallModelWidth}
|
||||
title={intl.formatMessage({
|
||||
id: 'device.interface_manage.table.list.capture',
|
||||
defaultMessage: `最近拍摄`,
|
||||
})}
|
||||
open={props.captureModalOpen}
|
||||
form={form}
|
||||
autoFocusFirstInput
|
||||
modalProps={{
|
||||
destroyOnClose: true,
|
||||
onCancel: () => {
|
||||
props.handleModal();
|
||||
},
|
||||
// okText: intl.formatMessage({ id: 'common.okText', defaultMessage: '确认' }),
|
||||
// cancelText: intl.formatMessage({ id: 'common.cancelText', defaultMessage: '取消' }),
|
||||
}}
|
||||
submitTimeout={2000}
|
||||
submitter={false}
|
||||
onFinish={async (values) => {
|
||||
console.log(values);
|
||||
values.id = props.values.id;
|
||||
postInterfaces(values)
|
||||
.then(() => {
|
||||
message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '成功' }));
|
||||
props.reload();
|
||||
})
|
||||
.catch(() => {
|
||||
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
|
||||
});
|
||||
|
||||
props.handleModal();
|
||||
return true;
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
<div>
|
||||
来源: <span>{props.values.device_name}</span>
|
||||
</div>
|
||||
<div>
|
||||
触发时间: <span>{moment(props.values.appear_time).format('YYYY-MM-DD hh:mm:ss')}</span>
|
||||
</div>
|
||||
<div>
|
||||
<Image width={100} preview={false} src={props.values.picture_path} />
|
||||
</div>
|
||||
</div>
|
||||
</ModalForm>
|
||||
);
|
||||
};
|
||||
export default CaptureForm;
|
@ -1,348 +0,0 @@
|
||||
import TableActionCard from '@/components/TableActionCard';
|
||||
import IsDelete from '@/components/TableActionCard/isDelete';
|
||||
import { getInterfacesUpload, postInterfacesUpload } from '@/services/realTime/interfaces';
|
||||
import { EditOutlined } from '@ant-design/icons';
|
||||
import type { ActionType, ProColumns } from '@ant-design/pro-components';
|
||||
import { PageContainer, ProTable } from '@ant-design/pro-components';
|
||||
import { FormattedMessage, useIntl } from '@umijs/max';
|
||||
import { Button, Tag, message } from 'antd';
|
||||
import moment from 'moment';
|
||||
import React, { useRef, useState } from 'react';
|
||||
import { proTablePaginationOptions } from '../../../../config/defaultTable';
|
||||
import CaptureForm from './components/CaptureForm';
|
||||
import CreateForm from './components/CreateForm';
|
||||
import UpdateForm from './components/UpdateForm';
|
||||
const OfflineDeviceList: React.FC = () => {
|
||||
/**
|
||||
* @en-US International configuration
|
||||
* @zh-CN 国际化配置
|
||||
* */
|
||||
const intl = useIntl();
|
||||
const actionRef = useRef<ActionType>();
|
||||
// 动态设置每页数量
|
||||
const [currentPageSize, setCurrentPageSize] = useState<number>(10);
|
||||
|
||||
const handleDestroy = async (selectedRow: API.UpdateInterfacesParams) => {
|
||||
postInterfacesUpload({ id: selectedRow.id, device_status: '3' })
|
||||
.then(() => {
|
||||
message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '成功' }));
|
||||
actionRef.current?.reload();
|
||||
})
|
||||
.catch(() => {
|
||||
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
|
||||
});
|
||||
};
|
||||
|
||||
const [currentRow, setCurrentRow] = useState<API.UpdateInterfacesParams>();
|
||||
/**
|
||||
* @en-US Pop-up window of new window
|
||||
* @zh-CN 新建窗口的弹窗
|
||||
* */
|
||||
const [createModalOpen, setCreateModalOpen] = useState<boolean>(false);
|
||||
const handleCreateModal = () => {
|
||||
if (createModalOpen) {
|
||||
setCreateModalOpen(false);
|
||||
setCurrentRow(undefined);
|
||||
} else {
|
||||
setCreateModalOpen(true);
|
||||
}
|
||||
};
|
||||
// 编辑弹框
|
||||
const [updateModalOpen, setUpdateModalOpen] = useState<boolean>(false);
|
||||
|
||||
const handleUpdateModal = () => {
|
||||
if (updateModalOpen) {
|
||||
setUpdateModalOpen(false);
|
||||
setCurrentRow(undefined);
|
||||
} else {
|
||||
setUpdateModalOpen(true);
|
||||
}
|
||||
};
|
||||
|
||||
// 最近拍摄
|
||||
const [captureModalOpen, setCaptureModalOpen] = useState<boolean>(false);
|
||||
|
||||
const handleCaptureModal = () => {
|
||||
console.log(captureModalOpen);
|
||||
if (captureModalOpen) {
|
||||
setCaptureModalOpen(false);
|
||||
setCurrentRow(undefined);
|
||||
} else {
|
||||
setCaptureModalOpen(true);
|
||||
}
|
||||
};
|
||||
// 测试连接
|
||||
// const [loading, setLoading] = useState<boolean>(false);
|
||||
|
||||
const columns: ProColumns<API.UpdateInterfacesParams>[] = [
|
||||
{
|
||||
title: (
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.list.videoName"
|
||||
defaultMessage="接口名称"
|
||||
/>
|
||||
),
|
||||
dataIndex: 'device_name',
|
||||
hideInSearch: true,
|
||||
},
|
||||
{
|
||||
title: (
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.list.obtainMode"
|
||||
defaultMessage="获取方式"
|
||||
/>
|
||||
),
|
||||
dataIndex: 'operate_mode',
|
||||
hideInSearch: true,
|
||||
render: (dom) => {
|
||||
return (
|
||||
<div>
|
||||
{dom === 1 && 'FTP'}
|
||||
{dom === 2 && 'FTP上传'}
|
||||
{dom === 3 && '文件系统'}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: (
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.list.obtainStatus"
|
||||
defaultMessage="设备状态"
|
||||
/>
|
||||
),
|
||||
dataIndex: 'test_result',
|
||||
hideInSearch: true,
|
||||
render: (dom, entity) => {
|
||||
return (
|
||||
<div>
|
||||
<Tag
|
||||
bordered={false}
|
||||
color={dom === 1 ? 'success' : ''}
|
||||
style={{
|
||||
// fontSize:14,
|
||||
color: dom === 1 ? '#52C41A' : '#999',
|
||||
}}
|
||||
>
|
||||
{dom === 1 ? '获取成功' : '获取失败'}
|
||||
</Tag>
|
||||
<span>{moment(entity.create_time).format('YYYY-MM-DD hh:mm:ss')}</span>
|
||||
{/* <Button
|
||||
type="link"
|
||||
icon={<RedoOutlined />}
|
||||
loading={loading}
|
||||
onClick={() => {
|
||||
connection(entity)
|
||||
}}
|
||||
/> */}
|
||||
</div>
|
||||
// <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: (
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.list.createTime"
|
||||
defaultMessage="创建时间"
|
||||
/>
|
||||
),
|
||||
dataIndex: 'create_time',
|
||||
sorter: true,
|
||||
hideInSearch: true,
|
||||
valueType: 'dateTime',
|
||||
},
|
||||
|
||||
{
|
||||
title: <FormattedMessage id="pages.searchTable.titleOption" defaultMessage="操作" />,
|
||||
dataIndex: 'option',
|
||||
valueType: 'option',
|
||||
width: '260px',
|
||||
fixed: 'right',
|
||||
render: (_, record) => [
|
||||
<TableActionCard
|
||||
key="TableActionCardRef"
|
||||
renderActions={[
|
||||
// {
|
||||
// key: 'capture',
|
||||
// renderDom: (
|
||||
// <Button
|
||||
// key="capture"
|
||||
// type="link"
|
||||
// size="small"
|
||||
// style={{
|
||||
// color:"#081FA8",
|
||||
// }}
|
||||
// icon={<InstagramOutlined style={{
|
||||
// marginRight: 3
|
||||
// }} />}
|
||||
// onClick={() => {
|
||||
// console.log('11');
|
||||
// setCaptureModalOpen(true);
|
||||
// setCurrentRow(record);
|
||||
// }}
|
||||
// >
|
||||
// {/* 最近拍摄 */}
|
||||
// <FormattedMessage id="device.interface_manage.table.list.capture" defaultMessage="最近拍摄" />
|
||||
// </Button>
|
||||
// ),
|
||||
// },
|
||||
{
|
||||
key: 'update',
|
||||
renderDom: (
|
||||
<Button
|
||||
key="update"
|
||||
type="link"
|
||||
size="small"
|
||||
style={{
|
||||
color: '#081FA8',
|
||||
}}
|
||||
icon={
|
||||
<EditOutlined
|
||||
style={{
|
||||
marginRight: 3,
|
||||
}}
|
||||
/>
|
||||
}
|
||||
onClick={() => {
|
||||
setUpdateModalOpen(true);
|
||||
setCurrentRow(record);
|
||||
}}
|
||||
>
|
||||
<FormattedMessage id="common.edit" defaultMessage="编辑" />
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'destroy',
|
||||
renderDom: (
|
||||
<IsDelete
|
||||
deleteApi={() => {
|
||||
handleDestroy(record).then(() => {});
|
||||
}}
|
||||
></IsDelete>
|
||||
),
|
||||
},
|
||||
]}
|
||||
></TableActionCard>,
|
||||
],
|
||||
},
|
||||
];
|
||||
return (
|
||||
<PageContainer
|
||||
title={false}
|
||||
content={
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontWeight: 600,
|
||||
fontSize: 20,
|
||||
color: '#333',
|
||||
}}
|
||||
>
|
||||
离线设备管理
|
||||
</div>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
setCreateModalOpen(true);
|
||||
}}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.list.addVideoSource"
|
||||
defaultMessage="新建视频源"
|
||||
/>
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<ProTable<API.DeviceCategory>
|
||||
cardProps={{
|
||||
bodyStyle: {
|
||||
padding: 20,
|
||||
},
|
||||
}}
|
||||
options={{ fullScreen: false, setting: false, density: false, reload: false }}
|
||||
actionRef={actionRef}
|
||||
rowKey="key"
|
||||
search={false}
|
||||
showSorterTooltip={false}
|
||||
pagination={{
|
||||
...proTablePaginationOptions,
|
||||
pageSize: currentPageSize,
|
||||
onChange: (page, pageSize) => setCurrentPageSize(pageSize),
|
||||
}}
|
||||
columnsState={{
|
||||
persistenceKey: 'device_category_list',
|
||||
persistenceType: 'localStorage',
|
||||
}}
|
||||
request={async (params = {}, sort) => {
|
||||
const { current, ...rest } = params;
|
||||
const reqParams = {
|
||||
page: current,
|
||||
desc: false,
|
||||
orderKey: '',
|
||||
...rest,
|
||||
};
|
||||
if (sort && Object.keys(sort).length) {
|
||||
reqParams.orderKey = Object.keys(sort)[0];
|
||||
let sort_select = sort[reqParams.orderKey];
|
||||
reqParams.desc = sort_select === 'descend';
|
||||
}
|
||||
// let resp = await postDeviceCategoryGetDeviceCategoryList({ ...reqParams });
|
||||
let resp = await getInterfacesUpload({ ...reqParams });
|
||||
return {
|
||||
data: resp.data.results.map((v: API.DeviceCategory) => {
|
||||
return { ...v, key: v.id };
|
||||
}),
|
||||
success: resp.success,
|
||||
total: resp.data.count,
|
||||
current: resp.data.page,
|
||||
pageSize: resp.data.pageSize,
|
||||
};
|
||||
}}
|
||||
columns={columns}
|
||||
/>
|
||||
<CreateForm
|
||||
createModalOpen={createModalOpen}
|
||||
values={currentRow || {}}
|
||||
handleModal={handleCreateModal}
|
||||
reload={actionRef.current?.reload}
|
||||
/>
|
||||
<UpdateForm
|
||||
updateModalOpen={updateModalOpen}
|
||||
values={currentRow || {}}
|
||||
handleModal={handleUpdateModal}
|
||||
reload={actionRef.current?.reload}
|
||||
/>
|
||||
<CaptureForm
|
||||
captureModalOpen={captureModalOpen}
|
||||
values={currentRow || {}}
|
||||
handleModal={handleCaptureModal}
|
||||
reload={actionRef.current?.reload}
|
||||
/>
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default OfflineDeviceList;
|
@ -1,84 +0,0 @@
|
||||
.alarmImgBox {
|
||||
// display: flex;
|
||||
// justify-content: flex-start;
|
||||
.alarmImgLeft {
|
||||
position: relative;
|
||||
width: 120px;
|
||||
margin-right: 32px;
|
||||
// height: 600px;
|
||||
.alarmImgLeftBox {
|
||||
width: 112px;
|
||||
height: 112px;
|
||||
border-radius: 4px;
|
||||
// background: skyblue;
|
||||
}
|
||||
.alarmImgLeftBoxActive {
|
||||
width: 112px;
|
||||
height: 112px;
|
||||
border: 1.5px solid #081fa8;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.shadowBox {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
left: 0;
|
||||
z-index: 999;
|
||||
width: 112px;
|
||||
height: 20px;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
.alarmImgRight {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
.alarmImgRightTopBox {
|
||||
width: 640px;
|
||||
height: 640px;
|
||||
background: skyblue;
|
||||
}
|
||||
.alarmDetails {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 38px;
|
||||
margin-bottom: 16px;
|
||||
padding-left: 24px;
|
||||
color: #ffffff;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
font-family: PingFang SC;
|
||||
line-height: 38px;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
.alarmSpan {
|
||||
// color: #333;
|
||||
margin-right: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.alarmImgDescribe {
|
||||
margin-bottom: 12px;
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
font-family: PingFang SC;
|
||||
span {
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
.alarmImgContent {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
width: 784px;
|
||||
margin-bottom: 24px;
|
||||
padding: 16px;
|
||||
// height: 172px;
|
||||
background: #f7f7f7;
|
||||
border: 1px dashed #dcdcdc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
.myButtonDisabled {
|
||||
visibility: hidden;
|
||||
}
|
@ -1,293 +0,0 @@
|
||||
import { postIgnoringvents } from '@/services/realTime/alarmlist';
|
||||
import { postRecognition } from '@/services/realTime/involved';
|
||||
import { ModalForm } from '@ant-design/pro-components';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, Form, message } from 'antd';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
// Import Swiper React components
|
||||
// import { Swiper, SwiperSlide } from 'swiper/react';
|
||||
// import { Navigation, Pagination, Mousewheel } from 'swiper/modules';
|
||||
// Import Swiper styles
|
||||
// import 'swiper/css';
|
||||
// import 'swiper/css/navigation';
|
||||
// import 'swiper/css/pagination';
|
||||
import moment from 'moment';
|
||||
import styles from './AlarmDetails.less';
|
||||
import ImageSinglePopover from './ImageSinglePopover';
|
||||
import ImageWithPopover from './ImageWithPopover';
|
||||
export type FormValueType = {
|
||||
target?: string;
|
||||
template?: string;
|
||||
type?: string;
|
||||
time?: string;
|
||||
frequency?: string;
|
||||
} & Partial<API.AlarmDetailsParams>;
|
||||
|
||||
export type UpdateFormProps = {
|
||||
updateModalOpen: boolean;
|
||||
handleModal: () => void;
|
||||
values: Partial<API.AlarmDetailsParams>;
|
||||
reload: any;
|
||||
};
|
||||
const UpdateForm: React.FC<UpdateFormProps> = (props) => {
|
||||
const intl = useIntl();
|
||||
const [form] = Form.useForm<API.AlarmDetailsParams>();
|
||||
// const [isActive, setIsActive] = useState(0);
|
||||
// const [imageSrc, setImageSrc] = useState('');
|
||||
// const [visible, setVisible] = useState(false);
|
||||
const [involved, setInvolved] = useState(0);
|
||||
// const [involvedInfo, setInvolvedInfo] = useState([...(props?.values?.person_list || [])]);
|
||||
const [involvedInfo, setInvolvedInfo] = useState<any[]>([]);
|
||||
useEffect(() => {
|
||||
if (props.values?.person_list) {
|
||||
setInvolvedInfo([...props.values.person_list]);
|
||||
}
|
||||
}, [props.values?.person_list]);
|
||||
useEffect(() => {
|
||||
if (props.values?.person_classify) {
|
||||
setInvolved(props.values.person_classify);
|
||||
console.log(involved);
|
||||
}
|
||||
}, [props.values?.person_classify]);
|
||||
const handlePostRecognition = (person_id: any, classify: any) => {
|
||||
postRecognition({
|
||||
person_id: person_id,
|
||||
classify: classify,
|
||||
})
|
||||
.then((res) => {
|
||||
console.log(res.data.classify, 'res.data.classify');
|
||||
if (res.data.classify === 1) {
|
||||
message.success('此人已被设为重点关注');
|
||||
} else {
|
||||
message.success('此人已被移除重点关注');
|
||||
}
|
||||
props.reload();
|
||||
})
|
||||
.catch(() => {
|
||||
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
|
||||
});
|
||||
};
|
||||
/** 多人告警组件 */
|
||||
const handleInvolved = (value: any, index: any) => {
|
||||
const updatedInvolvedInfo = [...involvedInfo];
|
||||
console.log(updatedInvolvedInfo);
|
||||
updatedInvolvedInfo[index][2] = value;
|
||||
setInvolvedInfo(updatedInvolvedInfo);
|
||||
handlePostRecognition(updatedInvolvedInfo[index][0], value);
|
||||
};
|
||||
/** 单人告警组件 */
|
||||
// const handleSingleInvolved = () => {
|
||||
// if (involved === 1) {
|
||||
// setInvolved(0);
|
||||
// handlePostRecognition(props.values?.person_id, 0)
|
||||
// } else {
|
||||
// setInvolved(1);
|
||||
// handlePostRecognition(props.values?.person_id, 1)
|
||||
// }
|
||||
// }
|
||||
|
||||
// const [open, setOpen] = useState(false);
|
||||
// useEffect(() => {
|
||||
// // console.log(Array.isArray(props.values?.person_id),'Array.isArray(props.values?.person_id)');
|
||||
// setImageSrc(props?.values?.picture_path?.[0]);
|
||||
// }, [props.updateModalOpen]);
|
||||
return (
|
||||
<ModalForm<any>
|
||||
width={832}
|
||||
title={`${props.values.warning_name}告警`}
|
||||
open={props.updateModalOpen}
|
||||
form={form}
|
||||
autoFocusFirstInput
|
||||
modalProps={{
|
||||
destroyOnClose: true,
|
||||
onCancel: () => {
|
||||
setInvolved(0);
|
||||
props.handleModal();
|
||||
},
|
||||
okText: intl.formatMessage({ id: 'common.yes', defaultMessage: '确认' }),
|
||||
cancelText: intl.formatMessage({ id: 'common.no', defaultMessage: '取消' }),
|
||||
}}
|
||||
submitter={{
|
||||
// resetButtonProps: {
|
||||
// style: {
|
||||
// display: 'none',
|
||||
// },
|
||||
// },
|
||||
// searchConfig: {
|
||||
// submitText: '忽略此事件',
|
||||
// },
|
||||
render: (prop) => {
|
||||
return [
|
||||
<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}
|
||||
onFinish={async (values) => {
|
||||
values.is_ignore = true;
|
||||
values.person_id = props.values.person_id;
|
||||
// console.log(values);
|
||||
postIgnoringvents(values)
|
||||
.then(() => {
|
||||
message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '成功' }));
|
||||
props.reload();
|
||||
})
|
||||
.catch(() => {
|
||||
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
|
||||
});
|
||||
|
||||
props.handleModal();
|
||||
return true;
|
||||
}}
|
||||
>
|
||||
{/* <ProForm.Group> */}
|
||||
<div className={styles.alarmImgBox}>
|
||||
<div className={styles.alarmImgDescribe}>
|
||||
来源: <span>{props.values.device_name}</span>
|
||||
</div>
|
||||
<div className={styles.alarmImgDescribe}>
|
||||
触发时间:{' '}
|
||||
<span className={styles.alarmSpan}>
|
||||
{moment(props.values.trigger_time).format('YYYY-MM-DD hh:mm:ss')}
|
||||
</span>
|
||||
</div>
|
||||
<div className={styles.alarmImgContent}>
|
||||
{Array.isArray(props.values?.person_id)
|
||||
? Array.isArray(involvedInfo) && involvedInfo.length
|
||||
? involvedInfo.map((item: any, index: any) => {
|
||||
return (
|
||||
<ImageWithPopover
|
||||
src={item?.[1]}
|
||||
involved={involvedInfo[index][2]}
|
||||
key={index}
|
||||
indexId={index}
|
||||
handleInvolved={handleInvolved}
|
||||
time={props.values.trigger_time}
|
||||
></ImageWithPopover>
|
||||
);
|
||||
})
|
||||
: Array.isArray(props?.values?.picture_path) && props?.values?.picture_path.length
|
||||
? props.values.picture_path.map((item: any, index: any) => {
|
||||
return (
|
||||
<ImageSinglePopover
|
||||
src={item}
|
||||
involved={involved}
|
||||
key={index}
|
||||
// handleInvolved={handleSingleInvolved}
|
||||
reload={props.reload} // 将reload方法作为prop传递给ImageSinglePopover组件
|
||||
time={props.values.trigger_time}
|
||||
></ImageSinglePopover>
|
||||
);
|
||||
})
|
||||
: null
|
||||
: Array.isArray(props?.values?.picture_path) && props?.values?.picture_path.length
|
||||
? props.values.picture_path.map((item: any, index: any) => {
|
||||
return (
|
||||
<ImageSinglePopover
|
||||
src={item}
|
||||
involved={involved}
|
||||
key={index}
|
||||
// handleInvolved={handleSingleInvolved}
|
||||
reload={props.reload} // 将reload方法作为prop传递给ImageSinglePopover组件
|
||||
time={props.values.trigger_time}
|
||||
></ImageSinglePopover>
|
||||
);
|
||||
})
|
||||
: null}
|
||||
{/* { Array.isArray(involvedInfo) && involvedInfo.length && involvedInfo.map((item: any, index: any) => {
|
||||
console.log(involvedInfo,'item');
|
||||
return(<ImageWithPopover src={item?.[1]} involved={involvedInfo[index][2]} key={index} indexId={index} handleInvolved={handleInvolved}></ImageWithPopover>)
|
||||
})} */}
|
||||
</div>
|
||||
{/* <div className={styles.alarmImgLeft}>
|
||||
<Swiper
|
||||
style={{height:660}}
|
||||
slidesPerView={5}
|
||||
spaceBetween={20}
|
||||
direction='vertical'
|
||||
mousewheel={true}
|
||||
modules={[Mousewheel]}
|
||||
onSlideChange={() => {
|
||||
console.log(111);
|
||||
}}
|
||||
// pagination={{
|
||||
// clickable: true,
|
||||
// }}
|
||||
// modules={[Pagination]}
|
||||
>
|
||||
{ Array.isArray(props?.values?.picture_path) && props?.values?.picture_path.length && props?.values?.picture_path.map((item: any, index: any) => {
|
||||
return (<SwiperSlide key={index} virtualIndex={index} onClick={() => {
|
||||
console.log(index);
|
||||
setIsActive(index)
|
||||
setImageSrc(item)
|
||||
}}>
|
||||
<div className={ styles.alarmImgLeftBox }>
|
||||
<Image
|
||||
style={{
|
||||
width: 112,
|
||||
height: 112,
|
||||
borderRadius: 4
|
||||
}}
|
||||
className={ index === isActive ? styles.alarmImgLeftBoxActive : '' }
|
||||
preview={false}
|
||||
src={item}
|
||||
/>
|
||||
</div>
|
||||
</SwiperSlide>)
|
||||
})}
|
||||
</Swiper>
|
||||
<div className={styles.shadowBox}></div>
|
||||
</div>
|
||||
<div className={styles.alarmImgRight}>
|
||||
<div className={styles.alarmImgRightTopBox}>
|
||||
<Image
|
||||
width={640}
|
||||
height={640}
|
||||
preview={false}
|
||||
src={imageSrc}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.alarmDetails}>
|
||||
来源: <span className={styles.alarmSpan}>{props.values.device_name}</span>触发时间: <span className={styles.alarmSpan}>{moment(props.values.trigger_time).format('YYYY-MM-DD hh:mm:ss')}</span>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
{/* </ProForm.Group> */}
|
||||
</ModalForm>
|
||||
);
|
||||
};
|
||||
export default UpdateForm;
|
@ -1,147 +0,0 @@
|
||||
import { EyeOutlined } from '@ant-design/icons';
|
||||
import { Image } from 'antd';
|
||||
import moment from 'moment';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
interface ImageSinglePopoverProps {
|
||||
src: string;
|
||||
involved: any;
|
||||
// handleInvolved: () => void;
|
||||
reload: any;
|
||||
time: any;
|
||||
}
|
||||
|
||||
const ImageSinglePopover: React.FC<ImageSinglePopoverProps> = ({ src, involved, time }) => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
// const [open, setOpen] = useState(false);
|
||||
|
||||
// 定义一个方法,用于生成自定义的遮罩层
|
||||
const generateMask = (text: any) => (
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
color: '#fff',
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', fontSize: 12 }}>
|
||||
<EyeOutlined style={{ marginRight: 8, fontSize: 12 }} />
|
||||
<div>{text}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
// const content = (
|
||||
// <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center',alignItems: 'center', height: 56}}>
|
||||
// {/* <div>选项1</div>
|
||||
// <div>选项2</div> */}
|
||||
// <Button
|
||||
// type="text"
|
||||
// style={{ height:22, padding: 0,fontSize: 12,color: '#FFF' }}
|
||||
// icon={<InfoCircleOutlined style={{ color: '#FAAD14',fontSize: 12}} />}
|
||||
// onClick={()=>{
|
||||
// // setInvolved(true)
|
||||
// // handleInvolved();
|
||||
// // reload()
|
||||
// setOpen(false)
|
||||
// }}
|
||||
// >加入重点关注</Button>
|
||||
// <Button
|
||||
// type="text"
|
||||
// style={{ height:22, padding: 0,fontSize: 12,color: '#FFF' }}
|
||||
// icon={<CloseCircleOutlined style={{ color: '#E80D0D',fontSize: 12}} />}
|
||||
// onClick={()=>{
|
||||
// // setInvolved(false)
|
||||
// // handleInvolved();
|
||||
// // reload()
|
||||
// setOpen(false)
|
||||
// }}
|
||||
// >移除重点关注</Button>
|
||||
// </div>
|
||||
// );
|
||||
const handleVisibleChange = (value: boolean) => {
|
||||
setVisible(value);
|
||||
};
|
||||
|
||||
// const handleOpenChange = (value: boolean) => {
|
||||
// setOpen(value);
|
||||
// };
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
boxSizing: 'border-box',
|
||||
width: 140,
|
||||
height: 160,
|
||||
marginRight: 12,
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
style={{ borderRadius: 4 }}
|
||||
width={140}
|
||||
height={140}
|
||||
preview={{
|
||||
visible,
|
||||
src,
|
||||
onVisibleChange: handleVisibleChange,
|
||||
mask: generateMask('点击可预览大图'),
|
||||
}}
|
||||
src={src}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
height: 30,
|
||||
textAlign: 'center',
|
||||
lineHeight: '30px',
|
||||
fontWeight: 500,
|
||||
color: '#333',
|
||||
}}
|
||||
>
|
||||
{moment(time).format('YYYY-MM-DD hh:mm:ss')}
|
||||
</div>
|
||||
{/* <Popover
|
||||
placement="right"
|
||||
content={content}
|
||||
trigger="click"
|
||||
style={{ width: 104, height: 64 }}
|
||||
color="rgba(0, 0, 0, 0.6)"
|
||||
overlayInnerStyle={{ width: 104, height: 64, padding: 4, borderRadius: 2 }}
|
||||
open={open}
|
||||
onOpenChange={handleOpenChange}
|
||||
>
|
||||
<Button
|
||||
style={{ position: 'absolute', bottom: 8, right: 0 }}
|
||||
type="text"
|
||||
icon={<EllipsisOutlined style={{ color: '#fff', fontSize: 24, transform: 'rotate(90deg)' }} />}
|
||||
/>
|
||||
</Popover> */}
|
||||
{involved === 1 && (
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
right: 0,
|
||||
width: 64,
|
||||
height: 24,
|
||||
background: '#FAAD14',
|
||||
borderRadius: '0px 4px 0px 4px',
|
||||
color: '#FFF',
|
||||
fontSize: 12,
|
||||
textAlign: 'center',
|
||||
lineHeight: '24px',
|
||||
}}
|
||||
>
|
||||
重点关注
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageSinglePopover;
|
@ -1,170 +0,0 @@
|
||||
import {
|
||||
CloseCircleOutlined,
|
||||
EllipsisOutlined,
|
||||
EyeOutlined,
|
||||
InfoCircleOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { Button, Image, Popover } from 'antd';
|
||||
import moment from 'moment';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
interface ImageWithPopoverProps {
|
||||
src: string;
|
||||
involved: any;
|
||||
indexId: any;
|
||||
handleInvolved: (value: any, index: any) => void;
|
||||
time: any;
|
||||
}
|
||||
|
||||
const ImageWithPopover: React.FC<ImageWithPopoverProps> = ({
|
||||
src,
|
||||
involved,
|
||||
indexId,
|
||||
handleInvolved,
|
||||
time,
|
||||
}) => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
// 定义一个方法,用于生成自定义的遮罩层
|
||||
const generateMask = (text: any) => (
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
color: '#fff',
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', fontSize: 12 }}>
|
||||
<EyeOutlined style={{ marginRight: 8, fontSize: 12 }} />
|
||||
<div>{text}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
const content = (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
height: 56,
|
||||
}}
|
||||
>
|
||||
{/* <div>选项1</div>
|
||||
<div>选项2</div> */}
|
||||
<Button
|
||||
type="text"
|
||||
style={{ height: 22, padding: 0, fontSize: 12, color: '#FFF', marginBottom: 4 }}
|
||||
icon={<InfoCircleOutlined style={{ color: '#FAAD14', fontSize: 12 }} />}
|
||||
onClick={() => {
|
||||
// setInvolved(true)
|
||||
handleInvolved(1, indexId);
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
加入重点关注
|
||||
</Button>
|
||||
<Button
|
||||
type="text"
|
||||
style={{ height: 22, padding: 0, fontSize: 12, color: '#FFF' }}
|
||||
icon={<CloseCircleOutlined style={{ color: '#E80D0D', fontSize: 12 }} />}
|
||||
onClick={() => {
|
||||
// setInvolved(false)
|
||||
handleInvolved(0, indexId);
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
移除重点关注
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
const handleVisibleChange = (value: boolean) => {
|
||||
setVisible(value);
|
||||
};
|
||||
|
||||
const handleOpenChange = (value: boolean) => {
|
||||
setOpen(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
position: 'relative',
|
||||
boxSizing: 'border-box',
|
||||
width: 140,
|
||||
height: 160,
|
||||
marginRight: 12,
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
style={{ borderRadius: 4 }}
|
||||
width={140}
|
||||
height={140}
|
||||
preview={{
|
||||
visible,
|
||||
src,
|
||||
onVisibleChange: handleVisibleChange,
|
||||
mask: generateMask('点击可预览大图'),
|
||||
}}
|
||||
src={src}
|
||||
/>
|
||||
<Popover
|
||||
placement="right"
|
||||
content={content}
|
||||
trigger="click"
|
||||
style={{ width: 104, height: 64 }}
|
||||
color="rgba(0, 0, 0, 0.6)"
|
||||
overlayInnerStyle={{ width: 104, height: 68, padding: 4, borderRadius: 2 }}
|
||||
open={open}
|
||||
onOpenChange={handleOpenChange}
|
||||
>
|
||||
<Button
|
||||
style={{ position: 'absolute', bottom: 20, right: 0 }}
|
||||
type="text"
|
||||
icon={
|
||||
<EllipsisOutlined style={{ color: '#fff', fontSize: 24, transform: 'rotate(90deg)' }} />
|
||||
}
|
||||
/>
|
||||
</Popover>
|
||||
<div
|
||||
style={{
|
||||
height: 30,
|
||||
textAlign: 'center',
|
||||
lineHeight: '30px',
|
||||
fontWeight: 500,
|
||||
color: '#333',
|
||||
}}
|
||||
>
|
||||
{moment(time).format('YYYY-MM-DD hh:mm:ss')}
|
||||
</div>
|
||||
{involved === 1 && (
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
right: 0,
|
||||
width: 64,
|
||||
height: 24,
|
||||
background: '#FAAD14',
|
||||
borderRadius: '0px 4px 0px 4px',
|
||||
color: '#FFF',
|
||||
fontSize: 12,
|
||||
textAlign: 'center',
|
||||
lineHeight: '24px',
|
||||
}}
|
||||
>
|
||||
重点关注
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageWithPopover;
|
@ -1,7 +0,0 @@
|
||||
:global {
|
||||
.ant-form-item-control-input-content {
|
||||
.ant-space-gap-col-small {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,234 +0,0 @@
|
||||
import TableActionCard from '@/components/TableActionCard';
|
||||
|
||||
import { getAlarmRules } from '@/services/realTime/alarmRules';
|
||||
import { EditOutlined } from '@ant-design/icons';
|
||||
import type { ActionType, ProColumns } from '@ant-design/pro-components';
|
||||
import { PageContainer, ProTable } from '@ant-design/pro-components';
|
||||
import { FormattedMessage } from '@umijs/max';
|
||||
import { Button, Tag } from 'antd';
|
||||
import React, { useRef, useState } from 'react';
|
||||
import { proTablePaginationOptions } from '../../../../config/defaultTable';
|
||||
import UpdateForm from './components/UpdateForm';
|
||||
import UpdateMultiForm from './components/UpdateMultiForm';
|
||||
import UpdateTimeForm from './components/UpdateTimeForm';
|
||||
const AlarmRules: React.FC = () => {
|
||||
/**
|
||||
* @en-US International configuration
|
||||
* @zh-CN 国际化配置
|
||||
* */
|
||||
const actionRef = useRef<ActionType>();
|
||||
// 动态设置每页数量
|
||||
const [currentPageSize, setCurrentPageSize] = useState<number>(10);
|
||||
|
||||
// const handleDestroy = async (selectedRow: API.DeviceCategory) => {
|
||||
// // deleteDeviceCategoryDeleteDeviceCategory({ 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 [currentRow, setCurrentRow] = useState<API.DeviceCategory>();
|
||||
// 编辑弹框
|
||||
const [updateModalOpen, setUpdateModalOpen] = useState<boolean>(false);
|
||||
const [updateMultiModalOpen, setUpdateMultiModalOpen] = useState<boolean>(false);
|
||||
const [updateTimeModalOpen, setUpdateTimeModalOpen] = useState<boolean>(false);
|
||||
|
||||
const handleUpdateModal = () => {
|
||||
if (updateModalOpen) {
|
||||
setUpdateModalOpen(false);
|
||||
setCurrentRow(undefined);
|
||||
} else {
|
||||
setUpdateModalOpen(true);
|
||||
}
|
||||
};
|
||||
const handleUpdateMultiModal = () => {
|
||||
if (updateMultiModalOpen) {
|
||||
setUpdateMultiModalOpen(false);
|
||||
setCurrentRow(undefined);
|
||||
} else {
|
||||
setUpdateMultiModalOpen(true);
|
||||
}
|
||||
};
|
||||
const handleUpdateTimeModal = () => {
|
||||
setCurrentRow(undefined);
|
||||
|
||||
if (updateTimeModalOpen) {
|
||||
setUpdateTimeModalOpen(false);
|
||||
} else {
|
||||
setUpdateTimeModalOpen(true);
|
||||
}
|
||||
};
|
||||
|
||||
const columns: ProColumns<API.DeviceCategory>[] = [
|
||||
{
|
||||
title: <FormattedMessage id="alarm_rules.page.name" defaultMessage="告警规则" />,
|
||||
dataIndex: 'warning_name',
|
||||
hideInSearch: true,
|
||||
},
|
||||
|
||||
{
|
||||
title: <FormattedMessage id="alarm_rules.page.id" defaultMessage="规则ID" />,
|
||||
dataIndex: 'id',
|
||||
hideInSearch: true,
|
||||
},
|
||||
{
|
||||
title: <FormattedMessage id="alarm_rules.page.status" defaultMessage="规则状态" />,
|
||||
dataIndex: 'is_use',
|
||||
hideInSearch: true,
|
||||
render: (dom) => {
|
||||
return (
|
||||
<Tag
|
||||
bordered={false}
|
||||
color={dom === 1 ? 'success' : ''}
|
||||
style={{
|
||||
// fontSize:14,
|
||||
color: dom === 1 ? '#52C41A' : '#999',
|
||||
}}
|
||||
>
|
||||
{dom === 1 ? '已启用' : '未启用'}
|
||||
</Tag>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: <FormattedMessage id="alarm_rules.page.updateTime" defaultMessage="修改时间" />,
|
||||
dataIndex: 'update_time',
|
||||
sorter: true,
|
||||
hideInSearch: true,
|
||||
valueType: 'dateTime',
|
||||
},
|
||||
|
||||
{
|
||||
title: <FormattedMessage id="pages.searchTable.titleOption" defaultMessage="操作" />,
|
||||
dataIndex: 'option',
|
||||
valueType: 'option',
|
||||
fixed: 'right',
|
||||
render: (_, record) => [
|
||||
<TableActionCard
|
||||
key="TableActionCardRef"
|
||||
renderActions={[
|
||||
{
|
||||
key: 'update',
|
||||
renderDom: (
|
||||
<Button
|
||||
key="update"
|
||||
type="link"
|
||||
size="small"
|
||||
style={{
|
||||
color: '#081FA8',
|
||||
}}
|
||||
icon={
|
||||
<EditOutlined
|
||||
style={{
|
||||
marginRight: 3,
|
||||
}}
|
||||
/>
|
||||
}
|
||||
onClick={() => {
|
||||
console.log(record);
|
||||
if (record.id === 1) {
|
||||
setUpdateModalOpen(true);
|
||||
} else if (record.id === 2) {
|
||||
setUpdateMultiModalOpen(true);
|
||||
} else {
|
||||
setUpdateTimeModalOpen(true);
|
||||
}
|
||||
setCurrentRow(record);
|
||||
}}
|
||||
>
|
||||
<FormattedMessage id="common.edit" defaultMessage="编辑" />
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
// {
|
||||
// key: 'destroy',
|
||||
// renderDom: (
|
||||
// <IsDelete
|
||||
// deleteApi={() => {
|
||||
// handleDestroy(record).then(() => {});
|
||||
// }}
|
||||
// ></IsDelete>
|
||||
// ),
|
||||
// },
|
||||
]}
|
||||
></TableActionCard>,
|
||||
],
|
||||
},
|
||||
];
|
||||
return (
|
||||
<PageContainer>
|
||||
<ProTable<API.DeviceCategory>
|
||||
cardProps={{
|
||||
bodyStyle: {
|
||||
padding: 20,
|
||||
},
|
||||
}}
|
||||
options={{ fullScreen: false, setting: false, density: false, reload: false }}
|
||||
actionRef={actionRef}
|
||||
rowKey="key"
|
||||
search={false}
|
||||
showSorterTooltip={false}
|
||||
pagination={{
|
||||
...proTablePaginationOptions,
|
||||
pageSize: currentPageSize,
|
||||
onChange: (page, pageSize) => setCurrentPageSize(pageSize),
|
||||
}}
|
||||
columnsState={{
|
||||
persistenceKey: 'device_category_list',
|
||||
persistenceType: 'localStorage',
|
||||
}}
|
||||
request={async (params = {}, sort) => {
|
||||
const { current, ...rest } = params;
|
||||
const reqParams = {
|
||||
page: current,
|
||||
desc: false,
|
||||
orderKey: '',
|
||||
...rest,
|
||||
};
|
||||
if (sort && Object.keys(sort).length) {
|
||||
reqParams.orderKey = Object.keys(sort)[0];
|
||||
let sort_select = sort[reqParams.orderKey];
|
||||
reqParams.desc = sort_select === 'descend';
|
||||
}
|
||||
// let resp = await postDeviceCategoryGetDeviceCategoryList({ ...reqParams });
|
||||
let resp = await getAlarmRules(reqParams);
|
||||
console.log(resp);
|
||||
return {
|
||||
data: resp.data.results.map((v: API.DeviceCategory) => {
|
||||
return { ...v, key: v.id };
|
||||
}),
|
||||
success: resp.success,
|
||||
total: resp.data.count,
|
||||
current: resp.data.page,
|
||||
pageSize: resp.data.pageSize,
|
||||
};
|
||||
}}
|
||||
columns={columns}
|
||||
/>
|
||||
<UpdateForm
|
||||
updateModalOpen={updateModalOpen}
|
||||
values={currentRow || {}}
|
||||
handleModal={handleUpdateModal}
|
||||
reload={actionRef.current?.reload}
|
||||
/>
|
||||
<UpdateMultiForm
|
||||
updateModalOpen={updateMultiModalOpen}
|
||||
values={currentRow || {}}
|
||||
handleModal={handleUpdateMultiModal}
|
||||
reload={actionRef.current?.reload}
|
||||
/>
|
||||
<UpdateTimeForm
|
||||
updateModalOpen={updateTimeModalOpen}
|
||||
values={currentRow || {}}
|
||||
handleModal={handleUpdateTimeModal}
|
||||
reload={actionRef.current?.reload}
|
||||
/>
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default AlarmRules;
|
@ -1,60 +0,0 @@
|
||||
import { postTestDevice } from '@/services/realTime/interfaces';
|
||||
import { RedoOutlined } from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, Tag, message } from 'antd';
|
||||
import moment from 'moment';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
interface ImageSinglePopoverProps {
|
||||
values: any;
|
||||
reload: any;
|
||||
}
|
||||
|
||||
const CaptureButton: React.FC<ImageSinglePopoverProps> = (props) => {
|
||||
const intl = useIntl();
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const connection = () => {
|
||||
setLoading(true);
|
||||
postTestDevice({
|
||||
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 (
|
||||
<div>
|
||||
<Tag
|
||||
bordered={false}
|
||||
color={props.values.test_result === 1 ? 'success' : ''}
|
||||
style={{
|
||||
// fontSize:14,
|
||||
color: props.values.test_result === 1 ? '#52C41A' : '#999',
|
||||
}}
|
||||
>
|
||||
{props.values.test_result === 1 ? '在线' : '离线'}
|
||||
</Tag>
|
||||
<span>{moment(props.values.test_time).format('YYYY-MM-DD hh:mm:ss')}</span>
|
||||
<Button
|
||||
type="link"
|
||||
icon={<RedoOutlined />}
|
||||
loading={loading}
|
||||
onClick={() => {
|
||||
connection();
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CaptureButton;
|
@ -1,24 +0,0 @@
|
||||
.captureImgBox {
|
||||
.captureImgDescribe {
|
||||
margin-bottom: 12px;
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
font-family: PingFang SC;
|
||||
span {
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
.captureImgContent {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
margin-bottom: 24px;
|
||||
padding: 16px;
|
||||
// height: 172px;
|
||||
background: #f7f7f7;
|
||||
border: 1px dashed #dcdcdc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* @Author: donghao donghao@supervision.ltd
|
||||
* @Date: 2024-04-03 13:15:26
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2024-04-03 13:17:18
|
||||
* @FilePath: \uighur-recognition-web2\src\pages\RealTime\DeviceList\components\CaptureForm.tsx
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
import { postInterfaces } from '@/services/realTime/interfaces';
|
||||
import { ModalForm } from '@ant-design/pro-components';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Form, Image, message } from 'antd';
|
||||
import moment from 'moment';
|
||||
import React from 'react';
|
||||
import { proFormSmallModelWidth } from '../../../../../config/defaultForm';
|
||||
import styles from './CaptureForm.less';
|
||||
export type FormValueType = {
|
||||
target?: string;
|
||||
template?: string;
|
||||
type?: string;
|
||||
time?: string;
|
||||
frequency?: string;
|
||||
} & Partial<API.UpdateInterfacesParams>;
|
||||
|
||||
export type UpdateFormProps = {
|
||||
captureModalOpen: boolean;
|
||||
handleModal: () => void;
|
||||
values: Partial<API.UpdateInterfacesParams>;
|
||||
reload: any;
|
||||
};
|
||||
const CaptureForm: React.FC<UpdateFormProps> = (props) => {
|
||||
const intl = useIntl();
|
||||
const [form] = Form.useForm<API.UpdateInterfacesParams>();
|
||||
|
||||
return (
|
||||
<ModalForm<any>
|
||||
width={proFormSmallModelWidth}
|
||||
title={intl.formatMessage({
|
||||
id: 'device.interface_manage.table.list.capture',
|
||||
defaultMessage: `最近拍摄`,
|
||||
})}
|
||||
open={props.captureModalOpen}
|
||||
form={form}
|
||||
autoFocusFirstInput
|
||||
modalProps={{
|
||||
destroyOnClose: true,
|
||||
onCancel: () => {
|
||||
props.handleModal();
|
||||
},
|
||||
// okText: intl.formatMessage({ id: 'common.okText', defaultMessage: '确认' }),
|
||||
// cancelText: intl.formatMessage({ id: 'common.cancelText', defaultMessage: '取消' }),
|
||||
}}
|
||||
submitTimeout={2000}
|
||||
submitter={false}
|
||||
onFinish={async (values) => {
|
||||
console.log(values);
|
||||
values.id = props.values.id;
|
||||
postInterfaces(values)
|
||||
.then(() => {
|
||||
message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '成功' }));
|
||||
props.reload();
|
||||
})
|
||||
.catch(() => {
|
||||
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
|
||||
});
|
||||
|
||||
props.handleModal();
|
||||
return true;
|
||||
}}
|
||||
>
|
||||
<div className={styles.captureImgBox}>
|
||||
<div className={styles.captureImgDescribe}>
|
||||
来源: <span>{props.values.device_name}</span>
|
||||
</div>
|
||||
<div className={styles.captureImgDescribe}>
|
||||
触发时间: <span>{moment(props.values.appear_time).format('YYYY-MM-DD hh:mm:ss')}</span>
|
||||
</div>
|
||||
<div className={styles.captureImgContent}>
|
||||
<Image width={100} preview={false} src={props.values.picture_path} />
|
||||
</div>
|
||||
</div>
|
||||
</ModalForm>
|
||||
);
|
||||
};
|
||||
export default CaptureForm;
|
@ -1,212 +0,0 @@
|
||||
/**
|
||||
* 接口管理新建弹框
|
||||
*
|
||||
*/
|
||||
import { postInterfaces, postTestDevice } from '@/services/realTime/interfaces';
|
||||
import { ModalForm, ProForm, ProFormText, ProFormTextArea } from '@ant-design/pro-components';
|
||||
import { FormattedMessage, useIntl } from '@umijs/max';
|
||||
import { Button, Form, message } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
proFormSmallItemStyleProps,
|
||||
proFormSmallModelWidth,
|
||||
} from '../../../../../config/defaultForm';
|
||||
export type FormValueType = {
|
||||
target?: string;
|
||||
template?: string;
|
||||
type?: string;
|
||||
time?: string;
|
||||
frequency?: string;
|
||||
} & Partial<API.UpdateInterfacesParams>;
|
||||
|
||||
export type CreateFormProps = {
|
||||
createModalOpen: boolean;
|
||||
handleModal: () => void;
|
||||
values: Partial<API.UpdateInterfacesParams>;
|
||||
reload: any;
|
||||
};
|
||||
const CreateForm: React.FC<CreateFormProps> = (props) => {
|
||||
const intl = useIntl();
|
||||
const [form] = Form.useForm<API.UpdateInterfacesParams>();
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const connection = async () => {
|
||||
setLoading(true);
|
||||
console.log(form.getFieldsValue());
|
||||
postTestDevice({
|
||||
device_ip: form.getFieldsValue().device_ip,
|
||||
})
|
||||
.then((res) => {
|
||||
// message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '成功' }));
|
||||
// props.reload();
|
||||
console.log(res);
|
||||
if (res.success) {
|
||||
message.success(res.msg);
|
||||
}
|
||||
setLoading(false);
|
||||
})
|
||||
.catch(() => {
|
||||
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
|
||||
});
|
||||
// setTimeout(() => {
|
||||
// setLoading(false);
|
||||
// }, 6000);
|
||||
};
|
||||
|
||||
return (
|
||||
<ModalForm<API.UpdateInterfacesParams>
|
||||
width={proFormSmallModelWidth}
|
||||
title={intl.formatMessage({
|
||||
id: 'device.interface_manage.table.list.addPic',
|
||||
defaultMessage: '新建图像获取接口',
|
||||
})}
|
||||
open={props.createModalOpen}
|
||||
form={form}
|
||||
autoFocusFirstInput
|
||||
modalProps={{
|
||||
destroyOnClose: true,
|
||||
onCancel: () => {
|
||||
setLoading(false);
|
||||
props.handleModal();
|
||||
},
|
||||
okText: intl.formatMessage({ id: 'common.okText', defaultMessage: '确认' }),
|
||||
cancelText: intl.formatMessage({ id: 'common.cancelText', defaultMessage: '取消' }),
|
||||
}}
|
||||
submitTimeout={2000}
|
||||
onFinish={async (values) => {
|
||||
console.log(values);
|
||||
postInterfaces(values)
|
||||
.then(() => {
|
||||
message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '成功' }));
|
||||
props.reload();
|
||||
})
|
||||
.catch(() => {
|
||||
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
|
||||
});
|
||||
props.handleModal();
|
||||
return true;
|
||||
}}
|
||||
>
|
||||
<ProForm.Group>
|
||||
<ProFormText
|
||||
width={proFormSmallItemStyleProps.width}
|
||||
name="device_name"
|
||||
label={
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.list.name"
|
||||
defaultMessage="接口名称"
|
||||
/>
|
||||
}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '请输入',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device.interface_manage.table.list.name',
|
||||
defaultMessage: '接口名称',
|
||||
})}`}
|
||||
required={true}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: (
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.rule.required.name"
|
||||
defaultMessage="接口名称为必填项"
|
||||
/>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<ProFormText
|
||||
width={proFormSmallItemStyleProps.width}
|
||||
name="device_api"
|
||||
label={
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.list.address"
|
||||
defaultMessage="接口地址"
|
||||
/>
|
||||
}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '请输入',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device.interface_manage.table.list.address',
|
||||
defaultMessage: '接口地址',
|
||||
})}`}
|
||||
required={true}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: (
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.rule.required.address"
|
||||
defaultMessage="接口地址为必填项"
|
||||
/>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<ProFormText
|
||||
width={proFormSmallItemStyleProps.width - 96}
|
||||
name="device_ip"
|
||||
label={
|
||||
<FormattedMessage id="device.interface_manage.table.list.ip" defaultMessage="IP地址" />
|
||||
}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '请输入',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device.interface_manage.table.list.ip',
|
||||
defaultMessage: 'IP地址',
|
||||
})}`}
|
||||
required={true}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: (
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.rule.required.ip"
|
||||
defaultMessage="IP地址为必填项"
|
||||
/>
|
||||
),
|
||||
},
|
||||
]}
|
||||
addonAfter={
|
||||
<Button
|
||||
style={{
|
||||
width: 86,
|
||||
height: 32,
|
||||
border: '1px solid #081FA8',
|
||||
borderRadius: 4,
|
||||
fontSize: 14,
|
||||
color: '#081FA8',
|
||||
}}
|
||||
loading={loading}
|
||||
onClick={() => connection()}
|
||||
>
|
||||
{loading ? '' : '连接测试'}
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<ProFormTextArea
|
||||
width={proFormSmallItemStyleProps.width}
|
||||
name="note"
|
||||
label={
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.list.remark"
|
||||
defaultMessage="备注"
|
||||
/>
|
||||
}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '请输入',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device.interface_manage.table.list.remark',
|
||||
defaultMessage: '备注',
|
||||
})}`}
|
||||
required={false}
|
||||
/>
|
||||
</ProForm.Group>
|
||||
</ModalForm>
|
||||
);
|
||||
};
|
||||
export default CreateForm;
|
@ -1,222 +0,0 @@
|
||||
/*
|
||||
* @Author: zhoux zhouxia@supervision.ltd
|
||||
* @Date: 2023-11-01 13:56:33
|
||||
* @LastEditors: donghao donghao@supervision.ltd
|
||||
* @LastEditTime: 2024-04-03 13:17:58
|
||||
* @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
|
||||
*/
|
||||
import { postInterfaces, postTestDevice } from '@/services/realTime/interfaces';
|
||||
import { ModalForm, ProForm, ProFormText, ProFormTextArea } from '@ant-design/pro-components';
|
||||
import { FormattedMessage, useIntl } from '@umijs/max';
|
||||
import { Button, Form, message } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
proFormSmallItemStyleProps,
|
||||
proFormSmallModelWidth,
|
||||
} from '../../../../../config/defaultForm';
|
||||
export type FormValueType = {
|
||||
target?: string;
|
||||
template?: string;
|
||||
type?: string;
|
||||
time?: string;
|
||||
frequency?: string;
|
||||
} & Partial<API.UpdateInterfacesParams>;
|
||||
|
||||
export type UpdateFormProps = {
|
||||
updateModalOpen: boolean;
|
||||
handleModal: () => void;
|
||||
values: Partial<API.UpdateInterfacesParams>;
|
||||
reload: any;
|
||||
};
|
||||
const UpdateForm: React.FC<UpdateFormProps> = (props) => {
|
||||
const intl = useIntl();
|
||||
const [form] = Form.useForm<API.UpdateInterfacesParams>();
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const connection = () => {
|
||||
setLoading(true);
|
||||
console.log(props.values);
|
||||
postTestDevice({
|
||||
device_ip: form.getFieldsValue().device_ip,
|
||||
id: props.values.id,
|
||||
})
|
||||
.then((res) => {
|
||||
// message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '成功' }));
|
||||
// props.reload();
|
||||
console.log(res);
|
||||
if (res.success) {
|
||||
message.success(res.msg);
|
||||
}
|
||||
setLoading(false);
|
||||
})
|
||||
.catch(() => {
|
||||
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
|
||||
setLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<ModalForm<any>
|
||||
width={proFormSmallModelWidth}
|
||||
title={intl.formatMessage({
|
||||
id: 'device.interface_manage.table.list.updatePic',
|
||||
defaultMessage: `编辑${props.values.device_name}`,
|
||||
})}
|
||||
open={props.updateModalOpen}
|
||||
form={form}
|
||||
autoFocusFirstInput
|
||||
modalProps={{
|
||||
destroyOnClose: true,
|
||||
onCancel: () => {
|
||||
setLoading(false);
|
||||
props.handleModal();
|
||||
},
|
||||
okText: intl.formatMessage({ id: 'common.okText', defaultMessage: '确认' }),
|
||||
cancelText: intl.formatMessage({ id: 'common.cancelText', defaultMessage: '取消' }),
|
||||
}}
|
||||
submitTimeout={2000}
|
||||
onFinish={async (values) => {
|
||||
console.log(values);
|
||||
values.id = props.values.id;
|
||||
postInterfaces(values)
|
||||
.then(() => {
|
||||
message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '成功' }));
|
||||
props.reload();
|
||||
})
|
||||
.catch(() => {
|
||||
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
|
||||
});
|
||||
|
||||
props.handleModal();
|
||||
return true;
|
||||
}}
|
||||
>
|
||||
<ProForm.Group>
|
||||
<ProFormText
|
||||
width={proFormSmallItemStyleProps.width}
|
||||
name="device_name"
|
||||
label={
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.list.name"
|
||||
defaultMessage="接口名称"
|
||||
/>
|
||||
}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '请输入',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device.interface_manage.table.list.name',
|
||||
defaultMessage: '接口名称',
|
||||
})}`}
|
||||
required={true}
|
||||
initialValue={props.values.device_name}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: (
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.rule.required.name"
|
||||
defaultMessage="接口名称为必填项"
|
||||
/>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<ProFormText
|
||||
width={proFormSmallItemStyleProps.width}
|
||||
name="device_api"
|
||||
label={
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.list.address"
|
||||
defaultMessage="接口地址"
|
||||
/>
|
||||
}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '请输入',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device.interface_manage.table.list.address',
|
||||
defaultMessage: '接口地址',
|
||||
})}`}
|
||||
required={true}
|
||||
initialValue={props.values.device_api}
|
||||
disabled={false}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: (
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.rule.required.address"
|
||||
defaultMessage="接口地址为必填项"
|
||||
/>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<ProFormText
|
||||
width={proFormSmallItemStyleProps.width - 96}
|
||||
name="device_ip"
|
||||
label={
|
||||
<FormattedMessage id="device.interface_manage.table.list.ip" defaultMessage="IP地址" />
|
||||
}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '请输入',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device.interface_manage.table.list.ip',
|
||||
defaultMessage: 'IP地址',
|
||||
})}`}
|
||||
required={true}
|
||||
initialValue={props.values.device_ip}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: (
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.rule.required.ip"
|
||||
defaultMessage="IP地址为必填项"
|
||||
/>
|
||||
),
|
||||
},
|
||||
]}
|
||||
addonAfter={
|
||||
<Button
|
||||
style={{
|
||||
width: 86,
|
||||
height: 32,
|
||||
border: '1px solid #081FA8',
|
||||
borderRadius: 4,
|
||||
fontSize: 14,
|
||||
color: '#081FA8',
|
||||
}}
|
||||
loading={loading}
|
||||
onClick={() => connection()}
|
||||
>
|
||||
{loading ? '' : '连接测试'}
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<ProFormTextArea
|
||||
width={proFormSmallItemStyleProps.width}
|
||||
name="note"
|
||||
label={
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.list.remark"
|
||||
defaultMessage="备注"
|
||||
/>
|
||||
}
|
||||
placeholder={`${intl.formatMessage({
|
||||
id: 'common.please_input',
|
||||
defaultMessage: '请输入',
|
||||
})}${intl.formatMessage({
|
||||
id: 'device.interface_manage.table.list.remark',
|
||||
defaultMessage: '备注',
|
||||
})}`}
|
||||
initialValue={props.values.note}
|
||||
required={false}
|
||||
/>
|
||||
</ProForm.Group>
|
||||
</ModalForm>
|
||||
);
|
||||
};
|
||||
export default UpdateForm;
|
@ -1,298 +0,0 @@
|
||||
import TableActionCard from '@/components/TableActionCard';
|
||||
import IsDelete from '@/components/TableActionCard/isDelete';
|
||||
import { getInterfaces, postInterfaces } from '@/services/realTime/interfaces';
|
||||
import { EditOutlined, InstagramOutlined } from '@ant-design/icons';
|
||||
import type { ActionType, ProColumns } from '@ant-design/pro-components';
|
||||
import { PageContainer, ProTable } from '@ant-design/pro-components';
|
||||
import { FormattedMessage, useIntl } from '@umijs/max';
|
||||
import { Button, message } from 'antd';
|
||||
import React, { useRef, useState } from 'react';
|
||||
import { proTablePaginationOptions } from '../../../../config/defaultTable';
|
||||
import CaptureButton from './components/CaptureButton';
|
||||
import CaptureForm from './components/CaptureForm';
|
||||
import CreateForm from './components/CreateForm';
|
||||
import UpdateForm from './components/UpdateForm';
|
||||
const DeviceList: React.FC = () => {
|
||||
/**
|
||||
* @en-US International configuration
|
||||
* @zh-CN 国际化配置
|
||||
* */
|
||||
const intl = useIntl();
|
||||
const actionRef = useRef<ActionType>();
|
||||
// 动态设置每页数量
|
||||
const [currentPageSize, setCurrentPageSize] = useState<number>(10);
|
||||
|
||||
const handleDestroy = async (selectedRow: API.UpdateInterfacesParams) => {
|
||||
postInterfaces({ id: selectedRow.id, device_status: '3' })
|
||||
.then(() => {
|
||||
message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '成功' }));
|
||||
actionRef.current?.reload();
|
||||
})
|
||||
.catch(() => {
|
||||
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
|
||||
});
|
||||
};
|
||||
|
||||
const [currentRow, setCurrentRow] = useState<API.UpdateInterfacesParams>();
|
||||
/**
|
||||
* @en-US Pop-up window of new window
|
||||
* @zh-CN 新建窗口的弹窗
|
||||
* */
|
||||
const [createModalOpen, setCreateModalOpen] = useState<boolean>(false);
|
||||
const handleCreateModal = () => {
|
||||
if (createModalOpen) {
|
||||
setCreateModalOpen(false);
|
||||
setCurrentRow(undefined);
|
||||
} else {
|
||||
setCreateModalOpen(true);
|
||||
}
|
||||
};
|
||||
// 编辑弹框
|
||||
const [updateModalOpen, setUpdateModalOpen] = useState<boolean>(false);
|
||||
|
||||
const handleUpdateModal = () => {
|
||||
if (updateModalOpen) {
|
||||
setUpdateModalOpen(false);
|
||||
setCurrentRow(undefined);
|
||||
} else {
|
||||
setUpdateModalOpen(true);
|
||||
}
|
||||
};
|
||||
|
||||
// 最近拍摄
|
||||
const [captureModalOpen, setCaptureModalOpen] = useState<boolean>(false);
|
||||
|
||||
const handleCaptureModal = () => {
|
||||
console.log(captureModalOpen);
|
||||
if (captureModalOpen) {
|
||||
setCaptureModalOpen(false);
|
||||
setCurrentRow(undefined);
|
||||
} else {
|
||||
setCaptureModalOpen(true);
|
||||
}
|
||||
};
|
||||
const columns: ProColumns<API.UpdateInterfacesParams>[] = [
|
||||
{
|
||||
title: (
|
||||
<FormattedMessage id="device.interface_manage.table.list.name" defaultMessage="接口名称" />
|
||||
),
|
||||
dataIndex: 'device_name',
|
||||
hideInSearch: true,
|
||||
},
|
||||
{
|
||||
title: <FormattedMessage id="alarm_rules.page.status" 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.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: (
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.list.createTime"
|
||||
defaultMessage="创建时间"
|
||||
/>
|
||||
),
|
||||
dataIndex: 'create_time',
|
||||
sorter: true,
|
||||
hideInSearch: true,
|
||||
valueType: 'dateTime',
|
||||
},
|
||||
|
||||
{
|
||||
title: <FormattedMessage id="pages.searchTable.titleOption" defaultMessage="操作" />,
|
||||
dataIndex: 'option',
|
||||
valueType: 'option',
|
||||
width: '260px',
|
||||
fixed: 'right',
|
||||
render: (_, record) => [
|
||||
<TableActionCard
|
||||
key="TableActionCardRef"
|
||||
renderActions={[
|
||||
{
|
||||
key: 'capture',
|
||||
renderDom: (
|
||||
<Button
|
||||
key="capture"
|
||||
type="link"
|
||||
size="small"
|
||||
style={{
|
||||
color: '#081FA8',
|
||||
}}
|
||||
icon={
|
||||
<InstagramOutlined
|
||||
style={{
|
||||
marginRight: 3,
|
||||
}}
|
||||
/>
|
||||
}
|
||||
onClick={() => {
|
||||
console.log('11');
|
||||
setCaptureModalOpen(true);
|
||||
setCurrentRow(record);
|
||||
}}
|
||||
>
|
||||
{/* 最近拍摄 */}
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.list.capture"
|
||||
defaultMessage="最近拍摄"
|
||||
/>
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'update',
|
||||
renderDom: (
|
||||
<Button
|
||||
key="update"
|
||||
type="link"
|
||||
size="small"
|
||||
style={{
|
||||
color: '#081FA8',
|
||||
}}
|
||||
icon={
|
||||
<EditOutlined
|
||||
style={{
|
||||
marginRight: 3,
|
||||
}}
|
||||
/>
|
||||
}
|
||||
onClick={() => {
|
||||
setUpdateModalOpen(true);
|
||||
setCurrentRow(record);
|
||||
}}
|
||||
>
|
||||
<FormattedMessage id="common.edit" defaultMessage="编辑" />
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'destroy',
|
||||
renderDom: (
|
||||
<IsDelete
|
||||
deleteApi={() => {
|
||||
handleDestroy(record).then(() => {});
|
||||
}}
|
||||
></IsDelete>
|
||||
),
|
||||
},
|
||||
]}
|
||||
></TableActionCard>,
|
||||
],
|
||||
},
|
||||
];
|
||||
return (
|
||||
<PageContainer
|
||||
title={false}
|
||||
content={
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontWeight: 600,
|
||||
fontSize: 20,
|
||||
color: '#333',
|
||||
}}
|
||||
>
|
||||
设备管理
|
||||
</div>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
setCreateModalOpen(true);
|
||||
}}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="device.interface_manage.table.list.add"
|
||||
defaultMessage="新建设备/输入源"
|
||||
/>
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<ProTable<API.DeviceCategory>
|
||||
cardProps={{
|
||||
bodyStyle: {
|
||||
padding: 20,
|
||||
},
|
||||
}}
|
||||
options={{ fullScreen: false, setting: false, density: false, reload: false }}
|
||||
actionRef={actionRef}
|
||||
rowKey="key"
|
||||
search={false}
|
||||
showSorterTooltip={false}
|
||||
pagination={{
|
||||
...proTablePaginationOptions,
|
||||
pageSize: currentPageSize,
|
||||
onChange: (page, pageSize) => setCurrentPageSize(pageSize),
|
||||
}}
|
||||
columnsState={{
|
||||
persistenceKey: 'device_category_list',
|
||||
persistenceType: 'localStorage',
|
||||
}}
|
||||
request={async (params = {}, sort) => {
|
||||
const { current, ...rest } = params;
|
||||
const reqParams = {
|
||||
page: current,
|
||||
desc: false,
|
||||
orderKey: '',
|
||||
...rest,
|
||||
};
|
||||
if (sort && Object.keys(sort).length) {
|
||||
reqParams.orderKey = Object.keys(sort)[0];
|
||||
let sort_select = sort[reqParams.orderKey];
|
||||
reqParams.desc = sort_select === 'descend';
|
||||
}
|
||||
let resp = await getInterfaces({ ...reqParams });
|
||||
return {
|
||||
data: resp.data.results.map((v: API.DeviceCategory) => {
|
||||
return { ...v, key: v.id };
|
||||
}),
|
||||
success: resp.success,
|
||||
total: resp.data.count,
|
||||
current: resp.data.page,
|
||||
pageSize: resp.data.pageSize,
|
||||
};
|
||||
}}
|
||||
columns={columns}
|
||||
/>
|
||||
<CreateForm
|
||||
createModalOpen={createModalOpen}
|
||||
values={currentRow || {}}
|
||||
handleModal={handleCreateModal}
|
||||
reload={actionRef.current?.reload}
|
||||
/>
|
||||
<UpdateForm
|
||||
updateModalOpen={updateModalOpen}
|
||||
values={currentRow || {}}
|
||||
handleModal={handleUpdateModal}
|
||||
reload={actionRef.current?.reload}
|
||||
/>
|
||||
<CaptureForm
|
||||
captureModalOpen={captureModalOpen}
|
||||
values={currentRow || {}}
|
||||
handleModal={handleCaptureModal}
|
||||
reload={actionRef.current?.reload}
|
||||
/>
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default DeviceList;
|
@ -1,100 +0,0 @@
|
||||
import { postRecognition } from '@/services/realTime/involved';
|
||||
import { CloseCircleOutlined, EllipsisOutlined } from '@ant-design/icons';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, Image, Popover, message } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
interface ImageWithPopoverProps {
|
||||
src: string;
|
||||
reload: any;
|
||||
person_id: any;
|
||||
}
|
||||
|
||||
const ImageWithPopover: React.FC<ImageWithPopoverProps> = ({ src, person_id, reload }) => {
|
||||
const intl = useIntl();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const content = (
|
||||
<div
|
||||
style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}
|
||||
>
|
||||
{/* <div>选项1</div>
|
||||
<div>选项2</div> */}
|
||||
<Button
|
||||
type="text"
|
||||
style={{ height: 22, padding: 0, fontSize: 12, color: '#FFF' }}
|
||||
icon={<CloseCircleOutlined style={{ color: '#E80D0D', fontSize: 12 }} />}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
postRecognition({
|
||||
person_id: person_id,
|
||||
classify: '0',
|
||||
})
|
||||
.then(() => {
|
||||
message.success('此人已被移除重点关注');
|
||||
reload();
|
||||
})
|
||||
.catch(() => {
|
||||
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
|
||||
});
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
移除重点关注
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
const handleOpenChange = (value: boolean) => {
|
||||
setOpen(value);
|
||||
};
|
||||
const handleButtonClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
event.stopPropagation(); // 阻止事件冒泡到父组件并阻止默认事件触发
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ position: 'relative', boxSizing: 'border-box', width: 96, height: 96 }}>
|
||||
<Image style={{ borderRadius: 4 }} width={96} height={96} preview={false} src={src} />
|
||||
<Popover
|
||||
placement="right"
|
||||
content={content}
|
||||
trigger="click"
|
||||
style={{ width: 104, height: 32 }}
|
||||
color="rgba(0, 0, 0, 0.6)"
|
||||
overlayInnerStyle={{ width: 104, height: 32, padding: 4, borderRadius: 2 }}
|
||||
open={open}
|
||||
onOpenChange={handleOpenChange}
|
||||
>
|
||||
<Button
|
||||
style={{ position: 'absolute', bottom: 0, right: -4 }}
|
||||
type="text"
|
||||
icon={
|
||||
<EllipsisOutlined style={{ color: '#fff', fontSize: 24, transform: 'rotate(90deg)' }} />
|
||||
}
|
||||
onClick={handleButtonClick}
|
||||
/>
|
||||
</Popover>
|
||||
{/* {involved.state && (
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
right: 0,
|
||||
width: 64,
|
||||
height: 24,
|
||||
background: '#FAAD14',
|
||||
borderRadius: '0px 4px 0px 4px',
|
||||
color: '#FFF',
|
||||
fontSize: 12,
|
||||
textAlign: 'center',
|
||||
lineHeight: '24px'
|
||||
}}
|
||||
>
|
||||
重点关注
|
||||
</div>
|
||||
)} */}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageWithPopover;
|
@ -1,26 +0,0 @@
|
||||
.InvolvedImgBox {
|
||||
box-sizing: border-box;
|
||||
// display: flex;
|
||||
// justify-content: flex-start;
|
||||
padding: 16px 32px;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
.involvedImgList {
|
||||
position: relative;
|
||||
span {
|
||||
position: absolute;
|
||||
bottom: -30px;
|
||||
left: 15px;
|
||||
width: 2px;
|
||||
height: 30px;
|
||||
border-left: 2px dashed #081fa8;
|
||||
}
|
||||
}
|
||||
}
|
||||
.myButtonDisabled {
|
||||
visibility: hidden;
|
||||
}
|
||||
.involvedModalForm {
|
||||
.ant-modal .ant-modal-content {
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
@ -1,318 +0,0 @@
|
||||
import { getInvolvedTravelList, postRecognition } from '@/services/realTime/involved';
|
||||
import { CloseCircleOutlined, EllipsisOutlined } from '@ant-design/icons';
|
||||
import { ModalForm } from '@ant-design/pro-components';
|
||||
import { useIntl } from '@umijs/max';
|
||||
import { Button, Form, Image, List, Popover, message } from 'antd';
|
||||
import moment from 'moment';
|
||||
import VirtualList from 'rc-virtual-list';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import trajectoryBottom from '../../../../../public/images/involved/trajectoryBottom.png';
|
||||
import './InvolvedDetails.less';
|
||||
import styles from './InvolvedDetails.less';
|
||||
export type FormValueType = {
|
||||
target?: string;
|
||||
template?: string;
|
||||
type?: string;
|
||||
time?: string;
|
||||
frequency?: string;
|
||||
} & Partial<API.InvolvedDetailsParams>;
|
||||
|
||||
export type UpdateFormProps = {
|
||||
updateModalOpen: boolean;
|
||||
handleModal: () => void;
|
||||
values: Partial<API.InvolvedDetailsParams>;
|
||||
reload: any;
|
||||
};
|
||||
const InvolvedDetails: React.FC<UpdateFormProps> = (props) => {
|
||||
const intl = useIntl();
|
||||
const [form] = Form.useForm<API.InvolvedDetailsParams>();
|
||||
const [dataFlag, setDataFlag] = useState(false);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [trajectoryData, setTrajectoryData] = useState([]);
|
||||
// 动态设置每页数量
|
||||
const [currentPageSize, setCurrentPageSize] = useState<number>(10);
|
||||
const [currentPage, setCurrentPage] = useState<number>(1);
|
||||
const [total, setTotal] = useState<number>(0);
|
||||
const ContainerHeight = 630;
|
||||
const content = (
|
||||
<div
|
||||
style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}
|
||||
>
|
||||
{/* <div>选项1</div>
|
||||
<div>选项2</div> */}
|
||||
<Button
|
||||
type="text"
|
||||
style={{ height: 22, padding: 0, fontSize: 12, color: '#FFF' }}
|
||||
icon={<CloseCircleOutlined style={{ color: '#E80D0D', fontSize: 12 }} />}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
postRecognition({
|
||||
person_id: props.values.person_id,
|
||||
classify: '0',
|
||||
})
|
||||
.then(() => {
|
||||
message.success('此人已被移除重点关注');
|
||||
props.reload();
|
||||
})
|
||||
.catch(() => {
|
||||
message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
|
||||
});
|
||||
setOpen(false);
|
||||
props.handleModal();
|
||||
}}
|
||||
>
|
||||
移除重点关注
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
const handleOpenChange = (value: boolean) => {
|
||||
setOpen(value);
|
||||
};
|
||||
|
||||
const appendData = (page: any, pageSize: any) => {
|
||||
const reqParams = {
|
||||
page: page,
|
||||
pageSize: pageSize,
|
||||
// desc: false,
|
||||
person_id: props.values.person_id,
|
||||
// ...rest,
|
||||
};
|
||||
getInvolvedTravelList(reqParams)
|
||||
.then((res) => {
|
||||
console.log(res);
|
||||
if (res.data.results) {
|
||||
setTrajectoryData(trajectoryData.concat(res.data.results));
|
||||
setTotal(res.data.count);
|
||||
if (res.data.next) {
|
||||
setDataFlag(true);
|
||||
} else {
|
||||
setDataFlag(false);
|
||||
// setTrajectoryData([]); // 重置trajectoryData数据为空数组
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// setLoading(false);
|
||||
setDataFlag(false);
|
||||
// setTrajectoryData([]); // 重置trajectoryData数据为空数组
|
||||
});
|
||||
};
|
||||
const onScroll = (e: React.UIEvent<HTMLElement, UIEvent>) => {
|
||||
// Refer to: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#problems_and_solutions
|
||||
console.log(e.currentTarget.scrollHeight - e.currentTarget.scrollTop - ContainerHeight);
|
||||
|
||||
if (Math.abs(e.currentTarget.scrollHeight - e.currentTarget.scrollTop - ContainerHeight) <= 1) {
|
||||
if (dataFlag) {
|
||||
const nextPage = currentPage + 1;
|
||||
setCurrentPage(nextPage);
|
||||
appendData(nextPage, 10);
|
||||
}
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
if (props.updateModalOpen) {
|
||||
// 调用接口获取数据
|
||||
setTrajectoryData([]); // 重置trajectoryData数据为空数组
|
||||
setCurrentPage(1);
|
||||
setCurrentPageSize(10);
|
||||
appendData(currentPage, currentPageSize);
|
||||
}
|
||||
}, [props.updateModalOpen]);
|
||||
return (
|
||||
<ModalForm<any>
|
||||
width={615}
|
||||
title={
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
padding: '24px 32px 0px',
|
||||
justifyContent: 'flex-start',
|
||||
}}
|
||||
>
|
||||
<div style={{ position: 'relative', boxSizing: 'border-box', width: 120, height: 120 }}>
|
||||
<Image
|
||||
style={{ borderRadius: 4 }}
|
||||
width={120}
|
||||
height={120}
|
||||
preview={false}
|
||||
src={props?.values?.picture_path}
|
||||
/>
|
||||
<Popover
|
||||
placement="right"
|
||||
content={content}
|
||||
trigger="click"
|
||||
style={{ width: 104, height: 32 }}
|
||||
color="rgba(0, 0, 0, 0.6)"
|
||||
overlayInnerStyle={{ width: 104, height: 32, padding: 4, borderRadius: 2 }}
|
||||
open={open}
|
||||
onOpenChange={handleOpenChange}
|
||||
>
|
||||
<Button
|
||||
style={{ position: 'absolute', bottom: 0, right: -4 }}
|
||||
type="text"
|
||||
icon={
|
||||
<EllipsisOutlined
|
||||
style={{ color: '#fff', fontSize: 24, transform: 'rotate(90deg)' }}
|
||||
/>
|
||||
}
|
||||
// onClick={handleButtonClick}
|
||||
/>
|
||||
</Popover>
|
||||
<div
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
right: 0,
|
||||
width: 64,
|
||||
height: 24,
|
||||
background: '#FAAD14',
|
||||
borderRadius: '0px 4px 0px 4px',
|
||||
color: '#FFF',
|
||||
fontSize: 12,
|
||||
textAlign: 'center',
|
||||
lineHeight: '24px',
|
||||
fontWeight: 400,
|
||||
}}
|
||||
>
|
||||
重点关注
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
marginLeft: 12,
|
||||
height: 98,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'space-between',
|
||||
color: '#666',
|
||||
fontSize: 14,
|
||||
fontWeight: 400,
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
关注时间:{' '}
|
||||
<span
|
||||
style={{
|
||||
color: '#333',
|
||||
}}
|
||||
>
|
||||
{moment(props?.values?.classify_time).format('YYYY-MM-DD hh:mm:ss')}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
最近发现:{' '}
|
||||
<span
|
||||
style={{
|
||||
color: '#333',
|
||||
}}
|
||||
>
|
||||
{moment(props?.values?.appear_time).format('YYYY-MM-DD hh:mm:ss')}
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
来源设备:{' '}
|
||||
<span
|
||||
style={{
|
||||
color: '#333',
|
||||
}}
|
||||
>
|
||||
{props?.values?.device_name}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
open={props.updateModalOpen}
|
||||
form={form}
|
||||
autoFocusFirstInput
|
||||
modalProps={{
|
||||
destroyOnClose: true,
|
||||
onCancel: () => {
|
||||
setTrajectoryData([]);
|
||||
setCurrentPage(1);
|
||||
setCurrentPageSize(10);
|
||||
props.handleModal();
|
||||
},
|
||||
wrapClassName: 'involvedModalForm',
|
||||
}}
|
||||
submitter={false}
|
||||
submitTimeout={2000}
|
||||
onFinish={async (values) => {
|
||||
values.is_ignore = true;
|
||||
values.person_id = props.values.person_id;
|
||||
// console.log(values);
|
||||
// postIgnoringvents(values)
|
||||
// .then(() => {
|
||||
// message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '成功' }));
|
||||
// props.reload();
|
||||
// })
|
||||
// .catch(() => {
|
||||
// message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '失败' }));
|
||||
// });
|
||||
setTrajectoryData([]);
|
||||
setCurrentPage(1);
|
||||
setCurrentPageSize(10);
|
||||
props.handleModal();
|
||||
return true;
|
||||
}}
|
||||
>
|
||||
{/* <ProForm.Group> */}
|
||||
{/* <div className={styles.alarmDetails}>
|
||||
告警名称: <span className={styles.alarmSpan}>单人徘徊告警</span>来源设备: <span className={styles.alarmSpan}>北广场检票口1#摄像头</span>触发时间: <span className={styles.alarmSpan}>2023-01-15 22:00:03</span>
|
||||
</div> */}
|
||||
<div className={styles.InvolvedImgBox}>
|
||||
<List>
|
||||
<VirtualList
|
||||
data={trajectoryData}
|
||||
height={ContainerHeight}
|
||||
itemHeight={64}
|
||||
itemKey="id"
|
||||
onScroll={onScroll}
|
||||
>
|
||||
{(item: any, index: any) => (
|
||||
<div key={item.person_id + index}>
|
||||
<List.Item style={{ borderBottom: 0, height: 64, padding: 0 }}>
|
||||
<List.Item.Meta
|
||||
avatar={
|
||||
<div className={styles.involvedImgList}>
|
||||
<img style={{ width: 32, height: 32 }} src={trajectoryBottom} />
|
||||
{index + 1 !== total && <span />}
|
||||
</div>
|
||||
}
|
||||
title={
|
||||
<div style={{ lineHeight: '30px', color: '#666' }}>
|
||||
拍摄时间:{' '}
|
||||
<span style={{ color: '#333', marginRight: 16 }}>
|
||||
{moment(item.appear_time).format('YYYY-MM-DD hh:mm:ss')}
|
||||
</span>{' '}
|
||||
来源设备: <span style={{ color: '#333' }}>{item.device_name}</span>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
<div>
|
||||
<Image
|
||||
style={{ borderRadius: 4 }}
|
||||
width={48}
|
||||
height={48}
|
||||
preview={{
|
||||
mask: '',
|
||||
}}
|
||||
src={item.picture_path}
|
||||
/>
|
||||
</div>
|
||||
</List.Item>
|
||||
{index === total - 1 && (
|
||||
<div style={{ textAlign: 'center', color: '#999' }}>已无更多数据~</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</VirtualList>
|
||||
</List>
|
||||
</div>
|
||||
|
||||
{/* </ProForm.Group> */}
|
||||
</ModalForm>
|
||||
);
|
||||
};
|
||||
export default InvolvedDetails;
|
Loading…
Reference in New Issue