11.21 11.15电子评标室预约优化

This commit is contained in:
jl-zhoujl2
2022-11-21 10:38:05 +08:00
parent c852fd29e0
commit f42e7dbacf
6 changed files with 403 additions and 238 deletions

View File

@ -1,5 +1,5 @@
import React, { useEffect, useRef, useState } from 'react';
import { Button, Checkbox, Col, Collapse, DatePicker, Drawer, Form, Input, message, Modal, Popconfirm, Row, Select, Spin, Upload, Image, RadioChangeEvent, Radio } from 'antd'
import { Button, Checkbox, Col, Collapse, DatePicker, Drawer, Form, Input, message, Modal, Popconfirm, Row, Select, Spin, Upload, Image, RadioChangeEvent, Radio, Typography, Popover, Tooltip } from 'antd'
import ProTable, { ActionType, ProColumns } from '@ant-design/pro-table';
import { getList, saveGroup, delOne, saveMember, changeEx, queryVoList, changeMember, applyFor, roomStatus, juryTem, rePassWord } from './service';
import moment from 'moment';
@ -7,7 +7,7 @@ import { getProId, getProMethod, getDefId, getSessionProjectData, getRoomReturnU
import './judgList.less';
import '@/assets/xsy_style.less';
import FileDown from '@/utils/Download';
import { UploadOutlined } from '@ant-design/icons';
import { DownOutlined, EllipsisOutlined, UploadOutlined } from '@ant-design/icons';
import { btnAuthority } from '@/utils/authority';
import RiskPrevention from '@/utils/RiskPrevention';
import { history } from 'umi';
@ -16,6 +16,7 @@ import ExpertPhotoUpload from '@/components/ElecBidEvaluation/ExpertPhotoUpload'
import { getUserPhoto } from '@/pages/Tender/ProjectManager/JudgingPanel/List/service';
import BidEvalAppointment from '@/components/ElecBidEvaluation/BidEvalAppointment';
import OutsourcingManage from '@/pages/Tender/ProjectManager/JudgingPanel/List/OutsourcingManage';
import { dateTimeFormatter } from '@/utils/DateUtils';
const JudgingPanel: React.FC<{}> = (props: any) => {
const modalHeight = window.innerHeight * 96 / 100;
@ -25,11 +26,13 @@ const JudgingPanel: React.FC<{}> = (props: any) => {
const sectionId = props.location?.state?.secId;
const openTime = props.location?.state?.openTime;//开始评审时间
const formLayout = { labelCol: { span: 8 }, wrapperCol: { span: 16 }, };
const form24Layout = { labelCol: { span: 4 }, wrapperCol: { span: 20 }, };
const FormItem = Form.Item;
const [form] = Form.useForm();
const { Option } = Select;
const { Panel } = Collapse;
const { TextArea } = Input;
const { Paragraph, Text, Link, Title } = Typography;
// const { TabPane } = Tabs;
const actionRef = useRef<ActionType>();
const [spin, spinSet] = useState<any>(false);
@ -50,7 +53,7 @@ const JudgingPanel: React.FC<{}> = (props: any) => {
const [initEvalTime, setInitEvalTime] = useState<any>();//电子评标室-时间输入框默认时间(跟随标段) 2022.9.27 zhoujianlong
// const [userPhotoId, setUserPhotoId] = useState<string>("");//电子评标室-录入外部专家-相片id 2022.8.29 zhoujianlong
const [appoType, setAppoType] = useState<string>("0");//电子评标室-预约框状态 2022.8.29 zhoujianlong
const [isReserve, setIsReserve] = useState<string>("0");//电子评标室-是否预约评标室 2022.9.23 zhoujianlong 0-不预约 1-预约
const [isReserve, setIsReserve] = useState<string>("0");//电子评标室-是否预约电子评标室 2022.9.23 zhoujianlong 0-不预约 1-预约
const userData = getSessionUserData();//当前登录人用户信息
const [assistVisible, setAssistVisible] = useState<boolean>(false);//协办管理visible 2022.10.10 zhoujianlong
//外协管理
@ -106,6 +109,8 @@ const JudgingPanel: React.FC<{}> = (props: any) => {
{ title: '专家数量', dataIndex: 'expertNumber', width: '8%', },
{ title: '采购人代表数量', dataIndex: 'representativeNumber', width: '12%', },
{ title: '包件名称', dataIndex: 'sectionName', },
{ title: '是否预约电子评标室', dataIndex: 'reserveStatus', width: '10%', valueEnum: { 1: "是", 0: "否" } },
{ title: "评审地点", dataIndex: 'evalLocation', width: '15%', ellipsis: true, render: (_: any, record: any) => sectionNameValue(record.elecEvalRoomReserve, record.evalLocation, record.reserveStatus) },
{ title: '预计开始时间', dataIndex: 'startTime', valueType: 'dateTime', width: '10%', },
{ title: '预计结束时间', dataIndex: 'endTime', valueType: 'dateTime', width: '10%', },
{
@ -161,10 +166,10 @@ const JudgingPanel: React.FC<{}> = (props: any) => {
setAssistVisible(true);
}}></Button>}
{record.elecEvalRoomReserve && (record.elecEvalRoomReserve.status == -1 || record.elecEvalRoomReserve.status == 0) && <Button type='text' onClick={() => {
setSelectEvalData(record.elecEvalRoomReserve)
setSelectEvalData({ ...record.elecEvalRoomReserve, areaAddress: record.evalLocation });
setAppoType("1");
setSelectEvalVisible(true);
}}></Button>}
}}></Button>}
</>
);
} else {
@ -207,7 +212,7 @@ const JudgingPanel: React.FC<{}> = (props: any) => {
setModalVis(true);
disabledSet(check);
// readOnlySet(check);
setSelectEvalData(record.elecEvalRoomReserve);
setSelectEvalData({ ...record.elecEvalRoomReserve, areaAddress: record.evalLocation });
}}>{check ? '查看' : '修改'}</Button>
)
}
@ -272,8 +277,49 @@ const JudgingPanel: React.FC<{}> = (props: any) => {
]
}
//评标地点 评标室更多信息
const evalLocationTitle = (detail: any, updateData: any) => {
return (
<div className="eval-location-title">
<p>{updateData?.reserveStatus == 1 ? updateData.elecEvalRoomReserve.areaAddress : updateData?.evalLocation}</p>
<p>{detail?.numberInMeeting}</p>
<p>{detail?.contactName}</p>
<p>{detail?.contactTel}</p>
</div>
)
}
//说明
const sectionNameValue = (detail: any, evalLocation: any, reserveStatus: any) => {
const address = reserveStatus == 1 ? detail?.areaAddress : evalLocation;
const content = (
<Paragraph>
<blockquote style={{ width: '300px' }}>
<div className="eval-location-title">
<p>{address}</p>
<p>{detail?.numberInMeeting}</p>
<p>{detail?.contactName}</p>
<p>{detail?.contactTel}</p>
</div>
</blockquote>
</Paragraph>
)
let text = address.length > 30 ? address.slice(0, 30) + "..." : address;
return (
detail != null ? (
<span>
<Popover content={content} trigger={["hover"]} placement="bottom">
{text}
<DownOutlined style={{ cursor: 'pointer', marginLeft: '4px' }} />
</Popover>
</span>
) : (
<span>{text}</span>
)
)
}
useEffect(() => {//给表单赋值
updateData && setIsReserve(String(updateData?.reserveStatus));//赋值给是否预约评标室
updateData && setIsReserve(String(updateData?.reserveStatus));//赋值给是否预约电子评标室
updateData && String(updateData?.reserveStatus) == "1" && getEarliestTime(openTime, String(updateData?.reserveStatus));//初始化赋值数据
form.setFieldsValue({
juryType: updateData != undefined ? updateData.juryType : null,
@ -281,7 +327,7 @@ const JudgingPanel: React.FC<{}> = (props: any) => {
expertNumber: updateData != undefined ? updateData.expertNumber : null,
startTime: updateData != undefined ? updateData.reserveStatus == 1 ? moment(updateData.elecEvalRoomReserve.reserveStartDate, 'yyyy-MM-DD HH:mm:ss') : moment(updateData.startTime, 'yyyy-MM-DD HH:mm:ss') : null,
endTime: updateData != undefined ? updateData.reserveStatus == 1 ? moment(updateData.elecEvalRoomReserve.reserveEndDate, 'yyyy-MM-DD HH:mm:ss') : moment(updateData.endTime, 'yyyy-MM-DD HH:mm:ss') : null,
evalLocation: updateData != undefined ? updateData.evalLocation : null,
evalLocation: updateData != undefined ? updateData.reserveStatus == 1 ? updateData.elecEvalRoomReserve.areaAddress : updateData.evalLocation : null,
description: updateData != undefined ? updateData.description : null,
reserveBy: updateData?.reserveStatus == 1 ? updateData.elecEvalRoomReserve.reserveBy : null,
reserveContactNumber: updateData?.reserveStatus == 1 ? updateData.elecEvalRoomReserve.reserveContactNumber : null,
@ -628,18 +674,109 @@ const JudgingPanel: React.FC<{}> = (props: any) => {
const tab1 = () => {//cqtab1
return (
<>
<h3 className="first-title"></h3>
<Form {...formLayout}>
<h3 className="first-title"></h3>
<Form {...formLayout} form={form}>
<Row>
<Col span={12}><FormItem
label="是否预约评标室"
<Col span={24}><FormItem
label="是否预约电子评标室"
required
{...form24Layout}
extra={<span style={{ color: '#b30000' }}></span>}
>
<Radio.Group onChange={onRadioChange} value={isReserve} disabled={disabled}>
<Radio value="1"></Radio>
<Radio value="0"></Radio>
</Radio.Group>
</FormItem></Col>
{isReserve == "1" && !disabled ? (//预约电子评标室
<Col span={12}>
<Form.Item label="评审地点" style={{ marginBottom: 0 }} required>
<FormItem
name="evalLocation"
rules={[...rule('评审地点'), { type: 'string', message: '请输入正确内容' }, { max: 100, message: '内容超长' }]}
style={{ display: 'inline-block', width: 'calc(60% - 8px)' }}
>
<Input style={{ width: "100%" }} disabled={true} placeholder="评审地点" />
</FormItem>
<Form.Item
style={{ display: 'inline-block', width: 'calc(40% - 8px)', margin: '0 8px' }}
>
<Button type='primary' onClick={() => selectEvalClick()} disabled={disabled}></Button>
</Form.Item>
</Form.Item>
</Col>
) : (
<Col span={12}>
<FormItem
name="evalLocation"
label="评审地点"
rules={[...rule('评审地点'), { type: 'string', message: '请输入正确内容' }, { max: 100, message: '内容超长' }]}
>
<Input style={{ width: "90%" }} disabled={disabled} placeholder="评审地点"
addonAfter={
disabled && <Tooltip title={() => evalLocationTitle(selectEvalData, updateData)}>
<EllipsisOutlined />
</Tooltip>
} />
</FormItem>
</Col>
)}
{isReserve == "1" && (//预约电子评标室
<Col span={12}><FormItem
name="assistNumber"
label="外协人员数量"
rules={[{ type: 'string', message: '请输入正确内容' }, { pattern: /^([1-9]?\d|100)$/, message: '请输入正确数值' }]}
tooltip="在合规情况下临时可进入电子评标室人员,如视察领导等。"
>
<Input style={{ width: "90%" }} type="number" disabled={disabled} />
</FormItem></Col>
)}
<Col span={12}><FormItem
name="startTime"
label="预计评审开始时间"
rules={rule('开始时间')}
>
<DatePicker
format="YYYY-MM-DD HH:mm:ss"
disabledDate={disabledDate}
showTime={{ defaultValue: moment('00:00:00', 'HH:mm:ss') }}
disabled={disabled || (isReserve == "1")}
showNow={false}
style={{ width: "90%" }}
/>
</FormItem></Col>
<Col span={12}><FormItem
name="endTime"
label="预计评审结束时间"
rules={rule('结束时间')}
>
<DatePicker
format="YYYY-MM-DD HH:mm:ss"
disabledDate={disabledDate}
showTime={{ defaultValue: moment('00:00:00', 'HH:mm:ss') }}
disabled={disabled || (isReserve == "1")}
showNow={false}
style={{ width: "90%" }}
/>
</FormItem></Col>
{isReserve == "1" && (//预约电子评标室
<>
<Col span={12}><FormItem
name="reserveBy"
label="预约人"
rules={[{ required: true, message: `请录入预约人` }, { max: 100, message: '内容超长' }]}
>
<Input style={{ width: "90%" }} disabled={true} placeholder="预约人" />
</FormItem></Col>
<Col span={12}><FormItem
name="reserveContactNumber"
label="预约人联系方式"
rules={[{ required: true, message: `请录入预约人联系方式` }, { max: 100, message: '内容超长' }]}
>
<Input type="number" style={{ width: "90%" }} disabled={true} placeholder="预约人联系方式" />
</FormItem></Col>
</>
)}
</Row>
</Form>
<h3 className="first-title"></h3>
@ -691,34 +828,7 @@ const JudgingPanel: React.FC<{}> = (props: any) => {
>
<Input style={{ width: "90%" }} type="number" disabled={disabled} placeholder="专家数量" />
</FormItem></Col>
{isReserve == "1" ? (//预约评标室
<Col span={12}>
<Form.Item label="评审地点" style={{ marginBottom: 0 }} required>
<FormItem
name="evalLocation"
rules={[...rule('评审地点'), { type: 'string', message: '请输入正确内容' }, { max: 100, message: '内容超长' }]}
style={{ display: 'inline-block', width: 'calc(60% - 8px)' }}
>
<Input style={{ width: "100%" }} disabled={true} placeholder="评审地点" />
</FormItem>
<Form.Item
style={{ display: 'inline-block', width: 'calc(40% - 8px)', margin: '0 8px' }}
>
<Button type='primary' onClick={() => selectEvalClick()} disabled={disabled}></Button>
</Form.Item>
</Form.Item>
</Col>
) : (
<Col span={12}>
<FormItem
name="evalLocation"
label="评审地点"
rules={[...rule('评审地点'), { type: 'string', message: '请输入正确内容' }, { max: 100, message: '内容超长' }]}
>
<Input style={{ width: "90%" }} disabled={disabled} placeholder="评审地点" />
</FormItem>
</Col>
)}
<Col span={12}><FormItem
name="description"
label="申请要求"
@ -726,61 +836,6 @@ const JudgingPanel: React.FC<{}> = (props: any) => {
>
<Input style={{ width: "90%" }} disabled={disabled} />
</FormItem></Col>
{isReserve == "1" && (//预约评标室
<Col span={12}><FormItem
name="assistNumber"
label="外协人员数量"
rules={[{ type: 'string', message: '请输入正确内容' }, { pattern: /^([1-9]?\d|100)$/, message: '请输入正确数值' }]}
>
<Input style={{ width: "90%" }} type="number" disabled={disabled} />
</FormItem></Col>
)}
<Col span={12}><FormItem
name="startTime"
label="预计评审开始时间"
rules={rule('开始时间')}
>
<DatePicker
format="YYYY-MM-DD HH:mm:ss"
disabledDate={disabledDate}
showTime={{ defaultValue: moment('00:00:00', 'HH:mm:ss') }}
disabled={disabled || (isReserve == "1")}
showNow={false}
style={{ width: "90%" }}
/>
</FormItem></Col>
<Col span={12}><FormItem
name="endTime"
label="预计评审结束时间"
rules={rule('结束时间')}
>
<DatePicker
format="YYYY-MM-DD HH:mm:ss"
disabledDate={disabledDate}
showTime={{ defaultValue: moment('00:00:00', 'HH:mm:ss') }}
disabled={disabled || (isReserve == "1")}
showNow={false}
style={{ width: "90%" }}
/>
</FormItem></Col>
{isReserve == "1" && (//预约评标室
<>
<Col span={12}><FormItem
name="reserveBy"
label="预约人"
rules={[{ required: true, message: `请录入预约人` }, { max: 100, message: '内容超长' }]}
>
<Input style={{ width: "90%" }} disabled={true} placeholder="预约人" />
</FormItem></Col>
<Col span={12}><FormItem
name="reserveContactNumber"
label="预约人联系方式"
rules={[{ required: true, message: `请录入预约人联系方式` }, { max: 100, message: '内容超长' }]}
>
<Input type="number" style={{ width: "90%" }} disabled={true} placeholder="预约人联系方式" />
</FormItem></Col>
</>
)}
</Row>
</Form>
</>
@ -1421,6 +1476,7 @@ const JudgingPanel: React.FC<{}> = (props: any) => {
<Form.Item
name="faceId"
style={{ display: 'inline-block', width: '60%' }}
extra={<span style={{ color: '#b30000' }}>使</span>}
>
<ExpertPhotoUpload maxSize={200} />
</Form.Item>
@ -1697,9 +1753,9 @@ const JudgingPanel: React.FC<{}> = (props: any) => {
}}
>
<Spin spinning={spin}>
<div className='headerDiv pl24 pr16'>
<h3 className="first-title floatLeft"></h3>
<div className='rightDiv'>
<div className='headerDiv pl24 pr16' style={{ display: 'flex', justifyContent: 'space-between' }}>
<h3 className="first-title"></h3>
<div>
{/* <Button key="1" className='mR8' onClick={() => { }}>通知专家</Button> */}
<Button key="2" type='primary' className='mR8' hidden={!open || allEnd || btnAuthority(['ebtp-agency-project-manager', 'ebtp-purchase'])} onClick={() => {
checkBoxsSet([]);
@ -1712,6 +1768,9 @@ const JudgingPanel: React.FC<{}> = (props: any) => {
</Upload>
</div>
</div>
<div style={{ marginTop: '11px', marginLeft: '35px' }}>
<span style={{ color: '#b30000' }}>使</span>
</div>
<Collapse className='xsy-collapse' style={{ marginTop: '16px' }} defaultActiveKey={['1', '2', '3', '4', '5',]}>
{returnPanel()}
@ -1790,7 +1849,7 @@ const JudgingPanel: React.FC<{}> = (props: any) => {
getExpertPhoto();
}
}
//是否预约评标室
//是否预约电子评标室
const onRadioChange = (e: RadioChangeEvent) => {
setIsReserve(e.target.value);
setSelectEvalData(null);
@ -1799,8 +1858,17 @@ const JudgingPanel: React.FC<{}> = (props: any) => {
};
//评审开始时间处理
const getEarliestTime = (openTime: string | null | undefined, reserve: string) => {
let startTime = openTime ? moment(openTime).startOf("hour").add(1, 'h') : null;
let endTime = openTime ? moment(openTime).startOf("hour").add(3, 'h') : null;
let startTime = null;//开始时间小于17点正常17点+则为null
let endTime = null;
if (openTime) {
if (moment(openTime).hour() <= 15) {//结束时间小于16点正常+2h16-17点只能给18点17点+则为null
startTime = moment(openTime).startOf("hour").add(1, 'h');
endTime = moment(openTime).startOf("hour").add(3, 'h');
} else if (moment(openTime).hour() == 16) {
startTime = moment().startOf("hour").hour(17);
endTime = moment().startOf("hour").hour(18);
}
}
if (reserve == "1") {//预约了评标室
setInitEvalTime({ startTime, endTime, reserveBy: userData?.fullName, reserveContactNumber: userData?.mobilePhone, });
} else {