Merge branch '20220507-MAC地址强控' into 'master-20220527'

5.27 MAC地址强控

See merge request eshop/fe_service_ebtp_frontend!87
This commit is contained in:
周建龙
2022-05-27 15:49:44 +08:00
16 changed files with 745 additions and 139 deletions

View File

@ -35,7 +35,7 @@ const BiddingRoom = (props) => {
const roomId = getRoomId();
const [list, setList] = useState();
const [selectedPath, setSelectedPath] = useState(window.location.pathname.replace('ReviewResults/Jury', 'ReviewResults').replace('ReviewResults/GroupLeader', 'ReviewResults'));
const [risky, riskySet] = useState();
// const [risky, riskySet] = useState();
//字段类型(两种) 评标,评审
let sectionTypeTwo = MethodDict == "procurement_mode_1" || MethodDict == "procurement_mode_2" ? "评标" : "评审"
//字段类型(三种) 评标,评审,谈判
@ -156,19 +156,19 @@ const BiddingRoom = (props) => {
}, [])
//风险点展示获取是否有风险
async function isRisky() {
await getRiskStatus({ assessRoomId: roomId, tpId: tpId }).then((res) => {
if (res.code == 200) {
if (res?.data) {
riskySet(
<Tooltip title="当前存在风险项">
<ExclamationCircleOutlined style={{ color: 'rgb(250,173,20)', position: 'absolute', fontSize: 26, top: 12 }} />
</Tooltip>
)
}
}
})
}
// async function isRisky() {
// await getRiskStatus({ assessRoomId: roomId, tpId: tpId }).then((res) => {
// if (res.code == 200) {
// if (res?.data) {
// riskySet(
// <Tooltip title="当前存在风险项">
// <ExclamationCircleOutlined style={{ color: 'rgb(250,173,20)', position: 'absolute', fontSize: 26, top: 12 }} />
// </Tooltip>
// )
// }
// }
// })
// }
//评审结果页签点击事件
const onclick = async (path, id) => {
@ -285,7 +285,7 @@ const BiddingRoom = (props) => {
//初始化数据
const listRender = async () => {
await isRisky();
// await isRisky();
//供应商是否用ipass解密判断
IPassDecode == 0 ? null : supplierList.splice(2, 1)
//供应商是否显示评审进展判断(招标类不显示)

View File

@ -5,6 +5,7 @@ import Resumablejs from "./resumable";
import SparkMD5 from "./spark-md5";
import './style.css';
import { getCurrentTime, getTendererFileStatus } from './service';
import { getProId } from '@/utils/session';
function getUuid() {
return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
@ -39,7 +40,8 @@ export default class ReactResumableJs extends React.Component {
},
timer: 0,// 计时器
redText: false,
btnHide: false
btnHide: false,
projectId: getProId(),
};
this.resumable = null;
this.timerInterval;
@ -253,7 +255,8 @@ export default class ReactResumableJs extends React.Component {
let data = {
"tdocCatalogId": this.props.currentDate.tdocCatalogId,
"tdocId": this.props.currentDate.tdocId,
"tendererId": this.props.currentDate.tendererId
"tendererId": this.props.currentDate.tendererId,
"tpId": this.state.projectId,
}
getTendererFileStatus(data).then((res) => { // 判断是否已投标
if (res.code == 200) {

View File

@ -0,0 +1,70 @@
import React, { useState } from 'react';
import { Modal, Popover, Typography } from 'antd';
import { ExclamationCircleOutlined } from '@ant-design/icons';
import ViewRishFormModal from './ViewRishFormModal';
interface MACAddressPromptProps {
type: string; //score-打分 other-其他
companyName?: string //公司名称
}
const MACAddressPrompt: React.FC<MACAddressPromptProps> = (props) => {
const { type, companyName } = props;
const { Text, Link } = Typography;
const modalHeight = window.innerHeight * 96 / 100;
//Modal visible
const [visible, setVisible] = useState<boolean>(false);
return (
<>
{type == 'score' ? (
<Modal
destroyOnClose
visible={visible}
onCancel={() => setVisible(false)}
style={{ maxHeight: modalHeight }}
bodyStyle={{ maxHeight: modalHeight - 54, overflowY: 'auto', }}
width={'80%'}
centered
closable={false}
cancelText="关闭"
okButtonProps={{ hidden: true }}
>
<ViewRishFormModal activeKey={true} />
</Modal>
) : (
<Modal
destroyOnClose
visible={visible}
onCancel={() => setVisible(false)}
centered
bodyStyle={{ padding: 40 }}
footer={null}
>
<Text strong>{companyName}MAC地址相同WTZ2019110816765MAC地址相同</Text>
</Modal>
)}
<Popover
content={
<Typography>
<Text strong style={{ display: 'block', }}></Text>
<Text strong style={{ fontSize: 64, lineHeight: '8px', float: 'left', color: '#b30000' }}>·</Text>
<Link
href="#"
onClick={() => {
setVisible(true);
}}
underline={true}
>
MAC地址重复
</Link>
</Typography>
}
>
<ExclamationCircleOutlined style={{ color: '#b30000', marginLeft: 4 }} />
</Popover>
</>
);
};
export default MACAddressPrompt;

View File

@ -5,9 +5,10 @@ import { getProMethod, getRoomId } from '@/utils/session';
import FileDown from '@/utils/Download';
interface ViewRishFormModalProps {
modalVisible: boolean;
values: any;
onCancel: any;
modalVisible?: boolean;
values?: any;
onCancel?: any;
activeKey?: boolean;
}
@ -22,7 +23,7 @@ const ViewRishFormModal: React.FC<ViewRishFormModalProps> = (props) => {
} else {
name1 = "应答";
}
useEffect(() => {
getWarningList();
}, [])
@ -35,12 +36,12 @@ const ViewRishFormModal: React.FC<ViewRishFormModalProps> = (props) => {
{ title: '序号', width: '10%', render: (text: any, record: any, index: any) => `${index + 1}` },
{ title: '供应商名称', width: '20%', dataIndex: 'companyName', },
{
title: 'IP地址', width: 200, dataIndex: 'ip', render: (_ : any, record: any) => {
title: 'IP地址', width: 200, dataIndex: 'ip', render: (_: any, record: any) => {
return <div style={{ wordBreak: 'break-all', wordWrap: 'break-word' }}>{record.ip}</div>;
}
},
{
title: 'MAC地址', width: '20%', dataIndex: 'mac', render: (_ : any, record: any) => {
title: 'MAC地址', width: '20%', dataIndex: 'mac', render: (_: any, record: any) => {
return <div style={{ wordBreak: 'break-all', wordWrap: 'break-word' }}>{record.mac}</div>;
}
},
@ -51,7 +52,7 @@ const ViewRishFormModal: React.FC<ViewRishFormModalProps> = (props) => {
{ title: '序号', width: '10%', render: (text: any, record: any, index: any) => `${index + 1}` },
{ title: '供应商名称', width: '25%', dataIndex: 'companyName', },
{
title: 'MAC地址', width: '20%', dataIndex: 'mac', render: (_ : any, record: any) => {
title: 'MAC地址', width: '20%', dataIndex: 'mac', render: (_: any, record: any) => {
return <div style={{ wordBreak: 'break-all', wordWrap: 'break-word' }}>{record.mac}</div>;
}
},
@ -77,7 +78,7 @@ const ViewRishFormModal: React.FC<ViewRishFormModalProps> = (props) => {
return (
<>
<Collapse onChange={callback}>
<Collapse onChange={callback} defaultActiveKey={props?.activeKey ? ['1'] : []}>
<Collapse.Panel header={`${name1}文件制作地址日志信息查看`} key="1">
{rishList?.length == 0
? <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
@ -124,7 +125,7 @@ const ViewRishFormModal: React.FC<ViewRishFormModalProps> = (props) => {
</Collapse>
);
}) : (
<Card bordered={false} bodyStyle={{padding: '16px 24px'}}>
<Card bordered={false} bodyStyle={{ padding: '16px 24px' }}>
<p>MAC地址相同的供应商信息如下 </p>
<Table
size='small'

View File

@ -6,6 +6,7 @@ import { CheckOutlined, CloseOutlined } from '@ant-design/icons';
import { getProMethod, getRoomId } from '@/utils/session';
import { getURLInformation } from '@/utils/CommonUtils';
import ExtendUpload from '@/utils/ExtendUpload';
import MACAddressPrompt from '@/pages/Evaluation/BidControl/BidControlManager/components/MACAddressPrompt';
interface BidPreliminarySummaryProps {
totalSupplier: any;
@ -168,7 +169,12 @@ const PreliminarySummary: React.FC<BidPreliminarySummaryProps> = (props) => {
];
columns.forEach((ele: any) => {
tcolumns[4].children.push({
title: ele.supplierRegisterName,
title: (
<>
{ele.supplierRegisterName}
{ele.macConflictStatus && <MACAddressPrompt type='other' companyName={ele.supplierRegisterName} />}
</>
),
dataIndex: ele.supplierRegisterId,
key: ele.supplierRegisterId,
render: (value: any, record: any, index: any) => {

View File

@ -7,6 +7,7 @@ import FileDown from '@/utils/Download';
import { getURLInformation } from '@/utils/CommonUtils';
import FirstTrialTable from '../BidPreliminaryManager/module/FirstTrialTable';
import { btnAuthority } from '@/utils/authority';
import MACAddressPrompt from '../../BidControl/BidControlManager/components/MACAddressPrompt';
const { TabPane } = Tabs;
const { TextArea } = Input;
@ -214,7 +215,7 @@ const Index: React.FC<{}> = () => {
}
getProgress({ ...date }).then((res) => {
if (res.code == 200) {
if(res.data == 100){
if (res.data == 100) {
submitApi()
} else {
message.error("您有未完成的打分项,请完成后再提交!")
@ -237,7 +238,7 @@ const Index: React.FC<{}> = () => {
}
getProgress({ ...date }).then((res) => {
if (res.code == 200) {
if(res.data == 100){
if (res.data == 100) {
setProcess(res.data)
submitApi()
} else {
@ -359,7 +360,12 @@ const Index: React.FC<{}> = () => {
totalSupplierColumns.slice(currentDate, currentDate + 3).map((item: any) => {
supplierId.push(item.supplierRegisterId)
newColumns.push({
title: item.supplierRegisterName,
title: (
<>
{item.supplierRegisterName}
{item.macConflictStatus && <MACAddressPrompt type='score' />}
</>
),
dataIndex: item.supplierRegisterId,
render: (text: any, record: any) => {
if (record.scoreMap && record.scoreMap[item.supplierRegisterId]) {

View File

@ -1,10 +1,11 @@
import React, { useEffect, useImperativeHandle, useState } from 'react';
import { Input, Pagination, Table } from 'antd';
import React, { useEffect, useImperativeHandle, useRef, useState } from 'react';
import { Input, Pagination, Select, Table } from 'antd';
import '@/assets/ld_style.less';
import { getSupplierScoreData, isCheckShow } from '../service';
import { CheckOutlined, CloseOutlined } from '@ant-design/icons';
import { getURLInformation } from '@/utils/CommonUtils';
import { getProMethod, getRoomId } from '@/utils/session';
import MACAddressPrompt from '@/pages/Evaluation/BidControl/BidControlManager/components/MACAddressPrompt';
interface BidPreliminarySummaryProps {
totalSupplier?: any;
@ -29,12 +30,15 @@ const BidPreliminarySummary: React.FC<BidPreliminarySummaryProps> = (props) => {
const [tableDataSource, setTableDataSource] = useState<any[]>([]);
//刷新参数
const [count, setCount] = useState<number>(0);
const tableDataRef = useRef<any[]>([]);
const isShowRef = useRef<boolean>(false);
tableDataRef.current = tableDataSource;
const proMethod = getProMethod();//获取采购方式
let showNameT: any = { tbr: '', pb: '', tb: '' }//投标人供应商
if (proMethod === 'procurement_mode_1' || proMethod === 'procurement_mode_2') {//招标
showNameT = { tbr: '投标人', pb: '评标', tb: '投标' };
showNameT = { tbr: '投标人', pb: '评标', tb: '投标' };
} else {
showNameT = { tbr: '供应商', pb: '评审', tb: '应答' }
showNameT = { tbr: '供应商', pb: '评审', tb: '应答' }
}
const { TextArea } = Input;
@ -76,6 +80,7 @@ const BidPreliminarySummary: React.FC<BidPreliminarySummaryProps> = (props) => {
//判断采购方式是否符合
isCheckShow(juryDataParams.assessRoomId).then((res) => {
if (res.code == 200) {
isShowRef.current = res.data;
let count = 0;
totalSupplier.forEach((ele: any) => {
if (
@ -133,6 +138,18 @@ const BidPreliminarySummary: React.FC<BidPreliminarySummaryProps> = (props) => {
return pre
}
}, 0)
for (const key in inner.earlyMap) {
if (Object.prototype.hasOwnProperty.call(inner.earlyMap, key)) {
const element = inner.earlyMap[key];
for (const ite of totalSupplier) {
if (key == ite.supplierRegisterId) {
element['macConflictStatus'] = ite.macConflictStatus;
break;
}
}
element['originalResult'] = element.judgesResult;
}
}
if (count == inner.length - 1) {
count = 0
} else {
@ -232,7 +249,12 @@ const BidPreliminarySummary: React.FC<BidPreliminarySummaryProps> = (props) => {
];
columns.forEach((ele: any) => {
tcolumns[4].children.push({
title: ele.supplierRegisterName,
title: (
<>
{ele.supplierRegisterName}
{ele.macConflictStatus && <MACAddressPrompt type='other' companyName={ele.supplierRegisterName} />}
</>
),
dataIndex: ele.supplierRegisterId,
key: ele.supplierRegisterId,
render: (value: any, record: any, index: any) => {
@ -261,6 +283,7 @@ const BidPreliminarySummary: React.FC<BidPreliminarySummaryProps> = (props) => {
return readOnly ? value.remarks : (!value.judgesResult ? <TextArea
onBlur={(e) => {
value.remarks = e.target.value
setTableDataSource([...tableDataRef.current])
}}
maxLength={500}
autoSize
@ -268,7 +291,33 @@ const BidPreliminarySummary: React.FC<BidPreliminarySummaryProps> = (props) => {
defaultValue={value.remarks}
/> : null)
} else {
return value.judgesResult == true ? '合格' : '不合格';
// return value.judgesResult == true ? '合格' : '不合格';
return readOnly || !ele.macConflictStatus ? value.judgesResult ? '合格' : '不合格' : (<Select
onChange={(e) => {
value.judgesResult = !!e;
tableDataRef.current[tableDataRef.current.length - 1][ele.supplierRegisterId].judgesResult = !!e;
setTableDataSource([...tableDataRef.current])
if (isShowRef.current) {
let count = 0;
totalSupplier.forEach((ele: any) => {
if (tableDataRef.current[tableDataRef.current.length - 1][ele.supplierRegisterId].judgesResult) {
count = count + 1;
}
});
if (count < 3) {
onSubmit(true)
} else {
onSubmit(false)
}
}
}}
options={[
{ label: '合格', value: 1 },
{ label: '不合格', value: 0 },
]}
style={{ width: '100px' }}
defaultValue={value.judgesResult ? 1 : 0}
/>)
}
}
},

View File

@ -11,6 +11,7 @@ import FileDown from '@/utils/Download';
import { getURLInformation, isEmpty } from '@/utils/CommonUtils';
import ExtendUpload from '@/utils/ExtendUpload';
import { btnAuthority } from '@/utils/authority';
import MACAddressPrompt from '../../BidControl/BidControlManager/components/MACAddressPrompt';
const { TabPane } = Tabs;
const { SubMenu } = Menu;
@ -444,7 +445,12 @@ const Index: React.FC<{}> = () => {
totalSupplierColumns.slice(currentDate, currentDate + 3).map((item: any) => {
supplierId.push(item.supplierRegisterId)
newColumns.push({
title: item.supplierRegisterName,
title: (
<>
{item.supplierRegisterName}
{item.macConflictStatus && <MACAddressPrompt type='score' />}
</>
),
dataIndex: item.supplierRegisterId,
render: (text: any, record: any) => {
if (record.scoreMap && record.scoreMap[item.supplierRegisterId]) {
@ -737,25 +743,27 @@ const Index: React.FC<{}> = () => {
}
//处理汇总表返回的数据
const getRemarkList = (data: any) => {
console.log('data', data);
const List: any[] = []
const Error: any[] = []
totalSupplierColumns.forEach((item: any) => {
for (const item of totalSupplierColumns) {
const obj = data[data.length - 1][item?.supplierRegisterId]
if (obj.judgesResult == false) {//判断为不合格情况
if (isEmpty(obj.remarks)) {
Error.push(item?.supplierRegisterName)
return
message.info(`请填写【${item?.supplierRegisterName}】的不合格原因说明`)
return false;
}
}
if (obj.macConflictStatus && obj.judgesResult) {//mac地址重复供应商选为合格
message.info(`${item?.supplierRegisterName}与其他供应商MAC地址重复不可选为初审合格`);
return false;
}
List.push({
supplierRegisterId: item?.supplierRegisterId,
qualifiedStatus: obj?.judgesResult ? '1' : '2',
remarks: obj?.judgesResult ? null : obj?.remarks,
originalResult: obj?.originalResult ? '1' : '2',
modifyResultStatus: obj?.judgesResult != obj?.originalResult,
})
});
if (Error.length > 0) {
message.info(`请填写【${Error[0]}】的不合格原因说明`)
return false
}
return List
}

View File

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { Button, Card, DatePicker, Divider, Form, List, message, Modal, Progress, Spin } from "antd";
import { Button, Card, DatePicker, Divider, Form, List, message, Modal, Popover, Progress, Spin, Typography } from "antd";
import ProForm, {
ModalForm,
ProFormDateTimePicker,
@ -8,9 +8,10 @@ import ProTable from "@ant-design/pro-table";
import {
ClockCircleOutlined,
DownloadOutlined,
ExclamationCircleOutlined,
FullscreenExitOutlined,
UnorderedListOutlined
} from "@ant-design/icons/lib";
} from "@ant-design/icons";
import {
getBiddingDocumentsDecryptList,
DownFile,
@ -58,6 +59,7 @@ const BiddingDocumentsDecrypt: React.FC<BiddingDocumentsDecryptProps> = (props)
const [spinTip, spinTipSet] = useState<string>('请稍等...');//spin tip显示文字
const MethodDict = getProMethod();
const { Title, Text } = Typography;
//应答字段类型 评标,应答
let responseType = MethodDict == "procurement_mode_1" || MethodDict == "procurement_mode_2" ? "投标" : "应答"
let supplierType = MethodDict == "procurement_mode_1" || MethodDict == "procurement_mode_2" ? "投标人" : "供应商"
@ -368,6 +370,26 @@ const BiddingDocumentsDecrypt: React.FC<BiddingDocumentsDecryptProps> = (props)
dataIndex: 'companyName',
valueType: 'text'
},
{
title: (
<span>
MAC地址检测承诺书时间
<Popover
content={
<Typography>
<Title level={5}></Title>
<Text style={{ display: 'inline-block', textIndent: '2em' }}>IPMAC地址校验MAC地址相同/</Text>
</Typography>
}
overlayInnerStyle={{ width: 400 }}
>
<ExclamationCircleOutlined style={{ color: '#b30000', marginLeft: 4 }} />
</Popover>
</span>
),
dataIndex: 'confirmTime',
valueType: 'text'
},
{
title: '解密状态',
dataIndex: item.quoteOrOther == "1" ? 'decryptOtherStatus' : "decryptStatus",

View File

@ -15,6 +15,7 @@ import SortEditableTable from './SortEditableTable';
import ReviewReportUpload from '@/utils/ReviewReportUpload';
import { ExclamationCircleOutlined } from '@ant-design/icons';
import { getFileListByBid } from '@/utils/DownloadUtils';
import MACAddressPrompt from '@/pages/Evaluation/BidControl/BidControlManager/components/MACAddressPrompt';
const { Panel } = Collapse;
const { TextArea } = Input;
@ -286,6 +287,26 @@ const GroupLeader: React.FC = () => {
{
title: '供应商名称',
dataIndex: 'companyName',
render: (_: any, record: any) => {
if (record.problemInfoList != null) {
let count = 0;
record.problemInfoList.forEach((ele: any) => {
if (ele.problemType == 1) {//MAC地址重复
count += 1;
}
});
if (count > 0) {
return (
<>
{_}
{<MACAddressPrompt type='other' companyName={_} />}
</>
)
}
return _;
}
return _;
}
// render: (_: any, record: any) => {
// let tip = <></>;
// if (record.problemInfoList?.length > 0) {
@ -345,6 +366,23 @@ const GroupLeader: React.FC = () => {
title: '是否通过初步评审',
dataIndex: 'firstRvwResult',
render: (_: any, record: any) => {
/**
* 2022.5.9 zhoujianlong 增加MAC地址重复供应商不能将中标候选人选为的校验
*/
if (!confirmSubmitStatus && record.problemInfoList != null) {
let count = 0;
record.problemInfoList.forEach((ele: any) => {
if (ele.problemType == 1) {//MAC地址重复
count += 1;
}
});
if (count > 0) {
if (record.winnerCandidate == 'yes') {
message.info(`${record.companyName}与其他供应商MAC地址相同不可选为${candidateType}候选人`);
record.winnerCandidate = 'no'
}
}
}
if (record.firstRvwResult == null) {
return '-'
} else {
@ -382,6 +420,26 @@ const GroupLeader: React.FC = () => {
dataIndex: 'companyName',
width: 110,
fixed: 'left',
render: (_: any, record: any) => {
if (record.problemInfoList != null) {
let count = 0;
record.problemInfoList.forEach((ele: any) => {
if (ele.problemType == 1) {//MAC地址重复
count += 1;
}
});
if (count > 0) {
return (
<>
{_}
{<MACAddressPrompt type='other' companyName={_} />}
</>
)
}
return _;
}
return _;
}
// render: (_: any, record: any) => {
// let tip = <></>;
// if (record.problemInfoList?.length > 0) {
@ -476,6 +534,27 @@ const GroupLeader: React.FC = () => {
isEmpty(record.winnerCandidate) ? record.winnerCandidate = 'no' : null
isEmpty(record.winnerBidder) ? record.winnerBidder = '0' : null
}
/**
* 2022.5.9 zhoujianlong 增加MAC地址重复供应商不能将中标候选人选为的校验
*/
if (!confirmSubmitStatus && record.problemInfoList != null) {
let count = 0;
record.problemInfoList.forEach((ele: any) => {
if (ele.problemType == 1) {//MAC地址重复
count += 1;
}
});
if (count > 0) {
if (record.winnerCandidate == 'yes') {
message.info(`${record.companyName}与其他供应商MAC地址相同不可选为入围候选人`);
record.winnerCandidate = 'no'
}
if (record.winnerBidder == '1') {
message.info(`${record.companyName}与其他供应商MAC地址相同不可选为拟入围人`);
record.winnerBidder = '0'
}
}
}
record.answerValid = valid
return rvwResultRender(_, record.detailRvwReason);
}
@ -532,6 +611,26 @@ const GroupLeader: React.FC = () => {
dataIndex: 'companyName',
width: 110,
fixed: 'left',
render: (_: any, record: any) => {
if (record.problemInfoList != null) {
let count = 0;
record.problemInfoList.forEach((ele: any) => {
if (ele.problemType == 1) {//MAC地址重复
count += 1;
}
});
if (count > 0) {
return (
<>
{_}
{<MACAddressPrompt type='other' companyName={_} />}
</>
)
}
return _;
}
return _;
}
// render: (_: any, record: any) => {
// let tip = <></>;
// if (record.problemInfoList?.length > 0) {
@ -645,6 +744,27 @@ const GroupLeader: React.FC = () => {
isEmpty(record.winnerCandidate) ? record.winnerCandidate = 'no' : null
isEmpty(record.winnerBidder) ? record.winnerBidder = '0' : null
}
/**
* 2022.5.9 zhoujianlong 增加MAC地址重复供应商不能将中标候选人选为的校验
*/
if (!confirmSubmitStatus && record.problemInfoList != null) {
let count = 0;
record.problemInfoList.forEach((ele: any) => {
if (ele.problemType == 1) {//MAC地址重复
count += 1;
}
});
if (count > 0) {
if (record.winnerCandidate == 'yes') {
message.info(`${record.companyName}与其他供应商MAC地址相同不可选为${candidateType}候选人`);
record.winnerCandidate = 'no'
}
if (record.winnerBidder == '1') {
message.info(`${record.companyName}与其他供应商MAC地址相同不可选为拟${candidateType}`);
record.winnerBidder = '0'
}
}
}
record.answerValid = valid
return rvwResultRender(_, record.detailRvwReason);
}
@ -747,6 +867,26 @@ const GroupLeader: React.FC = () => {
dataIndex: 'companyName',
width: 110,
fixed: 'left',
render: (_: any, record: any) => {
if (record.problemInfoList != null) {
let count = 0;
record.problemInfoList.forEach((ele: any) => {
if (ele.problemType == 1) {//MAC地址重复
count += 1;
}
});
if (count > 0) {
return (
<>
{_}
{<MACAddressPrompt type='other' companyName={_} />}
</>
)
}
return _;
}
return _;
}
},
{
title: '商务分',
@ -827,6 +967,23 @@ const GroupLeader: React.FC = () => {
if (valid == 0 && !resultDisabledStatus) {//应答是否有效为否并且当前是编辑状态自动触发
isEmpty(record.winnerCandidate) ? record.winnerCandidate = 'no' : null
}
/**
* 2022.5.9 zhoujianlong 增加MAC地址重复供应商不能将中标候选人选为的校验
*/
if (!confirmSubmitStatus && record.problemInfoList != null) {
let count = 0;
record.problemInfoList.forEach((ele: any) => {
if (ele.problemType == 1) {//MAC地址重复
count += 1;
}
});
if (count > 0) {
if (record.winnerCandidate == 'yes') {
message.info(`${record.companyName}与其他供应商MAC地址相同不可通过审核结果`);
record.winnerCandidate = 'no'
}
}
}
record.answerValid = valid
return rvwResultRender(_, record.detailRvwReason);
}

View File

@ -12,6 +12,7 @@ import { btnAuthority } from '@/utils/authority';
import WebOffice0609, { WebOfficeRefProps } from '@/pages/webOffice/weboffice0609';
import ReviewReportUpload from '@/utils/ReviewReportUpload';
import { getFileListByBid } from '@/utils/DownloadUtils';
import MACAddressPrompt from '@/pages/Evaluation/BidControl/BidControlManager/components/MACAddressPrompt';
const { Panel } = Collapse;
const { TextArea } = Input;
const { Paragraph, Text } = Typography;
@ -99,6 +100,26 @@ const Jury: React.FC = () => {
title: '供应商名称',
dataIndex: 'companyName',
width: 110,
render: (_: any, record: any) => {
if (record.problemInfoList != null) {
let count = 0;
record.problemInfoList.forEach((ele: any) => {
if (ele.problemType == 1) {//MAC地址重复
count += 1;
}
});
if (count > 0) {
return (
<>
{_}
{<MACAddressPrompt type='other' companyName={_} />}
</>
)
}
return _;
}
return _;
}
},
{
title: `报价(${quotationMethod}`,
@ -205,6 +226,26 @@ const Jury: React.FC = () => {
title: '供应商名称',
dataIndex: 'companyName',
width: 110,
render: (_: any, record: any) => {
if (record.problemInfoList != null) {
let count = 0;
record.problemInfoList.forEach((ele: any) => {
if (ele.problemType == 1) {//MAC地址重复
count += 1;
}
});
if (count > 0) {
return (
<>
{_}
{<MACAddressPrompt type='other' companyName={_} />}
</>
)
}
return _;
}
return _;
}
},
{
title: '商务分',
@ -291,6 +332,26 @@ const Jury: React.FC = () => {
title: '供应商名称',
dataIndex: 'companyName',
width: 210,
render: (_: any, record: any) => {
if (record.problemInfoList != null) {
let count = 0;
record.problemInfoList.forEach((ele: any) => {
if (ele.problemType == 1) {//MAC地址重复
count += 1;
}
});
if (count > 0) {
return (
<>
{_}
{<MACAddressPrompt type='other' companyName={_} />}
</>
)
}
return _;
}
return _;
}
},
{
title: '报价总金额净价(元)',
@ -353,6 +414,26 @@ const Jury: React.FC = () => {
title: '供应商名称',
dataIndex: 'companyName',
width: 110,
render: (_: any, record: any) => {
if (record.problemInfoList != null) {
let count = 0;
record.problemInfoList.forEach((ele: any) => {
if (ele.problemType == 1) {//MAC地址重复
count += 1;
}
});
if (count > 0) {
return (
<>
{_}
{<MACAddressPrompt type='other' companyName={_} />}
</>
)
}
return _;
}
return _;
}
},
{
title: '商务分',

View File

@ -11,6 +11,7 @@ import { btnAuthority } from '@/utils/authority';
import WebOffice0609, { WebOfficeRefProps } from '@/pages/webOffice/weboffice0609';
import ReviewReportUpload from '@/utils/ReviewReportUpload';
import { getFileListByBid } from '@/utils/DownloadUtils';
import MACAddressPrompt from '@/pages/Evaluation/BidControl/BidControlManager/components/MACAddressPrompt';
const { Panel } = Collapse;
const { Paragraph, Text } = Typography;
@ -101,6 +102,26 @@ const Manager: React.FC = () => {
title: '供应商名称',
dataIndex: 'companyName',
width: 110,
render: (_: any, record: any) => {
if (record.problemInfoList != null) {
let count = 0;
record.problemInfoList.forEach((ele: any) => {
if (ele.problemType == 1) {//MAC地址重复
count += 1;
}
});
if (count > 0) {
return (
<>
{_}
{<MACAddressPrompt type='other' companyName={_} />}
</>
)
}
return _;
}
return _;
}
},
{
title: `报价(${quotationMethod}`,
@ -207,6 +228,26 @@ const Manager: React.FC = () => {
title: '供应商名称',
dataIndex: 'companyName',
width: 110,
render: (_: any, record: any) => {
if (record.problemInfoList != null) {
let count = 0;
record.problemInfoList.forEach((ele: any) => {
if (ele.problemType == 1) {//MAC地址重复
count += 1;
}
});
if (count > 0) {
return (
<>
{_}
{<MACAddressPrompt type='other' companyName={_} />}
</>
)
}
return _;
}
return _;
}
},
{
title: '商务分',
@ -293,6 +334,26 @@ const Manager: React.FC = () => {
title: '供应商名称',
dataIndex: 'companyName',
width: 210,
render: (_: any, record: any) => {
if (record.problemInfoList != null) {
let count = 0;
record.problemInfoList.forEach((ele: any) => {
if (ele.problemType == 1) {//MAC地址重复
count += 1;
}
});
if (count > 0) {
return (
<>
{_}
{<MACAddressPrompt type='other' companyName={_} />}
</>
)
}
return _;
}
return _;
}
},
{
title: '报价总金额净价(元)',
@ -355,6 +416,26 @@ const Manager: React.FC = () => {
title: '供应商名称',
dataIndex: 'companyName',
width: 110,
render: (_: any, record: any) => {
if (record.problemInfoList != null) {
let count = 0;
record.problemInfoList.forEach((ele: any) => {
if (ele.problemType == 1) {//MAC地址重复
count += 1;
}
});
if (count > 0) {
return (
<>
{_}
{<MACAddressPrompt type='other' companyName={_} />}
</>
)
}
return _;
}
return _;
}
},
{
title: '商务分',

View File

@ -0,0 +1,98 @@
import React, { useEffect, useState } from 'react';
import { Modal, Typography } from 'antd';
import { createMACInfo, getMACInfo } from '../service';
interface SupplierCommitmentProps {
projectId: string;
callback: () => void;
}
/**
* 上传应答文件-供应商承诺书同意
* @param props
* @returns
*/
const SupplierCommitment: React.FC<SupplierCommitmentProps> = (props) => {
const { projectId, callback } = props;
const { warning } = Modal;
const { Text } = Typography;
const [time, setTime] = useState<number>(10);
const [btnLoading, setBtnLoading] = useState<boolean>(false);
const [visible, setVisible] = useState<boolean>(false);
useEffect(() => {
//查询供应商承诺书状态
getMACInfo({ tpId: projectId }).then(res => {
if (res?.code == 200) {
const data = res?.data;
if (data) {//已同意
callback();
} else {
setVisible(true);//未同意
}
}
})
}, []);
useEffect(() => {
let timeInteval: any
if (visible) {
timeInteval = setInterval(() => { // 倒计时
setTime(n => {
if (n == 1) {
clearInterval(timeInteval)
}
return n - 1;
})
}, 1000);
} else {
clearInterval(timeInteval);
}
return () => {
clearInterval(timeInteval);
}
}, [visible]);
const onCancel = () => {
warning({
title: '请先同意承诺书内容',
content: null,
centered: true,
});
}
const onOk = () => {
setBtnLoading(true);
//同意承诺书
createMACInfo({ projectId: projectId }).then(res => {
if (res?.code == 200) {
setVisible(false);
callback();
}
}).finally(() => {
setBtnLoading(false);
})
}
return (
<Modal
destroyOnClose
visible={visible}
maskClosable={false}
keyboard={false}
closable={false}
centered
width={600}
onOk={onOk}
okText={time !== 0 ? "同意(" + time + "s)" : "同意"}
okButtonProps={{
disabled: time !== 0,
loading: btnLoading,
}}
bodyStyle={{ padding: 40 }}
onCancel={onCancel}
>
<Text strong style={{ fontSize: 16 }}>IPMAC地址校验MAC地址相同/</Text>
</Modal>
);
};
export default SupplierCommitment;

View File

@ -11,6 +11,7 @@ import { btnAuthority } from '@/utils/authority';
import { verificationSupplier } from '@/utils/IpassVerification'
import { ExclamationCircleOutlined } from '@ant-design/icons';
import { getStatusByProId } from '@/services/downLoad';
import SupplierCommitment from './components/SupplierCommitment';
const { confirm } = Modal;
@ -51,6 +52,7 @@ const Index: React.FC<{}> = () => {
const [isModalVisible, setIsModalVisible] = useState<boolean>(false);
const [timeDateList, setTimeDateList] = useState([]);
const [currentDateList, setCurrentDateList] = useState<any>();
const [isInit, setIsInit] = useState<boolean>(false);//是否初始化列表-供应商承诺书用
const columns: any[] = [ // 列表数据
{
@ -289,7 +291,7 @@ const Index: React.FC<{}> = () => {
idArr.push(id)
getCodeInfo(idArr).then((res) => {
if (res.code == 200) {
if(res?.data[0]){
if (res?.data[0]) {
setIpassCode(res.data[0].organizationCode)
}
}
@ -404,7 +406,7 @@ const Index: React.FC<{}> = () => {
const onUploadError = (resumable: any) => {
if (resumable == '超过截止时间') {
message.error('已超过截止时间')
} else if(resumable == '撤销后再上传'){
} else if (resumable == '撤销后再上传') {
message.error('您已上传应答文件,需撤销后再上传!')
setUploadVisible(false)
getList()
@ -427,7 +429,7 @@ const Index: React.FC<{}> = () => {
const getCurrent = () => {
getCurrentTime().then((res) => {
if (res.code == 200) {
let currentTiem = new Date(res.data.replace(/-/g,'/')).getTime()
let currentTiem = new Date(res.data.replace(/-/g, '/')).getTime()
setTimestamp(currentTiem)
}
})
@ -447,12 +449,12 @@ const Index: React.FC<{}> = () => {
})
}
const handleTimeInterval= ()=>{ // 倒计时
if(dateList.length>0 && timestamp>0){
setTimestamp(timestamp+1000);
const handleTimeInterval = () => { // 倒计时
if (dateList.length > 0 && timestamp > 0) {
setTimestamp(timestamp + 1000);
let newTimeDateList: any = [];
dateList.map((item:any,index:any)=>{
if(item?.endDate && item?.endDate!=""&&item?.endDate!=null){
dateList.map((item: any, index: any) => {
if (item?.endDate && item?.endDate != "" && item?.endDate != null) {
newTimeDateList.push(showTimeDetail(item?.endDate));
}
})
@ -466,22 +468,24 @@ const Index: React.FC<{}> = () => {
});
useEffect(() => {
getList();
getCurrent();
timeInteval = setInterval(()=>{ // 倒计时
savedCallback.current();
},1000);
if (isInit) {
getList();
getCurrent();
timeInteval = setInterval(() => { // 倒计时
savedCallback.current();
}, 1000);
}
return ()=>{
return () => {
clearInterval(timeInteval);
if(task){
if (task) {
clearInterval(task)
}
}
}, []);
}, [isInit]);
const showTimeDetail = (endDate: any) => {
let endtime = new Date(endDate.replace(/-/g,'/')); //定义结束时间
let endtime = new Date(endDate.replace(/-/g, '/')); //定义结束时间
let lefttime = endtime.getTime() - timestamp; //距离结束时间的毫秒数
let returnResult = "";
if (lefttime > 0) {
@ -522,9 +526,9 @@ const Index: React.FC<{}> = () => {
<Panel header={item.sectionName} key={index}>
<div className="table-mess">
<span className="f12 mess">{item.endDate}</span>
<span className="f12 mess">{ currentDateList }</span>
<span className="f12 mess">{currentDateList}</span>
<span className="tr f12 mess">
<span className="red">{timeDateList.length>0 ? timeDateList[index]:null}</span>
<span className="red">{timeDateList.length > 0 ? timeDateList[index] : null}</span>
{
item.state == '0' && timestamp > 0 && new Date(item.startDate.replaceAll("-", "/")).getTime() < timestamp && new Date(item.endDate.replaceAll("-", "/")).getTime() > timestamp ?
<Button
@ -564,32 +568,32 @@ const Index: React.FC<{}> = () => {
}
</div>
{
uploadVisible?
<Modal // 批量上传
title="文件上传"
visible={uploadVisible}
onCancel={closeModal}
width={800}
centered
style={{ maxHeight: modalHeight }}
bodyStyle={{ maxHeight: modalHeight - 107, overflowY: 'auto' }}
footer={[<Button onClick={() => closeModal()}></Button>]}
>
<ReactResumableJs
query={{ 'relativePath': filePath, 'Tfile': Tfile, 'Tuid': uuid }}
maxFiles={1}
fileAccept={fileT}
endTime={endTime}
currentDate={currentDate}
onUploadSuccess={onUploadSuccess.bind(this)}
onUploadError={onUploadError.bind(this)}
onFileAdded={(file: any, resumable: any) => { onFileAdded(file, resumable) }}
onPauseUpload={(file: any, resumable: any) => { onPauseUpload(file, resumable) }}
onResumeUpload={(file: any, resumable: any) => { onResumeUpload(file, resumable) }}
onCancelUpload={(file: any, resumable: any) => { onCancelUpload(file, resumable) }}
service="/api/core-service-ebtp-updownload/v1/hulk/upload"
/>
</Modal>:null
uploadVisible ?
<Modal // 批量上传
title="文件上传"
visible={uploadVisible}
onCancel={closeModal}
width={800}
centered
style={{ maxHeight: modalHeight }}
bodyStyle={{ maxHeight: modalHeight - 107, overflowY: 'auto' }}
footer={[<Button onClick={() => closeModal()}></Button>]}
>
<ReactResumableJs
query={{ 'relativePath': filePath, 'Tfile': Tfile, 'Tuid': uuid }}
maxFiles={1}
fileAccept={fileT}
endTime={endTime}
currentDate={currentDate}
onUploadSuccess={onUploadSuccess.bind(this)}
onUploadError={onUploadError.bind(this)}
onFileAdded={(file: any, resumable: any) => { onFileAdded(file, resumable) }}
onPauseUpload={(file: any, resumable: any) => { onPauseUpload(file, resumable) }}
onResumeUpload={(file: any, resumable: any) => { onResumeUpload(file, resumable) }}
onCancelUpload={(file: any, resumable: any) => { onCancelUpload(file, resumable) }}
service="/api/core-service-ebtp-updownload/v1/hulk/upload"
/>
</Modal> : null
}
<Modal // 撤回
width={300}
@ -626,6 +630,7 @@ const Index: React.FC<{}> = () => {
>
<p></p>
</Modal>
<SupplierCommitment projectId={projectId} callback={() => { setIsInit(true) }} />
</>
)
}

View File

@ -45,22 +45,35 @@ export async function saveUploadLog(data: any) { // 开始上传给后台做记
* @param data
* @returns
*/
export async function getSupplierBlack(data: any) {
export async function getSupplierBlack(data: any) {
return request('/api/biz-service-ebtp-bid/v1/supplier/info/getSupplierBlack', {
method: 'post',
data: data
method: 'post',
data: data
});
}
export async function getCurrentTime() { // 获取当前时间戳
  return request('/api/biz-service-ebtp-extend/v1/timeService/getServiceTime', {
    method: 'get',
  });
export async function getCurrentTime() { // 获取当前时间戳
return request('/api/biz-service-ebtp-extend/v1/timeService/getServiceTime', {
method: 'get',
});
}
export async function getTendererFileStatus(data: any) { // 查看是否已经上传投标文件
  return request('/api/biz-service-ebtp-resps/v1/tfile/getTendererFileStatus', {
    method: 'post',
    data: data
  });
export async function getTendererFileStatus(data: any) { // 查看是否已经上传投标文件
return request('/api/biz-service-ebtp-resps/v1/tfile/getTendererFileStatus', {
method: 'post',
data: data
});
}
export async function getMACInfo(params: any) { //查询供应商承诺书同意状态
return request('/api/biz-service-ebtp-tender/v1/confirmMacInfo/queryCheck', {
method: 'post',
params: params,
});
}
export async function createMACInfo(data: any) { //供应商承诺书同意
return request('/api/biz-service-ebtp-tender/v1/confirmMacInfo/create', {
method: 'post',
data: data
});
}

View File

@ -8,6 +8,7 @@ import ProList from '@ant-design/pro-list';
import TableLook from './TableLook';
import { getStatusByProId } from '@/services/downLoad';
import { ExclamationCircleOutlined } from '@ant-design/icons';
import SupplierCommitment from '@/pages/Tender/UploadResponse/components/SupplierCommitment';
const Index: React.FC<{}> = () => {
let projectId = getProId()
@ -16,6 +17,8 @@ const Index: React.FC<{}> = () => {
const [supplierStatus, setSupplierStatus] = useState<boolean>(false);
// 提示信息显隐
const [tip, setTip] = useState<boolean>(true);
//是否初始化列表-供应商承诺书用
const [isInit, setIsInit] = useState<boolean>(false);
/**
* 根据项目id获取供应商资质库信息引用状态
@ -64,42 +67,45 @@ const Index: React.FC<{}> = () => {
</Row>
</div>
</div>
<ProList
className="pro-list"
rowKey="bsId"
params={{ "projectId": projectId }}
request={async (params) =>
await getPackages(params).then((res) => {
if (res.code == 200) {
let data = res.data;
// setDateList(res.data.records)
{isInit && (
<ProList
className="pro-list"
rowKey="bsId"
params={{ "projectId": projectId }}
request={async (params) =>
await getPackages(params).then((res) => {
if (res.code == 200) {
let data = res.data;
// setDateList(res.data.records)
return Promise.resolve({
data: listRender(data.records),
success: res.success,
total: res.data.total,
current: res.data.current,
});
}
return Promise.resolve({
data: listRender(data.records),
success: res.success,
total: res.data.total,
current: res.data.current,
data: [],
success: false,
total: 0,
current: 1,
});
}
return Promise.resolve({
data: [],
success: false,
total: 0,
current: 1,
});
})
}
pagination={{
defaultPageSize: 10,
showSizeChanger: true,
}}
expandable={{ expandedRowKeys, onExpandedRowsChange: setExpandedRowKeys, onExpand: changeList }}
// dataSource={listDate}
metas={{
title: {},
content: {},
description: {}
}}
/>
})
}
pagination={{
defaultPageSize: 10,
showSizeChanger: true,
}}
expandable={{ expandedRowKeys, onExpandedRowsChange: setExpandedRowKeys, onExpand: changeList }}
// dataSource={listDate}
metas={{
title: {},
content: {},
description: {}
}}
/>
)}
<SupplierCommitment projectId={projectId} callback={() => { setIsInit(true) }} />
</div>
</>
)