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

@ -51,4 +51,27 @@ export async function saveAppointmentEdit(data: any) {
method: 'POST',
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 {
height: calc(~"100% - 110px - 0.5rem");
width: 100%;
@ -287,7 +310,7 @@
.map-grand {
position: absolute;
right: 4rem;
right: 6%;
bottom: 2rem;
.map-grand-title {
@ -327,7 +350,7 @@
.screen-table {
margin-top: 0.5rem;
height: calc(100% - 36px - 0.5rem);
height: calc(100% - 40px - 0.5rem);
overflow: hidden;
.ant-table-container table>thead>tr:first-child th:first-child {

View File

@ -342,15 +342,17 @@ export default () => {
renderItem={item => (
<List.Item>
<div className="list-card" onClick={() => onCardClick(item)}>
<p className="list-card-title">
<img src={content_title} />
<span>{item.meetingName}</span>
</p>
<p><span className="project-text">{item.projectName}</span></p>
<p>{item.sectionName}</p>
<p>{item.startDate} {item.endDate}</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>
<div>
<p className="list-card-title">
<img src={content_title} />
<span>{item.areaName}</span>
</p>
<p><span className="project-text">{item.projectName}</span></p>
<p>{item.sectionName}</p>
<p>{item.startDate} {item.endDate}</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>
</div>
</div>
</List.Item>
)}

View File

@ -36,6 +36,10 @@
.ant-tooltip-arrow {
display: none;
}
&>.ant-tooltip-content>.ant-tooltip-inner>p {
margin-bottom: 0;
}
}
.top-province-tag {
@ -189,7 +193,7 @@
border-radius: 4px;
border: 1px solid #5c69a1;
cursor: pointer;
padding: 1rem;
padding: 0 0.5rem;
&:hover {
border-color: #fff;
@ -215,16 +219,24 @@
justify-content: space-between;
}
&>p {
font-size: 1rem;
&>div {
position: relative;
top: 50%;
transform: translateY(-50%);
}
&>div>p {
margin-bottom: 0.5rem;
color: #fff;
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
&:last-child {
margin-bottom: 0.25rem;
margin-bottom: 0;
}
color: #fff;
.project-text {
color: #2bddf4;
}
@ -254,46 +266,140 @@
}
}
@media screen and (max-height:1080px) {
@media screen and (min-height:1440px) {
.list-card {
height: 36vh;
max-height: 36vh;
padding: 1rem 1.2rem;
height: 41vh;
max-height: 41vh;
padding: 0 2rem;
.list-card-title {
font-size: 1.4rem;
line-height: 1.4rem;
font-size: 1.8rem;
line-height: 1.9rem;
&>img {
height: 1.4rem;
height: 1.8rem;
}
}
&>p {
font-size: 1.1rem;
margin-bottom: 1.625rem;
&>div>p {
font-size: 1.6rem;
line-height: 1.7rem;
margin-bottom: 3.3rem;
}
}
}
@media screen and (max-height:900px) {
@media screen and (max-height:1440px) {
.list-card {
height: 32vh;
max-height: 32vh;
padding: 1rem;
height: 40vh;
max-height: 40vh;
padding: 0 2rem;
.list-card-title {
font-size: 1.2rem;
line-height: 1.2rem;
font-size: 1.8rem;
line-height: 1.9rem;
&>img {
height: 1.2rem;
height: 1.8rem;
}
}
&>p {
&>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) {
.list-card {
height: 36vh;
max-height: 36vh;
padding: 0 1.4rem;
.list-card-title {
font-size: 1.4rem;
line-height: 1.45rem;
&>img {
height: 1.3rem;
}
}
&>div>p {
font-size: 1.2rem;
line-height: 1.3rem;
margin-bottom: 2.1rem;
}
}
}
@media screen and (max-height:900px) and (min-height:720px) {
.list-card {
height: 32vh;
max-height: 32vh;
padding: 0 1rem;
.list-card-title {
font-size: 1.1rem;
line-height: 1.15rem;
&>img {
height: 1.1rem;
}
}
&>div>p {
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,
onCell,
onHeaderCell,
render: (_: any, record: any) => `${record.details[0].thresholdOfPeople}`,
render: (_: any, record: any) => `${record.details?.[0].thresholdOfPeople}`,
},
{
title: '实际人数',
@ -73,7 +73,7 @@ const backPeopleNumColumns: any[] = [
align: 'center',
onCell,
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) {
if (ite.userType == "manager") {//项目经理
data["manager"] = ite.userNumber;
} else if (ite.userType == "purchase_expert") {//专家-招标人代表
} else if (ite.userType == "purchaseExpert") {//专家-招标人代表
data["purchaseExpert"] = ite.userNumber;
} else if (ite.userType == "expert") {//专家
data["expert"] = ite.userNumber;
@ -313,7 +313,7 @@ export default (props: any) => {
<Col span={18}>
<div className="answer-supplier">
<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>
</Tooltip>
</div>
@ -350,7 +350,7 @@ export default (props: any) => {
<p>{item.createDate}</p>
</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>
))
@ -361,7 +361,7 @@ export default (props: any) => {
<p>{item.describeStranger}</p>
</div>
<div>
<Image src={pictureDisplayPath + "?filePath=" + item.filePath} height={"100%"} />
<Image src={pictureDisplayPath + "?filePath=" + item.filePath} preview={false} height={"100%"} />
</div>
</div>
))}
@ -372,7 +372,7 @@ export default (props: any) => {
className="screen-table"
rowKey="id"
size="small"
dataSource={basicInfo?.status == "2" ? backNumberList?.[0].details : earlyWarnData?.numberDetails}
dataSource={basicInfo?.status == "2" ? backNumberList : earlyWarnData?.numberDetails}
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) {
.left-monitor,
.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,
.right-warn-list {
@ -111,6 +135,14 @@
}
}
@media screen and (max-height:720px) {
.left-monitor,
.right-warn-list {
height: 66vh;
}
}
.left-monitor {
border: 1px solid #fff;
margin-right: 4px;

View File

@ -1,55 +1,57 @@
import React, { useEffect,useState } from 'react';
import { Tabs,Collapse,Form, Input, Modal,Col,Row,Divider, Table, Button, Empty ,message,Spin,Card,} from 'antd';
import {saveUpdateEvalRoom} from '../service';
import {} from '@/utils/CommonUtils'
import React, { useEffect, useState } from 'react';
import { Tabs, Collapse, Form, Input, Modal, Col, Row, Divider, Table, Button, Empty, message, Spin, Card, } from 'antd';
import { saveUpdateEvalRoom } from '../service';
import { } from '@/utils/CommonUtils'
import ProTable, { ProColumns } from "@ant-design/pro-table";
import { getProMethod, getRoomId, getSessionRoleData } from '@/utils/session';
import ExtendUpload from "@/utils/ExtendUpload";
import ScreenWarnBack from '@/components/ElecBidEvaluation/ScreenWarnBack';
interface alarmDataObj {
tilte:string;//标题
id:string;//告警id
reserveId:string;//预约id
tpName:string;//项目名称
tpNumber:string;//项目编号
bsName:string;//标段名称
placeName:string; //评标室名称
startDate:string; //开始时间
endDate:string; //结束时间
status:string;//处理状态0未处理1已处理',
roomStatus:string;//评标室状态 0-未开启 1-进行中 2-已结束
pNumber:string;//人数信息
remark:string;//处理说明
attachment:string;//附件id
tilte: string;//标题
id: string;//告警id
reserveId: string;//预约id
tpName: string;//项目名称
tpNumber: string;//项目编号
bsName: string;//标段名称
placeName: string; //评标室名称
startDate: string; //开始时间
endDate: string; //结束时间
status: string;//处理状态0未处理1已处理',
roomStatus: string;//评标室状态 0-未开启 1-进行中 2-已结束
pNumber: string;//人数信息
remark: string;//处理说明
attachment: string;//附件id
}
interface ViewEvalAlarmUpdateModalProps {
alarmData: alarmDataObj;
detail:boolean;
isLookType:boolean;
onCancel:any;
onOk:any;
detail: boolean;
isLookType: boolean;
onCancel: any;
onOk: any;
}
const ViewEvalAlarmUpdateModal: React.FC<ViewEvalAlarmUpdateModalProps> = (props) => {
const {alarmData,detail,isLookType,onCancel,onOk}= props;
const { alarmData, detail, isLookType, onCancel, onOk } = props;
const { TextArea } = Input;//文本域
const [orderSpin, orderSpinSet] = useState<boolean>(false);//订单页加载中
const [uploadProps, setUploadProps] = useState<any>(false);
const [detailModalVisible, setDetailModalVisible] = useState<boolean>(false);//详情弹窗
const [form] = Form.useForm();
var roleId = getSessionRoleData().roleCode;
useEffect(() => {
setUploadProps(alarmData.status=="1"||isLookType);
},[])
setUploadProps(alarmData.status == "1" || isLookType);
}, [])
const saveUpdate = async () =>{
const saveUpdate = async () => {
orderSpinSet(true);
form.validateFields().then(res => {
console.log( form.getFieldValue("remark"));
console.log(form.getFieldValue("remark"));
const fromData = {
id: alarmData.id,
remark: form.getFieldValue("remark"),
@ -70,15 +72,15 @@ const ViewEvalAlarmUpdateModal: React.FC<ViewEvalAlarmUpdateModalProps> = (props
}
//0-未开启 1-进行中 2-已结束
function getStautsValue(key:any){
function getStautsValue(key: any) {
let val = "";
//setUploadProps(false);
if(key=="0"){
if (key == "0") {
val = "未开启"
}else if(key=="1"){
} else if (key == "1") {
val = "正在评标"
//setUploadProps(true);
}else if(key=="2"){
} else if (key == "2") {
val = "已结束"
}
return val;
@ -90,9 +92,9 @@ const ViewEvalAlarmUpdateModal: React.FC<ViewEvalAlarmUpdateModalProps> = (props
visible={detail}
width={"1000px"}
centered
title={"异常信息:"+alarmData.tilte}//+alarmData.tilte
title={"异常信息:" + alarmData.tilte}//+alarmData.tilte
onCancel={() => { onCancel(); }}
onOk={() => {onOk();}}
onOk={() => { onOk(); }}
bodyStyle={{ maxHeight: "500px", overflow: "auto", zIndex: 1 }}
footer={[
<Button key="back" onClick={() => {
@ -126,31 +128,32 @@ const ViewEvalAlarmUpdateModal: React.FC<ViewEvalAlarmUpdateModalProps> = (props
<Col span={12}><Form.Item label="评标状态">{getStautsValue(alarmData.roomStatus)}</Form.Item></Col>
<Col span={12}></Col>
</Row>
<Row hidden={alarmData.pNumber==null||alarmData.pNumber==""}>
<Row hidden={alarmData.pNumber == null || alarmData.pNumber == ""}>
<Col span={2}></Col>
<Col span={16}>{(alarmData.pNumber)}</Col>
</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>
</Row>
<Row>
<Col span={12}><Form.Item label="处理说明" name="remark">{isLookType?alarmData.remark:
<TextArea rows={4} style={{ resize: 'vertical' }} placeholder="请填写备注" value={alarmData.remark} />}</Form.Item></Col>
<Col span={12}><Form.Item label="处理说明" name="remark">{isLookType ? alarmData.remark :
<TextArea rows={4} style={{ resize: 'vertical' }} placeholder="请填写备注" value={alarmData.remark} />}</Form.Item></Col>
</Row>
<Row>
<Col span={12}><Form.Item label="附件" name="attachment">
<ExtendUpload bid={alarmData.attachment} uploadProps={{ disabled: uploadProps }}>
</ExtendUpload>
</Form.Item></Col>
<ExtendUpload bid={alarmData.attachment} uploadProps={{ disabled: uploadProps }}>
</ExtendUpload>
</Form.Item></Col>
<Col span={12}></Col>
</Row>
</Form>
</Card>
</Spin>
</Modal>
)
)
{detailModalVisible && <ScreenWarnBack modalVisible={detailModalVisible} onCancel={() => setDetailModalVisible(false)} warnId={alarmData.id} />}
</>
);
};