diff --git a/package.json b/package.json index a9eaec8..cbf3167 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "classnames": "^2.2.6", "dva": "^2.4.0", "echarts": "^5.2.2", + "echarts-for-react": "^3.0.2", "lodash": "^4.17.11", "moment": "^2.29.1", "omit.js": "^2.0.2", diff --git a/src/assets/supplierRisk/empty_data.png b/src/assets/supplierRisk/empty_data.png new file mode 100644 index 0000000..b8dddda Binary files /dev/null and b/src/assets/supplierRisk/empty_data.png differ diff --git a/src/components/BiddingRoom/index.js b/src/components/BiddingRoom/index.js index 0a8ef57..393f814 100644 --- a/src/components/BiddingRoom/index.js +++ b/src/components/BiddingRoom/index.js @@ -7,7 +7,7 @@ import { routerRedux } from 'dva/router'; import React, { useState, useEffect, useReducer } from 'react'; import { getSessionUserData, getRoomId, getProMethod, getSessionRoleData, getIPassDecode, getDefId, getProId } from '@/utils/session'; import { getURLInformation } from '@/utils/CommonUtils'; -import { getLeader, isShowResult, isShowCount, getErrorStatus, getRiskStatus } from './service'; +import { getLeader, isShowResult, isShowCount, getErrorStatus, getRiskStatus, isShowRiskModal, saveConfirm, isLeaderConfirm } from './service'; import logo from '@/images/opening/logo.svg' import InstantMessage from './components/InstantMessage' import { DownOutlined, UserOutlined, UserSwitchOutlined, CarryOutOutlined, HomeOutlined } from '@ant-design/icons'; @@ -17,6 +17,7 @@ import { ExclamationCircleOutlined } from '@ant-design/icons'; import { getRoomDataById } from '@/services/common'; +import RiskModal from '../RiskModal'; const BiddingRoom = (props) => { //获取采购方式 @@ -34,6 +35,10 @@ const BiddingRoom = (props) => { //获取评审室id const roomId = getRoomId(); const [list, setList] = useState(); + //风险提示文字弹窗控制 + const [riskVisible, setRiskVisible] = useState(false); + //评审结果提示文字还是进入评审室提示文字 + const [isResult, setIsResult] = useState(false); const [selectedPath, setSelectedPath] = useState(window.location.pathname.replace('ReviewResults/Jury', 'ReviewResults').replace('ReviewResults/GroupLeader', 'ReviewResults')); // const [risky, riskySet] = useState(); //字段类型(两种) 评标,评审 @@ -56,7 +61,7 @@ const BiddingRoom = (props) => { }, { id: 2, - path: "/EvaRoom/Eva", + path: "/EvaRoom/Eva/", text: `${sectionTypeThree}进展` }, { @@ -97,7 +102,7 @@ const BiddingRoom = (props) => { }, { id: 2, - path: "/EvaRoom/Eva", + path: "/EvaRoom/Eva/", text: sectionTypeTwo }, { @@ -137,7 +142,7 @@ const BiddingRoom = (props) => { }, { id: 2, - path: "/EvaRoom/Eva", + path: "/EvaRoom/Eva/", text: "项目评审" }, { @@ -234,12 +239,19 @@ const BiddingRoom = (props) => { //专家角色评审结果路由确定 const expertClickResult = async () => { - return await getLeader(roomId).then(res => { + return await getLeader(roomId).then(async res => { if (res?.code == 200) { if (res?.data == "Review") { return "/EvaRoom/Evaluation/expert/ReviewResults/Jury" } else { - return "/EvaRoom/Evaluation/expert/ReviewResults/GroupLeader" + const result = await isLeaderConfirm({ assessRoomId: roomId });//供应商股权关系-专家组长是否确认风险 + if (result?.success && result?.data) { + return "/EvaRoom/Evaluation/expert/ReviewResults/GroupLeader" + } else { + setIsResult(true) + setRiskVisible(true) + return false; + } } } else { return false @@ -283,6 +295,33 @@ const BiddingRoom = (props) => { return true //默认显示算术错误调整 } + //判断当前登录人是否弹出供应商关联风险信息 + const showRiskModal = async (resultClick) => { + if (role == "ebtp-agency-project-manager" || role == "ebtp-purchase" || role == "ebtp-expert") { + return await isShowRiskModal({ assessRoomId: roomId }).then(res => { + if (res?.code == 200 && res?.success) { + if (!res?.data) { + setIsResult(resultClick) + setRiskVisible(true) + } + return res?.data; + } + return true; + }) + } + return true; + } + //确认风险 + const confirmRisk = async () => { + return await saveConfirm({ assessRoomId: roomId }).then(res => { + if (res?.code == 200) { + return res?.data; + } else { + return false; + } + }) + } + //初始化数据 const listRender = async () => { // await isRisky(); @@ -304,7 +343,8 @@ const BiddingRoom = (props) => { JuryList.splice(5, 1) } } - + //弹出供应商关联风险信息 + await showRiskModal(false) //代理&项目经理 if (role == "ebtp-agency-project-manager" || role == "ebtp-purchase") {//代理和采购经理 setList(managerList); @@ -343,8 +383,8 @@ const BiddingRoom = (props) => { key={item.id} style={{ width: '100000px', - color: selectedPath == item.path ? "#FFFFFF" : "#b30000", - background: selectedPath == item.path ? "#b30000" : "#FFFFFF" + color: selectedPath == item.path || (item.path === '/EvaRoom/Eva/' && selectedPath.includes('/EvaRoom/Eva/')) ? "#FFFFFF" : "#b30000", + background: selectedPath == item.path || (item.path === '/EvaRoom/Eva/' && selectedPath.includes('/EvaRoom/Eva/')) ? "#b30000" : "#FFFFFF" }} onClick={() => { onclick(item.path, item.id) }} > @@ -358,6 +398,7 @@ const BiddingRoom = (props) => { })} + {riskVisible && { setRiskVisible(false); setSelectedPath(window.location.pathname) }} onSubmit={confirmRisk} isResult={isResult} role={role} />} {(MethodDict != "procurement_mode_5" && MethodDict != "procurement_mode_6") && role == "ebtp-supplier" ? null : } ); diff --git a/src/components/BiddingRoom/service.ts b/src/components/BiddingRoom/service.ts index 99a265a..2da7421 100644 --- a/src/components/BiddingRoom/service.ts +++ b/src/components/BiddingRoom/service.ts @@ -72,3 +72,24 @@ export async function getRiskStatus(params: any) { data: params }); } +// 供应商股权关系,专家及项目经理是否确认-智企查 +export async function isShowRiskModal(params: any) { + return request(`/api/biz-service-ebtp-resps/v1/risktendererwarning/haveWarningsOrConfirmed`, { + method: 'POST', + data: params + }); +} +// 供应商股权关系,专家及项目经理进入评审室确认风险-智企查 +export async function saveConfirm(params: any) { + return request(`/api/biz-service-ebtp-resps/v1/risktendererwarningConfirm/saveConfirm`, { + method: 'POST', + data: params + }); +} +// 供应商股权关系,专家组长是否确认风险-智企查 +export async function isLeaderConfirm(params: any) { + return request(`/api/biz-service-ebtp-resps/v1/risktendererwarning/haveWarningsHeadConfirmed`, { + method: 'POST', + data: params + }); +} diff --git a/src/components/EquityRelation/RelationCharts.tsx b/src/components/EquityRelation/RelationCharts.tsx new file mode 100644 index 0000000..4c5021a --- /dev/null +++ b/src/components/EquityRelation/RelationCharts.tsx @@ -0,0 +1,109 @@ +import ReactEcharts from 'echarts-for-react'; +import PropTypes from 'prop-types'; +import React, { useMemo } from 'react'; +/** + * 供应商股权关系-Echarts关系图 + * @param props + * @returns + */ +export default function RelationCharts(props: { linkData?: any[] | undefined; suppListTrans?: any[] | undefined; }) { + const { linkData = [], suppListTrans = [] } = props; + const option = { + title: { + text: '' + }, + color: '#EA8786', + tooltip: { + show: false, + }, + animationDurationUpdate: 1500, + animationEasingUpdate: 'quinticInOut', + series: [ + { + type: 'graph', + layout: 'force', + edgeSymbol: ['', 'arrow'], + label: { + normal: { + show: true, + position: 'top',//设置label显示的位置 + textStyle: { + fontSize: '12px' + }, + } + }, + symbolSize: (value: any, params: { data: { category: any; }; }) => { + switch (params.data.category) { + case 0: return 50; + case 1: return 30; + case 2: return 20; + case 3: return 30; + default: return 10; + } + }, + draggable: true, + data: suppListTrans, + force: { + edgeLength: 200, + repulsion: 3000, + gravity: 0.2, + }, + Symbol: 'circle', + // symbol:function(x,y) { + // switch (y.data.category) { + // case 1: return 'circle'; + // // case 1: return 'roundRect'; + // case 2: return 'circle'; + // default: 'circle'; + // } + // }, + links: linkData, + roam: true, + zoom: 0.8, + itemStyle: { + normal: { + color: function (params: { data: { category: any; }; }) { + // console.log('--params:', params) + // if + switch (params.data.category) { + case 1: return '#EA8786'; + case 2: return '#128bed'; + case 3: return '#f39800'; + default: return '#EA8786'; + } + }, + } + }, + lineStyle: { + color: '#EA8786', + // color: 'source', + // curveness: 0.2 + }, + edgeLabel: { + width: '80', + overflow: 'break', + }, + } + ] + } + let onclick = { + 'click': (e: { data: { isProvider: number; code: any; }; }) => { + if (e.data.isProvider == 1) { + // windowOpen(`/supplier-info/supplier-detail/${e.data.code}`, "_blank") + // alert(e.data.code); + } + } + } + return ( + <> + { + suppListTrans.length > 0 && useMemo(() => (), [suppListTrans]) + } + + ) + +} +RelationCharts.propTypes = { + linkData: PropTypes.array, + suppListTrans: PropTypes.array, +}; \ No newline at end of file diff --git a/src/components/EquityRelation/index.tsx b/src/components/EquityRelation/index.tsx new file mode 100644 index 0000000..d902ba4 --- /dev/null +++ b/src/components/EquityRelation/index.tsx @@ -0,0 +1,190 @@ +import { Checkbox, Spin } from 'antd'; +import { CheckboxChangeEvent } from 'antd/lib/checkbox'; +import { CheckboxValueType } from 'antd/lib/checkbox/Group'; +import { multiply } from 'lodash'; +import React, { useEffect, useRef, useState } from 'react'; +import RelationCharts from './RelationCharts'; +import empty_data from '@/assets/supplierRisk/empty_data.png'; +/** + * 供应商股权关系-关系图 + * @returns + */ +const EquityRelation: React.FC<{ result: any, suppCodeList: any[] }> = (props) => { + const { result, suppCodeList } = props; + const plainOptions = [ + { label: '法人', value: '6' }, + { label: '分支机构', value: '5' }, + { label: '投资', value: '1' }, + { label: '任职', value: '2' }, + { label: '疑似地址', value: '4' }, + { label: '疑似电话', value: '3' }, + { label: '疑似邮箱', value: '7' }, + ]; + const [linkData, setLinkData] = useState(); + const [suppListTrans, setSuppListTrans] = useState([]); + const [checkedAll, setCheckedAll] = useState(true); + const [checked, setChecked] = useState([]); + const resDataRef = useRef(); + function onCheckedAllChange(e: CheckboxChangeEvent) { + if (e.target.checked) { + setCheckedAll(e.target.checked); + setChecked([]); + filterData([]); + } + }; + function onCheckedChange(checkedValues: CheckboxValueType[]) { + setChecked(checkedValues); + setCheckedAll(checkedValues.length == 0); + filterData(checkedValues); + }; + function doType(str: string) { + let newArr = str.split(","); + let typeCn = ""; + for (let i = 0; i < newArr.length; i++) { + if (newArr[i] == '1') { + typeCn += '投资' + } else if (newArr[i] == '3') { + typeCn += '企业疑似电话' + } else if (newArr[i] == '4') { + typeCn += '企业疑似地址' + } else if (newArr[i] == '5') { + typeCn += '分支机构' + } else if (newArr[i] == '6') { + typeCn += '法人' + } else if (newArr[i] == '7') { + typeCn += '企业疑似邮箱' + } else { + typeCn += `${newArr[i]}` + } + } + return typeCn; + } + //选择后数据筛选 + function filterData(selected: any[]) { + if (resDataRef.current) { + if (selected.length > 0) { + const filterLinks = resDataRef.current.links.filter((item: any) => selected.includes(item.type)); + const i_links: string[] = []; + for (let i = 0, length = filterLinks.length; i < length; i++) { + i_links.push(filterLinks[i].from); + i_links.push(filterLinks[i].to); + } + const r_links = [...new Set(i_links)];//数组去重 + const filterNodes = resDataRef.current.nodes.filter((item: any) => r_links.includes(item.id)); + dataHandle(filterNodes, filterLinks);//处理数据并刷新 + } else { + dataHandle(resDataRef.current.nodes, resDataRef.current.links); + } + } + } + //数据处理 + function dataHandle(nodes: any[] | undefined, links: any[] | undefined) { + //处理右侧数据 + const valueList = nodes ? nodes : [] + valueList.map((item) => { + Object.assign(item, { + name: item.name ? item.name : item.properties?.samevalue ? item.properties?.samevalue : '暂无信息', + // category: item.isProvider == 1 ? 1 : 2, + category: suppCodeList.findIndex(ite => ite.companyName == item.name) !== -1 ? 3 : (item.type == 1 ? 1 : 2),//从珊珊拿全部供应商 + id: item.id, + }) + return item + }) + setSuppListTrans([...valueList]) + let mapList = links ? links : [] + let copeLink1 = JSON.parse(JSON.stringify(mapList)) + if (copeLink1.length > 0) { + for (let i = 0; i < copeLink1.length; i++) { + if (copeLink1[i].type == 2) { + copeLink1[i].type = copeLink1[i].properties.position_desc + } else { + if (copeLink1[i].type == 1) { + copeLink1[i].type = '投资' + multiply(copeLink1[i].properties.conprop, 100) + '%' + } else { + copeLink1[i].type = doType(copeLink1[i].type) + } + } + //手动去重 + for (let j = i + 1; j < copeLink1.length; j++) { + if (copeLink1[i].from == copeLink1[j].from && copeLink1[i].to == copeLink1[j].to && copeLink1[j].type) { + //type=2 需提前处理 + if (copeLink1[j].type == 1) { + copeLink1[j].type = '投资' + multiply(copeLink1[j].properties.conprop, 100) + '%' + } else if (copeLink1[j].type == 2) { + copeLink1[i].type = copeLink1[i].type + ',' + copeLink1[j].properties.position_desc + copeLink1[j].type = '' + } else { + if (copeLink1[j].type != 2) { + copeLink1[j].type = doType(copeLink1[j].type) + } + } + //拼接相同类型的type + if (copeLink1[i].type.substring(copeLink1[i].type.length - 1, copeLink1[i].type.length) == ',') { + copeLink1[i].type = copeLink1[i].type + copeLink1[j].type + } else { + copeLink1[i].type = copeLink1[i].type + ',' + copeLink1[j].type + } + copeLink1[j].type = '' + } else { + //type=1 需提前处理 + if (copeLink1[j].type == 1) { + copeLink1[j].type = '投资' + multiply(copeLink1[j].properties.conprop, 100) + '%,' + } else if (copeLink1[j].type == 2) { + copeLink1[j].type = copeLink1[j].properties.position_desc + } else { + if (copeLink1[j].type != 2) { + copeLink1[j].type = doType(copeLink1[j].type) + } + } + continue; + } + } + } + } + copeLink1.map((item: any) => { + Object.assign(item, { + source: item.from, + target: item.to, + label: { + show: true, + fontSize: 12, + verticalAlign: 'bottom', + formatter: () => { + return item.type + }, + }, + id: item.id, + flag: false + }) + return item + }) + setLinkData(copeLink1) + } + useEffect(() => { + if (result && result?.nodes && result.nodes.length > 0 && suppCodeList && suppCodeList.length > 0) { + resDataRef.current = result; + dataHandle(result.nodes, result.links); + } + }, [result, suppCodeList]) + return ( + <> +
+ 全部 + +
+ { + suppListTrans.length > 0 ? ( +
+ +
+ ) : ( +
+ +
+ ) + } + + ); +}; + +export default EquityRelation; diff --git a/src/components/RiskModal/index.tsx b/src/components/RiskModal/index.tsx new file mode 100644 index 0000000..fd91b8f --- /dev/null +++ b/src/components/RiskModal/index.tsx @@ -0,0 +1,53 @@ +import React from 'react'; +import { Button, Modal } from 'antd'; +import { history } from 'umi'; + +interface RiskModalProps { + modalVisible: boolean; + onCancel: () => void; + onSubmit?: () => Promise;//确认后调用接口 + isResult: boolean; + role: string; +} +/** + * 供应商股权关系,风险弹窗 + * @param props + * @returns + */ +const RiskModal: React.FC = (props) => { + const { modalVisible, onCancel, isResult, role, onSubmit = () => Promise } = props; + const onOk = async () => { + if (role == "ebtp-agency-project-manager" || role == "ebtp-purchase") {//代理或采购经理 + if (!isResult) { + history.push('/EvaRoom/Evaluation/BidControl/BidControlManager?n=1'); + } + } else if (role == "ebtp-expert") {//专家 + history.push('/EvaRoom/Evaluation/BidControl/Jury?n=1'); + } + if (!isResult) { + const result = await onSubmit(); + if (result) onCancel(); + } else { + onCancel(); + } + } + + return ( + onCancel()} + bodyStyle={{ padding: '40px 40px 30px' }} + centered + maskClosable={false} + footer={null} + > +
+

{((role == "ebtp-agency-project-manager") && isResult) ? "供应商关联关系存在疑似违规行为,请确保专家组长已确认风险!" : "供应商关联关系存在疑似违规行为,请前往【风险点展示】界面查看风险!"}

+ +
+
+ ); +}; + +export default RiskModal; diff --git a/src/pages/BidEvaluation/manager.js b/src/pages/BidEvaluation/manager.js index 214650f..6fd40f3 100644 --- a/src/pages/BidEvaluation/manager.js +++ b/src/pages/BidEvaluation/manager.js @@ -119,6 +119,7 @@ class manager extends PureComponent { sessionStorage.setItem("groupId", record.chatGroupId) sessionStorage.setItem("expertGroupId", record.expertChatGroupId) sessionStorage.setItem("roomTypeByEva", getURLInformation("roomType")) + sessionStorage.setItem("sectionId", record.sectionId) this.setState({ loading: true }) await getQuotationMethodById(record.id) // this.props.dispatch(routerRedux.push('/ProjectLayout/EvaRoom')) diff --git a/src/pages/Evaluation/BidControl/BidControlManager/components/ZhiQiCha.tsx b/src/pages/Evaluation/BidControl/BidControlManager/components/ZhiQiCha.tsx new file mode 100644 index 0000000..c955ef2 --- /dev/null +++ b/src/pages/Evaluation/BidControl/BidControlManager/components/ZhiQiCha.tsx @@ -0,0 +1,273 @@ +import { getLeader } from "@/components/BiddingRoom/service"; +import EquityRelation from "@/components/EquityRelation"; +import { getURLInformation } from "@/utils/CommonUtils"; +import { getRoomId, getSessionProjectData, getSessionRoleData } from "@/utils/session"; +import { ExclamationCircleOutlined } from "@ant-design/icons"; +import ProTable, { EditableProTable, ProColumns } from "@ant-design/pro-table"; +import { Button, Col, Collapse, Form, Input, message, Modal, Radio, RadioChangeEvent, Row, Spin, Typography } from "antd"; +import React, { Fragment, useEffect, useState } from "react"; +import { getSuspectedViolation, leaderConfirm } from "../service"; + +/** + * 智企查-供应商关联关系疑似违规行为 + * @param props + * @returns + */ +const ZhiQiCha: React.FC<{}> = (props) => { + const title_style = { color: "#b30000", fontWeight: 700 }; + const options = [ + { label: '确认无风险', value: 0 }, + { label: '确认有风险', value: 1 }, + ]; + //是否展开智企查疑似关联关系 + const defaultZQCKey = getURLInformation('n') == '1' ? ['zhiqicha'] : [] + const { Paragraph, Text } = Typography; + const { TextArea } = Input; + const { confirm } = Modal; + const [form] = Form.useForm(); + //项目id 标段id 评审室id + const projectId = getSessionProjectData()?.id; + const sessionId = sessionStorage.getItem("sectionId"); + const roomId = getRoomId(); + //获取角色 + const role = getSessionRoleData().roleCode; + //专家组长填写的表格的供应商 + const [supplierTableData, setSupplierTableData] = useState([]); + //查询的供应商股权关系数据,确认数据。 + const [warningsData, setWarningsData] = useState(); + //是否是专家组长 + const [isLeader, setIsLeader] = useState(false);//true-是组长 false-不是组长或者不是专家 + //是否有风险 + const [isRisk, setIsRisk] = useState(false);//true-有风险 false-无风险 + //radio选择 + const [radioValue, setRadioValue] = useState(""); + //loading + const [loading, setLoading] = useState(true); + + const columns: ProColumns[] = [ + { + title: 供应商, + dataIndex: 'companyName', + key: 'companyName', + editable: false, + }, + { + title: 是否有风险, + dataIndex: 'isRisk', + key: 'isRisk', + valueType: 'radio', + valueEnum: { + "0": { text: '否' }, + "1": { text: '是' }, + }, + }, + { + title: 说明, + dataIndex: 'memo', + key: 'memo', + tooltip: "此项为选填", + fieldProps: { + maxLength: 100, + } + }, + ]; + const readOnlyColumns: ProColumns[] = [ + { + title: 供应商, + dataIndex: 'companyName', + key: 'companyName', + }, + { + title: 是否有风险, + dataIndex: 'isRisk', + key: 'isRisk', + render: (_: any, record: any) => ( + {record.isRisk == 1 ? "是" : record.isRisk == 0 ? "否" : "-"} + ), + }, + { + title: 说明, + dataIndex: 'memo', + key: 'memo', + }, + ]; + //获取智企查数据 + const getZQCData = () => { + let params = { + "tpId": projectId, + "sectionId": sessionId, + "assessRoomId": roomId, + } + // let params = { "tpId": "1625300469640114176", "sectionId": "1625300469648502784", "assessRoomId": "1628212227869454336" } + getSuspectedViolation(params).then(async res => {//获取数据 + if (res?.success) { + if (role == "ebtp-expert") { + const resp = await getLeader(roomId)//判断是否是专家组长 + setIsLeader(resp?.data == "ReviewLeader"); + } + setWarningsData(res?.data); + setSupplierTableData(res?.data?.riskSupplier != null ? res?.data?.riskSupplier.supplist?.map((item: any) => { item.isRisk = String(item.isRisk); return item }) : []); + setIsRisk(res?.data?.riskSupplier != null); + form.setFieldsValue(res?.data); + } + }).finally(() => { + setLoading(false); + }) + } + //专家组长保存 + const handleSave = () => { + let values = form.getFieldsValue(); + values["riskSupplier"] = { supplist: supplierTableData }; + values["headmanConfirmStatus"] = "0";//保存参数 + setLoading(true); + leaderConfirm(values).then(res => {//专家组长保存 + if (res?.success) { + message.success("保存成功!"); + getZQCData(); + } + }).finally(() => { + setLoading(false); + }) + } + //专家组长提交 + const handleSubmit = () => { + form.validateFields().then(values => { + let emptyItem = -1; + let yesLength = 0; + for (let i = 0, length = supplierTableData.length; i < length; i++) { + const item = supplierTableData[i]; + if (item.isRisk == null) { + emptyItem = i; + break; + } + if (item.isRisk == "1") { + yesLength += 1; + } + } + if (emptyItem != -1) { + message.warning(`供应商【${supplierTableData[emptyItem].companyName}】的【是否有风险】项未填写`); + return; + } + if ((values.headmanConfirm == 1) && (yesLength == 0)) { + message.warning("【确认有风险】情况下,需至少一家供应商的【是否有风险】项选择【是】"); + return; + } + values["riskSupplier"] = { supplist: supplierTableData }; + values["headmanConfirmStatus"] = "1";//确认参数 + confirm({ + title: '提交后不可修改,确认是否提交?', + icon: , + content: <>, + centered: true, + okText: "是", + cancelText: "否", + onOk() { + setLoading(true); + return leaderConfirm(values).then(res => {//专家组长提交 + if (res?.success) { + message.success("提交成功!"); + getZQCData(); + } + }).finally(() => { + setLoading(false); + }) + }, + onCancel() { }, + }); + }); + } + const onRadioChange = (e: RadioChangeEvent) => { + setRadioValue(e.target.value); + } + useEffect(() => { + getZQCData(); + }, []) + return ( + + + + +

供应商关联关系疑似违规行为

+
+
+ +
+
+ + 《中华人民共和国招标投标法》第三十二条规定:”投标人不得相互串通投标报价,不得排挤其他投标人的公平竞争,损害招标人或者其他投标人的合法权益。投标人不得与招标人串通投标,损害国家利益、社会公共利益或者他人的合法权益。” + + + 《中华人民共和国招标投标法实施条例》第三十四条规定:“与招标人存在利害关系可能影响招标公正性的法人、其它组织或者个人,不得参加投标。单位负责人为同一人或者存在控股关系、管理关系的不同单位,不得参加同一标段投标或者未划分标段的同一招标项目投标。违反前两款规定的,相关投标无效。” + + + 控股超过51%或股权关系分散的占股最大的股东都属于控股,请项目经理与评委给予注意! + + {isRisk && ( + 经智企查分析,{warningsData?.riskSupplier?.riskSuppInfoList?.map((item: any, index: any) => {index != 0 && }{item})}存在疑似关联关系,具体见左图。 + )} + {isRisk && isLeader && ( +
+ + + + + +