9.7 大屏修改

This commit is contained in:
jl-zhoujl2
2022-09-07 08:28:12 +08:00
parent 424711f3c6
commit b98142f7fc
13 changed files with 631 additions and 162 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -0,0 +1,165 @@
import React, { useEffect, useRef, useState } from 'react';
import { Card, List, Modal, Typography, Image, Radio, Table } from 'antd';
import ProCard from '@ant-design/pro-card';
import { getCameraList, getWarnDetailData } from './service';
import ScreenVideoPlay from './ScreenVideoPlay';
import { pictureDisplayPath } from '@/utils/DownloadUtils';
import moment from 'moment';
interface ScreenWarnBackProps {
modalVisible: boolean;
onCancel: () => void;
warnId: string;//告警id
}
const modalHeight = window.innerHeight * 96 / 100;
/**
* 异常告警详情回放
* @param props
* @returns
*/
const ScreenWarnBack: React.FC<ScreenWarnBackProps> = (props) => {
const { modalVisible, onCancel, warnId } = props;
const { Title } = Typography;
//详情信息
const [detailData, setDetailData] = useState<any>();
//设备列表
const [caremaList, setCaremaList] = useState<any[]>([]);
//当前选择的设备
const [cameraSelect, setCameraSelect] = useState<string>("1");
//当前播放的设备参数
const [cameraParams, setCameraParams] = useState<any>();
//监控视频Ref
const videoRef = useRef<any>();
const peopleNumColumns: any[] = [
{
title: '时间',
dataIndex: 'eventTime',
key: 'eventTime',
align: 'center',
width: "40%",
},
{
title: '阈值',
dataIndex: 'thresholdOfPeople',
key: 'thresholdOfPeople',
align: 'center',
ellipsis: true,
render: (_: any, record: any) => `${_}`,
},
{
title: '实际人数',
dataIndex: 'realOfPeople',
key: 'realOfPeople',
align: 'center',
render: (_: any, record: any) => `${_}`,
},
];
//回放
const videoBack = (deviceCode: any, data: any) => {
let backTime = 20;
if (data.type == "2") {//人数预警
backTime = 10;
}
videoRef.current?.back(deviceCode, moment(data?.createDate).subtract(backTime, 'm').format('yyyy-MM-DD HH:mm:ss'), data?.createDate);
}
//获取告警详情数据
const getWarnDetail = () => {
getWarnDetailData({ id: warnId }).then(res => {
if (res?.code == 200) {
const data = res?.data;
setDetailData(data);
getCaremaData(data);
}
})
}
//获取设备
const getCaremaData = (baseData: any) => {
getCameraList({ areaId: baseData.placeId }).then(res => {
if (res?.code == 200) {
const data = res?.data;
setCaremaList(data);
if (data?.length > 0) {
//获取回看时间
setCameraSelect(data[0].deviceCode);
setCameraParams(data[0].platform);
setTimeout(() => {
videoBack(data[0].deviceCode, baseData);
}, 4000);
}
}
})
}
//切换设备
const onCaremaChange = (e: any) => {
const caremaCode = e.target.value;
for (const ite of caremaList) {
if (ite.deviceCode == caremaCode) {
setCameraSelect(caremaCode);
setCameraParams(ite.platform);
videoBack(caremaCode, detailData);
}
}
}
useEffect(() => {
warnId && getWarnDetail();
}, [warnId])
return (
<Modal
destroyOnClose
title="告警详情"
visible={modalVisible}
onCancel={() => onCancel()}
okButtonProps={{ hidden: true }}
width={"80%"}
maskClosable={false}
style={{ maxHeight: modalHeight }}
bodyStyle={{ height: modalHeight - 107, overflowY: 'auto', padding: 0 }}
centered
>
<ProCard split="vertical" bodyStyle={{ height: "calc(100vh - 136px)" }}>
<ProCard colSpan={7} key="0" bodyStyle={{ padding: "16px", overflowY: 'auto', height: "calc(100vh - 136px)" }}>
<Title level={5} style={{ marginBottom: '8px', color: "#b30000" }}>{detailData?.type == "3" ? "陌生人进入" : "人数异常"}</Title>
{detailData?.type == "3" ? (
<List
grid={{ column: 1 }}
dataSource={detailData?.details}
renderItem={(item: any) => (
<List.Item>
<Card bodyStyle={{ padding: "8px" }}>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<Typography>{item.eventTime}</Typography>
<Image src={pictureDisplayPath + "?filePath=" + item.filePath} preview={false} height="70px" />
</div>
</Card>
</List.Item>
)}
/>
) : (
<Table
pagination={false}
rowKey="id"
size="small"
dataSource={detailData?.details}
columns={peopleNumColumns}
/>
)}
</ProCard>
<ProCard colSpan={17} key="1" bodyStyle={{ padding: "16px" }}>
<Radio.Group value={cameraSelect} buttonStyle="solid" style={{ marginBottom: "8px" }} onChange={onCaremaChange}>
{caremaList.map(item => (<Radio.Button value={item.deviceCode} key={item.deviceCode}>{item.deviceName}</Radio.Button>))}
</Radio.Group>
<div style={{ height: "94%", border: '1px solid red' }}>
{cameraParams && <ScreenVideoPlay videoRef={videoRef} cameraParams={cameraParams} status={1} />}
</div>
</ProCard>
</ProCard>
</Modal>
);
};
export default ScreenWarnBack;

View File

@ -52,3 +52,26 @@ export async function saveAppointmentEdit(data: any) {
data: { ...data, }, data: { ...data, },
}); });
} }
/**
* 根据告警id查询告警详情
* @param params
*/
export async function getWarnDetailData(params: any) {
return request('/api/biz-service-ebtp-evaluation/v1/eval/room/alarm/get', {
method: 'POST',
params: params,
});
}
/**
* 设备列表
* @param params
* @returns
*/
export async function getCameraList(params: any) {
return request('/api/biz-service-ebtp-evaluation/v1/screen/queryAreaCamera', {
method: 'GET',
params: params,
});
}

File diff suppressed because one or more lines are too long

View File

@ -180,6 +180,29 @@
} }
} }
.card-project-default {
height: calc(~"(100vh - 177px - 3rem) / 3");
background-repeat: no-repeat;
background-size: 100% 100%;
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
display: flex;
justify-content: center;
align-items: center;
&>img {
height: 40%;
}
}
.card-default-01 {
background-image: url('@{screen-img-url}/default_pic01.jpg');
}
.card-default-02 {
background-image: url('@{screen-img-url}/default_pic02.jpg');
}
.card-carema-c { .card-carema-c {
height: calc(~"100% - 110px - 0.5rem"); height: calc(~"100% - 110px - 0.5rem");
width: 100%; width: 100%;
@ -287,7 +310,7 @@
.map-grand { .map-grand {
position: absolute; position: absolute;
right: 4rem; right: 6%;
bottom: 2rem; bottom: 2rem;
.map-grand-title { .map-grand-title {
@ -327,7 +350,7 @@
.screen-table { .screen-table {
margin-top: 0.5rem; margin-top: 0.5rem;
height: calc(100% - 36px - 0.5rem); height: calc(100% - 40px - 0.5rem);
overflow: hidden; overflow: hidden;
.ant-table-container table>thead>tr:first-child th:first-child { .ant-table-container table>thead>tr:first-child th:first-child {

View File

@ -342,9 +342,10 @@ export default () => {
renderItem={item => ( renderItem={item => (
<List.Item> <List.Item>
<div className="list-card" onClick={() => onCardClick(item)}> <div className="list-card" onClick={() => onCardClick(item)}>
<div>
<p className="list-card-title"> <p className="list-card-title">
<img src={content_title} /> <img src={content_title} />
<span>{item.meetingName}</span> <span>{item.areaName}</span>
</p> </p>
<p><span className="project-text">{item.projectName}</span></p> <p><span className="project-text">{item.projectName}</span></p>
<p>{item.sectionName}</p> <p>{item.sectionName}</p>
@ -352,6 +353,7 @@ export default () => {
<p className="space-between"><span>{item.expertNumber}</span><span>{proviceEnum[item.provinceDictId]}</span></p> <p className="space-between"><span>{item.expertNumber}</span><span>{proviceEnum[item.provinceDictId]}</span></p>
<p className="space-between"><span><span className={statusColorMap[item.status]}>{bidStatusMap[item.status]}</span></span>{item.isAbnormal == "1" && <span className="error-text"></span>}</p> <p className="space-between"><span><span className={statusColorMap[item.status]}>{bidStatusMap[item.status]}</span></span>{item.isAbnormal == "1" && <span className="error-text"></span>}</p>
</div> </div>
</div>
</List.Item> </List.Item>
)} )}
/> />

View File

@ -36,6 +36,10 @@
.ant-tooltip-arrow { .ant-tooltip-arrow {
display: none; display: none;
} }
&>.ant-tooltip-content>.ant-tooltip-inner>p {
margin-bottom: 0;
}
} }
.top-province-tag { .top-province-tag {
@ -189,7 +193,7 @@
border-radius: 4px; border-radius: 4px;
border: 1px solid #5c69a1; border: 1px solid #5c69a1;
cursor: pointer; cursor: pointer;
padding: 1rem; padding: 0 0.5rem;
&:hover { &:hover {
border-color: #fff; border-color: #fff;
@ -215,15 +219,23 @@
justify-content: space-between; justify-content: space-between;
} }
&>p { &>div {
font-size: 1rem; position: relative;
margin-bottom: 0.5rem; top: 50%;
transform: translateY(-50%);
&:last-child {
margin-bottom: 0.25rem;
} }
&>div>p {
margin-bottom: 0.5rem;
color: #fff; color: #fff;
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
&:last-child {
margin-bottom: 0;
}
.project-text { .project-text {
color: #2bddf4; color: #2bddf4;
@ -254,46 +266,140 @@
} }
} }
@media screen and (min-height:1440px) {
.list-card {
height: 41vh;
max-height: 41vh;
padding: 0 2rem;
.list-card-title {
font-size: 1.8rem;
line-height: 1.9rem;
&>img {
height: 1.8rem;
}
}
&>div>p {
font-size: 1.6rem;
line-height: 1.7rem;
margin-bottom: 3.3rem;
}
}
}
@media screen and (max-height:1440px) {
.list-card {
height: 40vh;
max-height: 40vh;
padding: 0 2rem;
.list-card-title {
font-size: 1.8rem;
line-height: 1.9rem;
&>img {
height: 1.8rem;
}
}
&>div>p {
font-size: 1.6rem;
line-height: 1.7rem;
margin-bottom: 3.3rem;
}
}
}
@media screen and (max-height:1260px) {
.list-card {
height: 38vh;
max-height: 38vh;
padding: 0 1.8rem;
.list-card-title {
font-size: 1.6rem;
line-height: 1.7rem;
&>img {
height: 1.6rem;
}
}
&>div>p {
font-size: 1.4rem;
line-height: 1.5rem;
margin-bottom: 2.8rem;
}
}
}
@media screen and (max-height:1080px) { @media screen and (max-height:1080px) {
.list-card { .list-card {
height: 36vh; height: 36vh;
max-height: 36vh; max-height: 36vh;
padding: 1rem 1.2rem; padding: 0 1.4rem;
.list-card-title { .list-card-title {
font-size: 1.4rem; font-size: 1.4rem;
line-height: 1.4rem; line-height: 1.45rem;
&>img { &>img {
height: 1.4rem; height: 1.3rem;
} }
} }
&>p { &>div>p {
font-size: 1.1rem; font-size: 1.2rem;
margin-bottom: 1.625rem; line-height: 1.3rem;
margin-bottom: 2.1rem;
} }
} }
} }
@media screen and (max-height:900px) { @media screen and (max-height:900px) and (min-height:720px) {
.list-card { .list-card {
height: 32vh; height: 32vh;
max-height: 32vh; max-height: 32vh;
padding: 1rem; padding: 0 1rem;
.list-card-title { .list-card-title {
font-size: 1.2rem; font-size: 1.1rem;
line-height: 1.2rem; line-height: 1.15rem;
&>img { &>img {
height: 1.2rem; height: 1.1rem;
} }
} }
&>p { &>div>p {
font-size: 1rem; font-size: 1rem;
margin-bottom: 0.5rem; line-height: 1.05rem;
margin-bottom: 1.3rem;
}
}
}
@media screen and (max-height:720px) {
.list-card {
height: 30vh;
max-height: 30vh;
padding: 0 0.8rem;
.list-card-title {
font-size: 1rem;
line-height: 1.05rem;
&>img {
height: 1rem;
}
}
&>div>p {
font-size: 0.875rem;
line-height: 0.925rem;
margin-bottom: 0.8rem;
} }
} }
} }

View File

@ -64,7 +64,7 @@ const backPeopleNumColumns: any[] = [
ellipsis: true, ellipsis: true,
onCell, onCell,
onHeaderCell, onHeaderCell,
render: (_: any, record: any) => `${record.details[0].thresholdOfPeople}`, render: (_: any, record: any) => `${record.details?.[0].thresholdOfPeople}`,
}, },
{ {
title: '实际人数', title: '实际人数',
@ -73,7 +73,7 @@ const backPeopleNumColumns: any[] = [
align: 'center', align: 'center',
onCell, onCell,
onHeaderCell, onHeaderCell,
render: (_: any, record: any) => `${record.details[0].realOfPeople}`, render: (_: any, record: any) => `${record.details?.[0].realOfPeople}`,
}, },
]; ];
@ -154,7 +154,7 @@ export default (props: any) => {
for (const ite of data.userNumberList) { for (const ite of data.userNumberList) {
if (ite.userType == "manager") {//项目经理 if (ite.userType == "manager") {//项目经理
data["manager"] = ite.userNumber; data["manager"] = ite.userNumber;
} else if (ite.userType == "purchase_expert") {//专家-招标人代表 } else if (ite.userType == "purchaseExpert") {//专家-招标人代表
data["purchaseExpert"] = ite.userNumber; data["purchaseExpert"] = ite.userNumber;
} else if (ite.userType == "expert") {//专家 } else if (ite.userType == "expert") {//专家
data["expert"] = ite.userNumber; data["expert"] = ite.userNumber;
@ -313,7 +313,7 @@ export default (props: any) => {
<Col span={18}> <Col span={18}>
<div className="answer-supplier"> <div className="answer-supplier">
<span>{basicInfo?.supplierLength}</span> <span>{basicInfo?.supplierLength}</span>
<Tooltip placement="bottomLeft" title={<>{basicInfo?.sectionPayerList?.map((item: any) => <p key={item.sectionName}>{item.sectionName}{item.payerNumber}{item.payerNames.join("、")}</p>)}</>} visible={visible} color="rgba(4,20,47,0.85)" overlayInnerStyle={{ width: '250%' }} overlayClassName="screen-tag"> <Tooltip placement="topLeft" title={<>{basicInfo?.sectionPayerList?.map((item: any) => <p key={item.sectionName}>{item.sectionName}{item.payerNumber}{item.payerNames.join("、")}</p>)}</>} visible={visible} color="rgba(4,20,47,0.85)" overlayInnerStyle={{ width: '250%' }} overlayClassName="screen-tag">
<span>{basicInfo?.sectionPayerList?.[0]?.payerNames.slice(0, 5).join("、")}<a onMouseEnter={() => setVisible(true)} onMouseLeave={() => setVisible(false)}></a></span> <span>{basicInfo?.sectionPayerList?.[0]?.payerNames.slice(0, 5).join("、")}<a onMouseEnter={() => setVisible(true)} onMouseLeave={() => setVisible(false)}></a></span>
</Tooltip> </Tooltip>
</div> </div>
@ -350,7 +350,7 @@ export default (props: any) => {
<p>{item.createDate}</p> <p>{item.createDate}</p>
</div> </div>
<div> <div>
<Image src={pictureDisplayPath + "?filePath=" + item.details[0].filePath} height={"100%"} /> <Image src={pictureDisplayPath + "?filePath=" + item.details[0].filePath} preview={false} height={"100%"} />
</div> </div>
</div> </div>
)) ))
@ -361,7 +361,7 @@ export default (props: any) => {
<p>{item.describeStranger}</p> <p>{item.describeStranger}</p>
</div> </div>
<div> <div>
<Image src={pictureDisplayPath + "?filePath=" + item.filePath} height={"100%"} /> <Image src={pictureDisplayPath + "?filePath=" + item.filePath} preview={false} height={"100%"} />
</div> </div>
</div> </div>
))} ))}
@ -372,7 +372,7 @@ export default (props: any) => {
className="screen-table" className="screen-table"
rowKey="id" rowKey="id"
size="small" size="small"
dataSource={basicInfo?.status == "2" ? backNumberList?.[0].details : earlyWarnData?.numberDetails} dataSource={basicInfo?.status == "2" ? backNumberList : earlyWarnData?.numberDetails}
columns={basicInfo?.status == "2" ? backPeopleNumColumns : peopleNumColumns} columns={basicInfo?.status == "2" ? backPeopleNumColumns : peopleNumColumns}
/> />
) : ( ) : (

View File

@ -95,15 +95,39 @@
} }
} }
@media screen and (min-height:1440px) {
.left-monitor,
.right-warn-list {
height: 84vh;
}
}
@media screen and (max-height:1440px) {
.left-monitor,
.right-warn-list {
height: 83vh;
}
}
@media screen and (max-height:1260px) {
.left-monitor,
.right-warn-list {
height: 80.2vh;
}
}
@media screen and (max-height:1080px) { @media screen and (max-height:1080px) {
.left-monitor, .left-monitor,
.right-warn-list { .right-warn-list {
height: 77vh; height: 76vh;
} }
} }
@media screen and (max-height:900px) { @media screen and (max-height:900px) and (min-height:720px) {
.left-monitor, .left-monitor,
.right-warn-list { .right-warn-list {
@ -111,6 +135,14 @@
} }
} }
@media screen and (max-height:720px) {
.left-monitor,
.right-warn-list {
height: 66vh;
}
}
.left-monitor { .left-monitor {
border: 1px solid #fff; border: 1px solid #fff;
margin-right: 4px; margin-right: 4px;

View File

@ -1,10 +1,11 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Tabs, Collapse, Form, Input, Modal, Col, Row, Divider, Table, Button, Empty, message, Spin, Card, } from 'antd'; import { Tabs, Collapse, Form, Input, Modal, Col, Row, Divider, Table, Button, Empty, message, Spin, Card, } from 'antd';
import { saveUpdateEvalRoom } from '../service'; import { saveUpdateEvalRoom } from '../service';
import {} from '@/utils/CommonUtils' import { } from '@/utils/CommonUtils'
import ProTable, { ProColumns } from "@ant-design/pro-table"; import ProTable, { ProColumns } from "@ant-design/pro-table";
import { getProMethod, getRoomId, getSessionRoleData } from '@/utils/session'; import { getProMethod, getRoomId, getSessionRoleData } from '@/utils/session';
import ExtendUpload from "@/utils/ExtendUpload"; import ExtendUpload from "@/utils/ExtendUpload";
import ScreenWarnBack from '@/components/ElecBidEvaluation/ScreenWarnBack';
interface alarmDataObj { interface alarmDataObj {
tilte: string;//标题 tilte: string;//标题
@ -39,6 +40,7 @@ const ViewEvalAlarmUpdateModal: React.FC<ViewEvalAlarmUpdateModalProps> = (props
const { TextArea } = Input;//文本域 const { TextArea } = Input;//文本域
const [orderSpin, orderSpinSet] = useState<boolean>(false);//订单页加载中 const [orderSpin, orderSpinSet] = useState<boolean>(false);//订单页加载中
const [uploadProps, setUploadProps] = useState<any>(false); const [uploadProps, setUploadProps] = useState<any>(false);
const [detailModalVisible, setDetailModalVisible] = useState<boolean>(false);//详情弹窗
const [form] = Form.useForm(); const [form] = Form.useForm();
var roleId = getSessionRoleData().roleCode; var roleId = getSessionRoleData().roleCode;
@ -131,7 +133,7 @@ const ViewEvalAlarmUpdateModal: React.FC<ViewEvalAlarmUpdateModalProps> = (props
<Col span={16}>{(alarmData.pNumber)}</Col> <Col span={16}>{(alarmData.pNumber)}</Col>
</Row> </Row>
<Row> <Row>
<Col span={12}><Form.Item label="告警详情"><a></a></Form.Item></Col> <Col span={12}><Form.Item label="告警详情"><a onClick={() => setDetailModalVisible(true)}></a></Form.Item></Col>
<Col span={12}></Col> <Col span={12}></Col>
</Row> </Row>
<Row> <Row>
@ -151,6 +153,7 @@ const ViewEvalAlarmUpdateModal: React.FC<ViewEvalAlarmUpdateModalProps> = (props
</Spin> </Spin>
</Modal> </Modal>
) )
{detailModalVisible && <ScreenWarnBack modalVisible={detailModalVisible} onCancel={() => setDetailModalVisible(false)} warnId={alarmData.id} />}
</> </>
); );
}; };