9.14 修改9.9问题

This commit is contained in:
jl-zhoujl2
2022-09-14 10:34:01 +08:00
parent 0c8dfcc992
commit 1e483afbd7
9 changed files with 282 additions and 29 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -225,4 +225,44 @@
.ant-collapse-content>.ant-collapse-content-box {
padding: 16px 0;
}
}
.screen-warn-p {
// .ant-drawer-close {
// color: #fff;
// &:focus,
// &:hover {
// color: #fff;
// }
// }
// .ant-drawer-content {
// background-color: rgba(0, 0, 0, 0.35);
// }
.ant-drawer-body {
text-align: center;
padding: 0;
&>div {
height: 100%;
}
&>div>img {
position: relative;
top: 50%;
transform: translateY(-50%);
-moz-user-select: 'none';
/* Firefox私有属性 */
-webkit-user-select: 'none';
/* WebKit内核私有属性 */
-ms-user-select: 'none';
/* IE私有属性(IE10及以后) */
user-select: 'none';
/* CSS3属性 */
}
}
}

View File

@ -1,8 +1,8 @@
import React, { useEffect, useRef, useState } from 'react';
import { Col, DatePicker, Descriptions, Form, Input, message, Modal, Row, Spin } from 'antd';
import ProTable, { ActionType, ProColumns } from '@ant-design/pro-table';
import { getBidEvalRoom, handleTakeEffectReserve, saveAppointmentEdit } from './service';
import { dateFormat, disabledDate, disabledDateTime, validateMessages } from './MeetingReservation';
import { getBidEvalRoom, getTimeByAreaId, handleTakeEffectReserve, saveAppointmentEdit } from './service';
import { dateFormat, disabledDate, otherDisabledDateTime, validateMessages } from './MeetingReservation';
import moment from 'moment';
import { dateTimeFormatter } from '@/utils/DateUtils';
import { getProId } from '@/utils/session';
@ -65,6 +65,8 @@ const BidEvalAppointment: React.FC<BidEvalAppointmentProps> = (props) => {
const [selectedRecord, setSelectedRecord] = useState<any>();
//loading
const [loading, setLoading] = useState<boolean>(false);
//不可选择日期
const [disabledMap, setDisabledMap] = useState<any>({});
const columns: ProColumns<any>[] = [
{
valueType: 'index',
@ -172,12 +174,26 @@ const BidEvalAppointment: React.FC<BidEvalAppointmentProps> = (props) => {
}
})
}
//获取不可选择时间
const getDisabledTime = (rowKeys: any[]) => {
getTimeByAreaId(rowKeys[0]).then(res => {
if (res?.code == 200) {
const data = res?.data;
setDisabledMap(data);
}
})
}
useEffect(() => {
setSelectedRowKeys([]);
setSelectedRecord(null);
setDisabledMap({});
}, [values])
useEffect(() => {
selectedRowKeys.length > 0 && getDisabledTime(selectedRowKeys);
}, [selectedRowKeys])
return (
<Modal
destroyOnClose
@ -284,7 +300,7 @@ const BidEvalAppointment: React.FC<BidEvalAppointmentProps> = (props) => {
rules={[{ required: true, message: '请选择' }]}
extra={<span style={{ color: "#b30000" }}> 7:00 ~ 18:00</span>}
>
<DatePicker showTime={{ defaultValue: moment().hour(7) }} showNow={false} disabledDate={disabledDate} disabledTime={disabledDateTime} showMinute={false} showSecond={false} format={dateFormat} style={{ width: '100%' }} />
<DatePicker showTime showNow={false} disabledDate={disabledDate} disabledTime={(current) => otherDisabledDateTime(current, disabledMap)} showMinute={false} showSecond={false} format={dateFormat} style={{ width: '100%' }} renderExtraFooter={() => "注:若时间被占用,则置灰不可选"} />
</Form.Item>
</Col>
<Col span={12}>
@ -293,7 +309,7 @@ const BidEvalAppointment: React.FC<BidEvalAppointmentProps> = (props) => {
name="reserveEndDate"
rules={[{ required: true, message: '请选择' }]}
>
<DatePicker showTime={{ defaultValue: moment().hour(7) }} showNow={false} disabledDate={disabledDate} disabledTime={disabledDateTime} showMinute={false} showSecond={false} format={dateFormat} style={{ width: '100%' }} />
<DatePicker showTime showNow={false} disabledDate={disabledDate} disabledTime={(current) => otherDisabledDateTime(current, disabledMap)} showMinute={false} showSecond={false} format={dateFormat} style={{ width: '100%' }} renderExtraFooter={() => "注:若时间被占用,则置灰不可选"} />
</Form.Item>
</Col>
<Col span={12}>

View File

@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react';
import { Button, DatePicker, DatePickerProps, Form, Input, message, Modal, Select, Skeleton, Spin } from 'antd';
import moment from 'moment'
import { cancelMeeting, getMeetingData, saveMeeting } from './service';
import { cancelMeeting, getMeetingData, saveAppointmentEdit, saveMeeting } from './service';
import { isNotEmpty } from '@/utils/CommonUtils';
import { ExclamationCircleOutlined } from '@ant-design/icons';
import { dateTimeFormatter, echoDateTimeFormatter } from '@/utils/DateUtils';
@ -36,6 +36,20 @@ export function disabledDate(current: any) {
export const disabledDateTime = () => ({
disabledHours: () => [...range(0, 7), ...range(19, 24)],
});
//不可选小时(额外不可选)
export const otherDisabledDateTime = (current: any, disabledMap: any) => {
let otherHour: any[] = range(0, 24);
if (current) {
otherHour = [];
if (Object.keys(disabledMap).length != 0) {
const time = moment(current).format("yyyy-MM-DD");
disabledMap[time] && (otherHour = [...disabledMap[time]]);
}
}
return ({
disabledHours: () => [...range(0, 7), ...range(19, 24), ...otherHour],
})
};
//时间选择框日期格式化
export const dateFormat: DatePickerProps['format'] = value => value?.startOf('hour').format('YYYY-MM-DD HH:mm:ss');
/**
@ -59,9 +73,10 @@ const MeetingReservation: React.FC<MeetingReservationProps> = (props) => {
const [meetType, setMeetType] = useState<string>("meeting");
//会议室预约是否可修改 true-不可修改 false-可修改
const [isEditMeet, setIsEditMeet] = useState<boolean>(false);
//存一份预约数据
const [meetingData, setMeetingData] = useState<any>();
const onFinish = (values: any) => {
console.log(values);
if (values.reserveStartDate < moment().format(dateTimeFormatter)) {
message.info("开始时间不可早于当前时间");
return;
@ -70,14 +85,25 @@ const MeetingReservation: React.FC<MeetingReservationProps> = (props) => {
params.reserveStartDate = moment(params.reserveStartDate).format(dateTimeFormatter);
params.reserveEndDate = moment(params.reserveEndDate).format(dateTimeFormatter);
setLoading(true);
saveMeeting(params).then(res => {
if (res?.code == 200) {
message.success("保存成功");
onSubmit && onSubmit();
}
}).finally(() => {
setLoading(false);
})
if (meetType == "meeting") {//会议室保存
saveMeeting(params).then(res => {
if (res?.code == 200) {
message.success("保存成功");
onSubmit && onSubmit();
}
}).finally(() => {
setLoading(false);
})
} else {
saveAppointmentEdit({ ...meetingData, ...params }).then(res => {//评标室保存
if (res?.code == 200) {
message.success("保存成功");
onSubmit && onSubmit();
}
}).finally(() => {
setLoading(false);
})
}
};
//获取预约信息
@ -87,8 +113,9 @@ const MeetingReservation: React.FC<MeetingReservationProps> = (props) => {
if (res?.code == 200) {
setSkeleing(false);
const data = res?.data;
const isEdit: boolean = data.reserveStartDate <= moment().format(dateTimeFormatter);
const isEdit: boolean = data.reserveType == "meeting" ? data.reserveStartDate <= moment().format(dateTimeFormatter) : data.status != 0;
setIsEditMeet(isEdit);
setMeetingData(data);
setMeetType(data.reserveType);//变更窗口类型
if (data.reserveType == "meeting") {
data.reserveStartDate = echoDateTimeFormatter(data.reserveStartDate);
@ -117,6 +144,16 @@ const MeetingReservation: React.FC<MeetingReservationProps> = (props) => {
onCancel() { },
});
}
const editMeeting = () => {
if (meetType == "eval") {//评标室预约修改
const data = JSON.parse(JSON.stringify(meetingData));//深拷贝
data.reserveStartDate = echoDateTimeFormatter(data.reserveStartDate);
data.reserveEndDate = echoDateTimeFormatter(data.reserveEndDate);
form.setFieldsValue(data);
}
setModalStatus("1");
}
useEffect(() => {
if (isNotEmpty(meetId)) {
getMeetData();
@ -135,10 +172,10 @@ const MeetingReservation: React.FC<MeetingReservationProps> = (props) => {
<Button key="close" onClick={onCancel}>
</Button>,
<Button key="save" type="primary" onClick={() => form.submit()} hidden={meetType == "eval" || meetType == undefined || modalStatus == "2"}>
<Button key="save" type="primary" onClick={() => form.submit()} hidden={meetType == undefined || modalStatus == "2"}>
</Button>,
<Button key="edit" onClick={() => { setModalStatus("1"); }} hidden={meetType == "eval" || meetType == undefined || modalStatus == "1" || modalStatus == "0" || isEditMeet}>
<Button key="edit" onClick={() => editMeeting()} hidden={meetType == undefined || modalStatus == "1" || modalStatus == "0" || isEditMeet}>
</Button>,
<Button type="primary" key="cancel" hidden={modalStatus == "0"} onClick={() => cancelMeet()}>
@ -193,12 +230,25 @@ const MeetingReservation: React.FC<MeetingReservationProps> = (props) => {
<Form.Item name="sectionNames" label="标段名称">
<TextArea readOnly bordered={false} autoSize />
</Form.Item>
<Form.Item name="reserveStartDate" label="预计开始时间">
<Input readOnly bordered={false} />
</Form.Item>
<Form.Item name="reserveEndDate" label="预计结束时间">
<Input readOnly bordered={false} />
</Form.Item>
{modalStatus == "2" ? (
<>
<Form.Item name="reserveStartDate" label="预计开始时间">
<Input readOnly bordered={false} />
</Form.Item>
<Form.Item name="reserveEndDate" label="预计结束时间">
<Input readOnly bordered={false} />
</Form.Item>
</>
) : (
<>
<Form.Item name="reserveStartDate" label="预计开始时间" rules={[{ required: true }]}>
<DatePicker showTime={{ defaultValue: moment().hour(7) }} showNow={false} disabledDate={disabledDate} disabledTime={disabledDateTime} showMinute={false} showSecond={false} format={dateFormat} style={{ width: '100%' }} />
</Form.Item>
<Form.Item name="reserveEndDate" label="预计结束时间" rules={[{ required: true }]}>
<DatePicker showTime={{ defaultValue: moment().hour(7) }} showNow={false} disabledDate={disabledDate} disabledTime={disabledDateTime} showMinute={false} showSecond={false} format={dateFormat} style={{ width: '100%' }} />
</Form.Item>
</>
)}
<Form.Item name="reserveBy" label="预约人">
<Input readOnly bordered={false} />
</Form.Item>

View File

@ -1,5 +1,5 @@
import React, { useEffect, useRef, useState } from 'react';
import { Card, List, Modal, Typography, Image, Radio, Table } from 'antd';
import { Card, List, Modal, Typography, Image, Radio, Table, Drawer } from 'antd';
import ProCard from '@ant-design/pro-card';
import { getCameraList, getWarnDetailData } from './service';
import ScreenVideoPlay from './ScreenVideoPlay';
@ -29,8 +29,14 @@ const ScreenWarnBack: React.FC<ScreenWarnBackProps> = (props) => {
const [cameraSelect, setCameraSelect] = useState<string>("1");
//当前播放的设备参数
const [cameraParams, setCameraParams] = useState<any>();
//图片查看抽屉显隐
const [drawerVisible, setDrawerVisible] = useState<boolean>(false);
//图片查看URL
const [drawerUrl, setDrawerUrl] = useState<string>('');
//监控视频Ref
const videoRef = useRef<any>();
//图片展示ref
const zoomImg = useRef<any>(null);
const peopleNumColumns: any[] = [
{
title: '时间',
@ -104,6 +110,38 @@ const ScreenWarnBack: React.FC<ScreenWarnBackProps> = (props) => {
}
}
//图片放大抽屉显示
const drawerClick = (filePath: string) => {
setDrawerUrl(filePath);
setDrawerVisible(true);
}
//图片放大抽屉关闭
const drawerClose = () => {
setDrawerVisible(false);
setDrawerUrl("");
}
const handleImgZoom = (e: { nativeEvent: { deltaY: number; }; }) => {
const { clientWidth, clientHeight, style, height, width } = zoomImg.current
const value = height / width
const num = 50
const bool = height > width ? clientWidth < 2000 : clientHeight < 1500
if (e.nativeEvent.deltaY <= 0 && bool) {
style.maxWidth = "none"
style.maxHeight = "none"
style.width = width + num + "px"
style.height = height + (num * value) + "px"
style.left = style.left - 1 % +"px"
style.top = style.top - 1 % +"px"
} else if (e.nativeEvent.deltaY > 0) {
if (width > 200 && height > 100) {
style.width = width - num + "px"
style.height = height - (num * value) + "px"
style.left = style.left + 1 % + "px"
style.top = style.top + 1 % + "px"
}
}
}
useEffect(() => {
warnId && getWarnDetail();
}, [warnId])
@ -122,7 +160,7 @@ const ScreenWarnBack: React.FC<ScreenWarnBackProps> = (props) => {
centered
>
<ProCard split="vertical" bodyStyle={{ height: "calc(100vh - 136px)" }}>
<ProCard colSpan={7} key="0" bodyStyle={{ padding: "16px", overflowY: 'auto', height: "calc(100vh - 136px)" }}>
<ProCard colSpan={7} key="0" bodyStyle={{ padding: "16px", overflowY: 'auto', height: "calc(100vh - 136px)" }} className="screen-warn-p">
<Title level={5} style={{ marginBottom: '8px', color: "#b30000" }}>{detailData?.type == "3" ? "陌生人进入" : "人数异常"}</Title>
{detailData?.type == "3" ? (
<List
@ -133,7 +171,7 @@ const ScreenWarnBack: React.FC<ScreenWarnBackProps> = (props) => {
<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" />
<Image src={pictureDisplayPath + "?filePath=" + item.filePath} preview={{ getContainer: "null" }} height="70px" onClick={() => drawerClick(item.filePath)} />
</div>
</Card>
</List.Item>
@ -148,6 +186,18 @@ const ScreenWarnBack: React.FC<ScreenWarnBackProps> = (props) => {
columns={peopleNumColumns}
/>
)}
{drawerVisible && <Drawer
placement="left"
onClose={drawerClose}
visible={drawerVisible}
width={'29.17%'}
getContainer={false}
style={{ position: 'absolute' }}
>
<div onClick={drawerClose}>
<img src={pictureDisplayPath + "?filePath=" + drawerUrl} onWheel={handleImgZoom} ref={zoomImg} />
</div>
</Drawer>}
</ProCard>
<ProCard colSpan={17} key="1" bodyStyle={{ padding: "16px" }}>
<Radio.Group value={cameraSelect} buttonStyle="solid" style={{ marginBottom: "8px" }} onChange={onCaremaChange}>

View File

@ -85,4 +85,15 @@ export async function handleTakeEffectReserve(params: any, data: any) {
method: "POST",
data: data,
})
}
/**
* 获取区域的预约记录(用于时间组件禁用)
* @param areaId
* @returns
*/
export async function getTimeByAreaId(areaId: any) {
return request(`/api/biz-service-ebtp-evaluation/v1/eval/room/reserve/occupiedTime/${areaId}`, {
method: 'GET',
});
}

View File

@ -1,4 +1,4 @@
import { Col, Radio, Row, Table, Tag, Tooltip, Image } from "antd"
import { Col, Radio, Row, Table, Tag, Tooltip, Image, Drawer } from "antd"
import React, { useEffect, useRef, useState } from "react"
import { EarlyWarn, LocalTime, onCell, onHeaderCell } from "../Home";
import '../Home/style.less'
@ -132,8 +132,14 @@ export default (props: any) => {
const [backNumberList, setBackNumberList] = useState<any[]>([]);
//采购方式字典
const [bidMethodObj, setBidMethodObj] = useState<any>();
//图片查看抽屉显隐
const [drawerVisible, setDrawerVisible] = useState<boolean>(false);
//图片查看URL
const [drawerUrl, setDrawerUrl] = useState<string>('');
//监控视频Ref
const videoRef = useRef<any>();
//图片展示ref
const zoomImg = useRef<any>(null);
//定时刷新间隔
const _time = 10000;
@ -250,6 +256,37 @@ export default (props: any) => {
}
setBidMethodObj(obj);
}
//图片放大抽屉显示
const drawerClick = (filePath: string) => {
setDrawerUrl(filePath);
setDrawerVisible(true);
}
//图片放大抽屉关闭
const drawerClose = () => {
setDrawerVisible(false);
setDrawerUrl("");
}
const handleImgZoom = (e: { nativeEvent: { deltaY: number; }; }) => {
const { clientWidth, clientHeight, style, height, width } = zoomImg.current
const value = height / width
const num = 50
const bool = height > width ? clientWidth < 2000 : clientHeight < 1500
if (e.nativeEvent.deltaY <= 0 && bool) {
style.maxWidth = "none"
style.maxHeight = "none"
style.width = width + num + "px"
style.height = height + (num * value) + "px"
style.left = style.left - 1 % +"px"
style.top = style.top - 1 % +"px"
} else if (e.nativeEvent.deltaY > 0) {
if (width > 200 && height > 100) {
style.width = width - num + "px"
style.height = height - (num * value) + "px"
style.left = style.left + 1 % + "px"
style.top = style.top + 1 % + "px"
}
}
}
useEffect(() => {
initDict();
@ -366,7 +403,7 @@ export default (props: any) => {
<p>{item.createDate}</p>
</div>
<div>
<Image src={pictureDisplayPath + "?filePath=" + item.details[0].filePath} preview={false} height={"100%"} />
<Image src={pictureDisplayPath + "?filePath=" + item.details[0].filePath} preview={{ getContainer: "null" }} height={"100%"} onClick={() => drawerClick(item.details[0].filePath)} />
</div>
</div>
))
@ -377,7 +414,7 @@ export default (props: any) => {
<p>{item.describeStranger}</p>
</div>
<div>
<Image src={pictureDisplayPath + "?filePath=" + item.filePath} preview={false} height={"100%"} />
<Image src={pictureDisplayPath + "?filePath=" + item.filePath} preview={{ getContainer: "null" }} height={"100%"} onClick={() => drawerClick(item.filePath)} />
</div>
</div>
))}
@ -401,6 +438,18 @@ export default (props: any) => {
columns={staffReportColumns}
/>
)}
{drawerVisible && <Drawer
placement="right"
onClose={drawerClose}
visible={drawerVisible}
getContainer={false}
width={'100%'}
style={{ position: 'absolute' }}
>
<div onClick={drawerClose}>
<img src={pictureDisplayPath + "?filePath=" + drawerUrl} onWheel={handleImgZoom} ref={zoomImg} />
</div>
</Drawer>}
</div>
</Col>
</Row>

View File

@ -201,6 +201,43 @@
justify-content: space-between;
}
}
.ant-drawer-close {
color: #fff;
&:focus,
&:hover {
color: #fff;
}
}
.ant-drawer-content {
background-color: rgba(0, 0, 0, 0.35);
}
.ant-drawer-body {
text-align: center;
padding: 0;
&>div {
height: 100%;
}
&>div>img {
position: relative;
top: 50%;
transform: translateY(-50%);
-moz-user-select: 'none';
/* Firefox私有属性 */
-webkit-user-select: 'none';
/* WebKit内核私有属性 */
-ms-user-select: 'none';
/* IE私有属性(IE10及以后) */
user-select: 'none';
/* CSS3属性 */
}
}
}
.ant-radio-group-solid .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled) {