diff --git a/config/JuryRoom/router_menuJury.config.ts b/config/JuryRoom/router_menuJury.config.ts index ca1e891..9e6c9ae 100644 --- a/config/JuryRoom/router_menuJury.config.ts +++ b/config/JuryRoom/router_menuJury.config.ts @@ -38,6 +38,11 @@ export default [//评标 path: '/EvaRoom/Evaluation/projectManager/ReviewResults/Manager', component: './Evaluation/projectManager/ReviewResults/Manager', }, + //评审结果-线下评审-项目经理 + { + path: '/EvaRoom/Evaluation/projectManager/ReviewResults/ManagerEntry', + component: './Evaluation/projectManager/ReviewResults/ManagerEntry', + }, //评审结果-组长 { path: '/EvaRoom/Evaluation/expert/ReviewResults/GroupLeader', diff --git a/config/YuShen/router_yushen.ts b/config/YuShen/router_yushen.ts index 00f765c..21e0e43 100644 --- a/config/YuShen/router_yushen.ts +++ b/config/YuShen/router_yushen.ts @@ -39,7 +39,7 @@ export default //评委会设置 资审发售 项目经理 { path: '/ProjectLayout/ZYuShen/Tender/ProjectManager/JudgingPanel', - component: './Tender/ProjectManager/JudgingPanel/List' + component: './Tender/ProjectManager/JudgingPanel/List/preIndex' }, //澄清 资审发售 项目经理 { diff --git a/src/assets/signPen/signPen.png b/src/assets/signPen/signPen.png new file mode 100644 index 0000000..02aa52c Binary files /dev/null and b/src/assets/signPen/signPen.png differ diff --git a/src/assets/styles.module.less b/src/assets/styles.module.less new file mode 100644 index 0000000..2081384 --- /dev/null +++ b/src/assets/styles.module.less @@ -0,0 +1,31 @@ +/** +* 手写签名用 +*/ +.container { + top: 10%; + left: 10%; + width: 100%; + height: 50vh; +} + +.sigContainer { + width: 100%; + height: 100%; + margin: 0 auto; + background-color: #fff; + cursor: auto; +} + +.sigPointer { + width: 100%; + height: 100%; + margin: 0 auto; + background-color: #fff; + cursor: url("./signPen/signPen.png"),Crosshair; +} + +.sigPad { + width: 100%; + height: 100%; + background: #fff; +} diff --git a/src/components/BiddingRoom/index.js b/src/components/BiddingRoom/index.js index dc412ce..986f754 100644 --- a/src/components/BiddingRoom/index.js +++ b/src/components/BiddingRoom/index.js @@ -5,7 +5,7 @@ import styles from './index.less'; import { connect } from "dva"; import { routerRedux } from 'dva/router'; import React, { useState, useEffect, useReducer } from 'react'; -import { getSessionUserData, getRoomId, getProMethod, getSessionRoleData, getIPassDecode, getDefId, getProId } from '@/utils/session'; +import { getSessionUserData, getRoomId, getRoomStatus, getProMethod, getSessionRoleData, getIPassDecode, getDefId, getProId, getOfflineStatusById } from '@/utils/session'; import { getURLInformation } from '@/utils/CommonUtils'; import { getLeader, isShowResult, isShowCount, getErrorStatus, getRiskStatus, isShowRiskModal, saveConfirm, isLeaderConfirm } from './service'; import logo from '@/images/opening/logo.svg' @@ -34,8 +34,13 @@ const BiddingRoom = (props) => { let data = getSessionUserData(); //获取比选一阶段二次项目,自定义流程,当前供应商 const isBxOneSecondCustom = sessionStorage.getItem("isBxOneSecondCustom"); + //评审方式:状态:0-默认,1-已确认配置分工及组长 + const roomJuryConfigStatus = sessionStorage.getItem("roomJuryConfigStatus"); + //评审方式:0-线上、1-线下 + const roomReviewMethod = sessionStorage.getItem("roomReviewMethod"); //获取评审室id const roomId = getRoomId(); + const roomStatus = getRoomStatus(); const [list, setList] = useState(); //风险提示文字弹窗控制 const [riskVisible, setRiskVisible] = useState(false); @@ -96,6 +101,28 @@ const BiddingRoom = (props) => { path: "/EvaRoom/Evaluation/projectManager/ReviewResults/Manager", text: "评审结果" }] + //项目经理角色 + let managerOffList = [ + { + id: 1, + path: "/EvaRoom", + text: "基本信息" + }, + { + id: 2, + path: "/EvaRoom/BiddingDocumentsDecrypt", + text: `${responseType}文件查看` + }, + { + id: 3, + path: "/EvaRoom/Evaluation/BidControl/BidControlManager", + text: "风险点展示" + }, + { + id: 8, + path: "/EvaRoom/Evaluation/projectManager/ReviewResults/ManagerEntry", + text: "评审结果录入" + }] let JuryList = [ { id: 1, @@ -179,13 +206,25 @@ const BiddingRoom = (props) => { //评审结果页签点击事件 const onclick = async (path, id) => { + await getOfflineStatusById(roomId) if ((role == 'ebtp-agency-project-manager' || role == 'ebtp-purchase') && id == 8) { //代理&采购经理进入评审结果 - const success = await isClickResult(); - if (success) { - history.push({ pathname: path }); - setSelectedPath(path); + if (roomReviewMethod == 0){ + const success = await isClickResult(); + if (success) { + history.push({ pathname: path }); + setSelectedPath(path); + } else { + message.info("未到评审结果环节,无法进入评审结果") + } } else { - message.info("未到评审结果环节,无法进入评审结果") + console.log("roomJuryConfigStatus", roomJuryConfigStatus) + + if (roomJuryConfigStatus == 1) { + history.push({ pathname: path }); + setSelectedPath(path); + } else { + message.info("未到评审结果环节,无法进入评审结果") + } } } else if (role == 'ebtp-expert' && id == 8) {//专家进入评审结果 const success = await isClickResult(); @@ -246,14 +285,14 @@ const BiddingRoom = (props) => { if (res?.data == "Review") { return "/EvaRoom/Evaluation/expert/ReviewResults/Jury" } else { - const result = await isLeaderConfirm({ assessRoomId: roomId });//供应商股权关系-专家组长是否确认风险 - if (result?.success && result?.data) { + //TODO zyx暂时不需要const result = await isLeaderConfirm({ assessRoomId: roomId });//供应商股权关系-专家组长是否确认风险 + //TODO zyx暂时不需要if (result?.success && result?.data) { return "/EvaRoom/Evaluation/expert/ReviewResults/GroupLeader" - } else { - setIsResult(true) - setRiskVisible(true) - return false; - } + //TODO zyx暂时不需要} else { + //TODO zyx暂时不需要 setIsResult(true) + //TODO zyx暂时不需要 setRiskVisible(true) + //TODO zyx暂时不需要 return false; + //TODO zyx暂时不需要} } } else { return false @@ -347,7 +386,11 @@ const BiddingRoom = (props) => { } //代理&项目经理 if (role == "ebtp-agency-project-manager" || role == "ebtp-purchase") {//代理和采购经理 - setList(managerList); + if(true){ + setList(managerOffList); + }else { + setList(managerList); + } } else if (role == "ebtp-expert") {//专家 setList(JuryList) } else if (role == "ebtp-supplier") {//供应商 diff --git a/src/models/bidev.js b/src/models/bidev.js index d4d0e79..067150e 100644 --- a/src/models/bidev.js +++ b/src/models/bidev.js @@ -1,4 +1,4 @@ -import { fetchManagerList,openBizassessroom,resetVerificationCode,fetchJuryList,fetchSupplierList +import { fetchManagerList,openBizassessroom,openOffBizassessroom,resetVerificationCode,fetchJuryList,fetchSupplierList ,fetchJuryMemInfo,updateJuryMemInfo,validateVerificationCode,fetchbidslist ,fetchPreSupplierList,fetchPreList,fetchPreListt,bxmultifetchPreListt,pushRedirectRe,getCheckedByRoomId,checkOpenBidSupplier,zmmultiOpenBizassessroom } from '../services/bidev'; import { message } from 'antd'; @@ -43,6 +43,23 @@ export default { } callback(); }, + // 开启线下评审室 + *openOffBizassessroom({payload,callback}, { call, put }){ + const response =yield call(openOffBizassessroom,payload) + if(response?.code==200){ + // 查询招标代理列表 + const params={ + pageNo:1, + pageSize:10, + reviewMethod:1, + roomType: getURLInformation('roomType'), + tpId:getProId()//项目id + } + yield put({ type: 'fetchManagerList', payload: {...params} }); + message.success("开启成功!") + } + callback(); + }, // 开启评审室(多轮招募) *zmmultiOpenBizassessroom({payload,callback}, { call, put }){ const response =yield call(zmmultiOpenBizassessroom,payload) diff --git a/src/pages/Evaluation/expert/ReviewResults/GroupLeader/components/GroupLeader.tsx b/src/pages/Evaluation/expert/ReviewResults/GroupLeader/components/GroupLeader.tsx index 117f5fc..110048b 100644 --- a/src/pages/Evaluation/expert/ReviewResults/GroupLeader/components/GroupLeader.tsx +++ b/src/pages/Evaluation/expert/ReviewResults/GroupLeader/components/GroupLeader.tsx @@ -11,6 +11,8 @@ import { reviewReportExpertsConfirmed } from '../../Jury/service'; import { getDicData, getProMethod, getRoomId } from '@/utils/session'; import { btnAuthority } from '@/utils/authority'; import WebOffice0609, { WebOfficeRefProps } from '@/pages/webOffice/weboffice0609'; +import styles from '@/assets/styles.module.less' +import SignaturePad from 'react-signature-canvas' import SortEditableTable from './SortEditableTable'; import ReviewReportUpload from '@/utils/ReviewReportUpload'; import { ExclamationCircleOutlined } from '@ant-design/icons'; @@ -111,6 +113,10 @@ const GroupLeader: React.FC = () => { const [resultDisabledStatus, setResultDisabledStatus] = useState(false); //报价类型 true-百分比类型(折扣率,优惠率)false-数值类型(总价,单价) const [quotationMethod, setQuotationMethod] = useState(false); + //评审报告确认无误弹出窗 + const [visibleConfirm, setVisibleConfirm] = useState(false); + //鼠标指针ref + const pointRef = useRef() //评价方法 eval_method_1 最低价法 eval_method_2 综合评估法 const [evalMethodDict, setEvalMethodDict] = useState(''); //评审结果排序弹窗 @@ -1446,6 +1452,142 @@ const GroupLeader: React.FC = () => { setSpinning(false); }) } + + /** + * 评审报告确认无误(签字面板) + * zhoujianlong 2021.8.19 + * @returns + */ + const modalConfirm = () => { + //保存loading + const [loading, setLoading] = useState(false); + //关闭modal + const onCancel = () => { + init(); + setVisibleConfirm(false); + } + //canvas ref + let sigPad: any = {} + //手写签名存储 + const [saveTrimCanvas, setSaveTrimCanvas] = useState('') + const canvasBase64 = reviewReportData?.expertList?.[0]?.expertSign + useEffect(() => { + if(canvasBase64 != undefined){ + setSaveTrimCanvas(canvasBase64) + } + }, [canvasBase64]) + + /** + * 保存或发送调用接口 + * @params expertSign 签名产生的base64值 + * status true-保存 false-发送 + */ + const toSaveOrSend = (expertSign: string,status: boolean) => { + let params = { + expertOpinion: 1, + reportId: reviewReportData.id, + expertSign: expertSign + }; + if(status){ //判断是保存还是发送 + params["status"] = 0 + } + setLoading(true) + reviewReportExpertsConfirmed(params).then(res => { + if(res?.code == 200 && res?.success === true) { + commonMessage(res); + if(status) {} else { + onCancel(); + } + } + }).finally(() => { + setLoading(false) + }) + } + //提交 status true-保存 false-发送 + const submit = (status: boolean) => { + let emptyStatus = sigPad.isEmpty(); + if(emptyStatus) { + message.error("当前无签名内容,请先签名"); + return; + } + //得到画布 + let canvas = sigPad._canvas; + if (canvas.getContext) { + let ctx = canvas.getContext('2d'); + // 将canvas的透明背景设置成白色 + let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); + for(var i = 0; i < imageData.data.length; i += 4) { + // 当该像素是透明的,则设置成白色 + if(imageData.data[i + 3] == 0) { + imageData.data[i] = 255; + imageData.data[i + 1] = 255; + imageData.data[i + 2] = 255; + imageData.data[i + 3] = 255; + } + } + ctx.putImageData(imageData, 0, 0); + } + let imgUrl = sigPad.toDataURL('image/png',1); + setSaveTrimCanvas(imgUrl) + toSaveOrSend(imgUrl,status) + } + //clear + const clear = () => { + sigPad.clear(); + } + //SignaturePad ref + const refRender = (ref: any) => { + sigPad = ref //存储ref + if(ref != null) { + ref?.clear() + ref?.fromDataURL(saveTrimCanvas) + } + } + return ( + <> + submit(false)}> + 发送 + , + , + , + , + 提示:按住鼠标左键进行签名 + ]} + > + +
+
pointRef.current.className = styles.sigPointer} onMouseUp={() => pointRef.current.className = styles.sigContainer}> + +
+
+
+
+ + ) + } /** * 评审报告存在问题 @@ -1529,7 +1671,7 @@ const GroupLeader: React.FC = () => { ) } /** - * 评审报告确认无误 + * 评审报告确认无误(无需手写签名) */ const beConfirmed = () => { setReviewReportLoading(true); @@ -1544,6 +1686,14 @@ const GroupLeader: React.FC = () => { }) } + //确认无误的手写签名判断方法 + const toReportConfirm = () => { + if(String(reviewReportData?.signStatus) == '1') {//判断是否启用手写签名 1-是 0-否 + setVisibleConfirm(true); + } else { + beConfirmed(); + } + } const saveTable = (data: any, config: any) => { let form = config?.form; form.validateFields().then((res: any) => { @@ -1606,11 +1756,12 @@ const GroupLeader: React.FC = () => { value={supplierTableData} onChange={setSupplierTableData} scroll={{ x: 1300 }} - onRow={record => { + onRow={(record, index) => { return { // 鼠标移入行 onMouseEnter: () => { setEditableRowKeys(resultDisabledStatus ? [] : [record.id]) + setEditableRowKeys((resultDisabledStatus || (assessId == "1558990153220034560" && index == 0)) ? [] : [record.id]) }, onMouseLeave: () => { setEditableRowKeys([]); @@ -1633,12 +1784,12 @@ const GroupLeader: React.FC = () => { {isNotEmpty(reviewReportData.id) && ( - + {reportFileList.length == 0 ? null : } - - + + @@ -1664,6 +1815,7 @@ const GroupLeader: React.FC = () => { )} {modelIssue()} + {modalConfirm()} {sortTableVisible && setSortTableVisible(false)} diff --git a/src/pages/Evaluation/expert/ReviewResults/Jury/components/Jury.tsx b/src/pages/Evaluation/expert/ReviewResults/Jury/components/Jury.tsx index 7f29f13..6337234 100644 --- a/src/pages/Evaluation/expert/ReviewResults/Jury/components/Jury.tsx +++ b/src/pages/Evaluation/expert/ReviewResults/Jury/components/Jury.tsx @@ -10,6 +10,8 @@ import Weboffice from "@/pages/webOffice/weboffice"; import { getDicData, getProMethod, getRoomId } from '@/utils/session'; import { btnAuthority } from '@/utils/authority'; import WebOffice0609, { WebOfficeRefProps } from '@/pages/webOffice/weboffice0609'; +import styles from '@/assets/styles.module.less' +import SignaturePad from 'react-signature-canvas' import ReviewReportUpload from '@/utils/ReviewReportUpload'; import { getFileListByBid } from '@/utils/DownloadUtils'; import MACAddressPrompt from '@/pages/Evaluation/BidControl/BidControlManager/components/MACAddressPrompt'; @@ -53,6 +55,10 @@ const Jury: React.FC = () => { const [ptcpMode, setPtcpMode] = useState(); //报价类型 %-百分比类型(折扣率,优惠率)元-数值类型(总价,单价) const [quotationMethod, setQuotationMethod] = useState('元'); + //评审报告确认无误弹出窗 + const [visibleConfirm, setVisibleConfirm] = useState(false); + //鼠标指针ref + const pointRef = useRef() //初始化显示字段 const candidateType = bidMethodDict == 'procurement_mode_1' || bidMethodDict == 'procurement_mode_2' ? '中标' : '中选';//初始化中标中选字段 //评审报告附件modal visible @@ -663,6 +669,143 @@ const Jury: React.FC = () => { ) } + + /** + * 评审报告确认无误(签字面板) + * zhoujianlong 2021.8.19 + * @returns + */ + const modalConfirm = () => { + //保存loading + const [loading, setLoading] = useState(false); + //关闭modal + const onCancel = () => { + init(); + setVisibleConfirm(false); + } + //canvas ref + let sigPad: any = {} + //手写签名存储 + const [saveTrimCanvas, setSaveTrimCanvas] = useState('') + const canvasBase64 = reviewReportData?.expertList?.[0]?.expertSign + useEffect(() => { + if(canvasBase64 != undefined){ + setSaveTrimCanvas(canvasBase64) + } + }, [canvasBase64]) + + /** + * 保存或发送调用接口 + * @params expertSign 签名产生的base64值 + * status true-保存 false-发送 + */ + const toSaveOrSend = (expertSign: string,status: boolean) => { + let params = { + expertOpinion: 1, + reportId: reviewReportData.id, + expertSign: expertSign + }; + if(status){ //判断是保存还是发送 + params["status"] = 0 + } + setLoading(true) + reviewReportExpertsConfirmed(params).then(res => { + if(res?.code == 200 && res?.success === true) { + commonMessage(res); + if(status) {} else { + onCancel(); + } + } + }).finally(() => { + setLoading(false) + }) + } + //提交 status true-保存 false-发送 + const submit = (status: boolean) => { + let emptyStatus = sigPad.isEmpty(); + if(emptyStatus) { + message.error("当前无签名内容,请先签名"); + return; + } + //得到画布 + let canvas = sigPad._canvas; + if (canvas.getContext) { + let ctx = canvas.getContext('2d'); + // 将canvas的透明背景设置成白色 + let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); + for(var i = 0; i < imageData.data.length; i += 4) { + // 当该像素是透明的,则设置成白色 + if(imageData.data[i + 3] == 0) { + imageData.data[i] = 255; + imageData.data[i + 1] = 255; + imageData.data[i + 2] = 255; + imageData.data[i + 3] = 255; + } + } + ctx.putImageData(imageData, 0, 0); + } + let imgUrl = sigPad.toDataURL('image/png',1); + setSaveTrimCanvas(imgUrl) + toSaveOrSend(imgUrl,status) + } + //clear + const clear = () => { + sigPad.clear(); + } + //SignaturePad ref + const refRender = (ref: any) => { + sigPad = ref //存储ref + if(ref != null) { + ref?.clear() + ref?.fromDataURL(saveTrimCanvas) + } + } + return ( + <> + submit(false)}> + 发送 + , + , + , + , + 提示:按住鼠标左键进行签名 + ]} + > + +
+
pointRef.current.className = styles.sigPointer} onMouseUp={() => pointRef.current.className = styles.sigContainer}> + +
+
+
+
+ + ) + } + /** * 评审报告 我有问题 */ @@ -783,7 +926,7 @@ const Jury: React.FC = () => { ) } /** - * 确认无误 + * 确认无误(无需手写签名) */ const submitReviewReport = () => { setReviewReportLoading(true); @@ -797,6 +940,15 @@ const Jury: React.FC = () => { init(); }) } + //确认无误的手写签名判断方法 + const toReportConfirm = () => { + console.log(String(reviewReportData?.signStatus)) + if(String(reviewReportData?.signStatus) == '1') {//判断是否启用手写签名 1-是 0-否 + setVisibleConfirm(true); + } else { + submitReviewReport(); + } + } /** * 获取表头 */ @@ -844,12 +996,14 @@ const Jury: React.FC = () => { { (isNotEmpty(reviewReportData) && isNotEmpty(reviewReportData.id)) && ( - + {reportFileList.length == 0 ? null : } - - + {/* + */} + + @@ -876,6 +1030,7 @@ const Jury: React.FC = () => { {modelIssue()} {modelProblem()} + {modalConfirm()} {reportUploadVisible && setReportUploadVisible(false)} diff --git a/src/pages/Evaluation/projectManager/ReviewResults/ManagerEntry/index.tsx b/src/pages/Evaluation/projectManager/ReviewResults/ManagerEntry/index.tsx new file mode 100644 index 0000000..6169442 --- /dev/null +++ b/src/pages/Evaluation/projectManager/ReviewResults/ManagerEntry/index.tsx @@ -0,0 +1,13 @@ +import React from 'react'; +import Manager from './components/Manager'; +/** + * 项目经理 + */ +const Index: React.FC = () => { + return ( + <> + + + ); +} +export default Index; \ No newline at end of file diff --git a/src/pages/Evaluation/projectManager/ReviewResults/service.ts b/src/pages/Evaluation/projectManager/ReviewResults/service.ts index acb2ea7..bbce483 100644 --- a/src/pages/Evaluation/projectManager/ReviewResults/service.ts +++ b/src/pages/Evaluation/projectManager/ReviewResults/service.ts @@ -51,3 +51,10 @@ export function finishFlow(id: any) { export function getAssessRoomStatus(id: any) { return request('/api/biz-service-ebtp-process/v1/bizassessroom/info/' + id); } +/** + * 生成签名报告 + * @param id + */ +export function saveSignPdfReport(id: any) { + return request('/api/biz-service-ebtp-evaluation/v1/review/report/signpdf/' + id); +} diff --git a/src/pages/Tender/ProjectManager/JudgingPanel/List/preIndex.tsx b/src/pages/Tender/ProjectManager/JudgingPanel/List/preIndex.tsx new file mode 100644 index 0000000..63c7ceb --- /dev/null +++ b/src/pages/Tender/ProjectManager/JudgingPanel/List/preIndex.tsx @@ -0,0 +1,1730 @@ +import React, { useEffect, useRef, useState } from 'react'; +import { Button, Checkbox, Col, Collapse, DatePicker, Drawer, Form, Input, message, Modal, Popconfirm, Row, Select, Spin, Upload, Image, InputNumber } from 'antd' +import ProTable, { ActionType, EditableProTable, ProColumns } from '@ant-design/pro-table'; +import { getList, saveGroup, delOne, saveMember, changeEx, queryVoList, changeMember, applyFor, roomStatus, juryTem, rePassWord, getUserPhoto, unlockAccount, getCrotchListUsingGET, getSecs } from './service'; +import moment from 'moment'; +import { getDefId, getProId, getProMethod, getProOpenTenderForm, getSessionUserData } from '@/utils/session'; +import { getURLInformation, isEmpty } from '@/utils/CommonUtils'; +import './judgList.less'; +import '@/assets/xsy_style.less'; +import FileDown from '@/utils/Download'; +import { UploadOutlined } from '@ant-design/icons'; +import { btnAuthority } from '@/utils/authority'; +import RiskPrevention from '@/utils/RiskPrevention'; +import { downloadPath } from '@/utils/DownloadUtils'; +import { sortBy } from 'lodash'; +import ExpertSchemeProfessionalInfo from './ExpertSchemeProfessionalInfo'; + +const JudgingPanel: React.FC<{}> = () => { + const modalHeight = window.innerHeight * 96 / 100; + const proId = getProId(); + const roomType = getURLInformation('roomType'); + // const tailLayout = { wrapperCol: { offset: 8, span: 20 }, }; + 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 CheckboxGroup = Checkbox.Group; + // const { TabPane } = Tabs; + const actionRef = useRef(); + const [spin, spinSet] = useState(false); + const [loading, loadingSet] = useState(false); + const [sections, setSections] = useState([]); + const [sectionsVal, setSectionsVal] = useState([]); + const [modalVis, setModalVis] = useState(false);//新增评委会 + const [updateData, updateDataSet] = useState();//评委会modal数据 + const [memberVis, setMemberVis] = useState(false); + const [open, openSet] = useState(true);//评委会里是否有开启评标的评审室 true有开启的 false无 + const [allEnd, allEndSet] = useState(true);//评委会关联标段的评审室是否都关闭了 + const [disabled, disabledSet] = useState(true);//禁用 + const [checkSectionName, checkSectionNameSet] = useState('');//查看 关联标包显示 + const [showName, showNameSet] = useState({ zbr: '', bb: '', pb: '', });//字段名 + // const [manNum, manNumSet] = useState(5);//人数 + const [riskVisible, setRiskVisible] = useState(false);//风控弹窗 2021.9.7 zhoujianlong + const [riskData, setRiskData] = useState([]);//风控数据 2021.9.7 zhoujianlong + // const [userPhotoId, setUserPhotoId] = useState("");//电子评标室-录入外部专家-相片id 2022.8.29 zhoujianlong + const userData = getSessionUserData();//当前登录人用户信息 + + const [professionalMap, setProfessionalMap] = useState(); + //当前可编辑的行 + const [editableKeys, setEditableRowKeys] = useState([]); + const [tableData, setTableData] = useState([]); + function getShouName() { + const method = getProMethod(); + let showNameT: any = { zbr: '', bb: '', pb: '', }//相关标段 标书费 保证金 服务费 + // let num = 3; + if (method === 'procurement_mode_1' || method === 'procurement_mode_2') {//招标 + showNameT = { zbr: '招标人', bb: '标段', pb: '评标', }; + // num = 5; + } else if (method === 'procurement_mode_4') {//招募类 + showNameT = { zbr: '采购人', bb: '包件', pb: '评审', } + } else {//谈判类 + showNameT = { zbr: '采购人', bb: '采购包', pb: '评审', } + } + showNameSet(showNameT); + } + + //多选控制 + const [indeterminate, setIndeterminate] = useState(false); + const [checkAll, setCheckAll] = useState(false); + const [checkedList, setCheckedList] = useState(); + const [sectionCount, sectionCountSet] = useState(0);//控制获取标包 + + //创建评委会小组 + const saveG = async (fields: any) => { + const hide = message.loading('正在配置'); + try { + const success = await saveGroup({ ...fields }).then((res) => { + if (res?.code == 4004 && res?.success == false) { //2021.9.7 zhoujianlong 新增评委会保存增加风控 + const data = res?.data?.result == undefined ? [] : res?.data?.result + setRiskData(data) + setRiskVisible(true) + } + return res.success + }); + hide(); + if (success) { + message.success('配置成功'); + } + return true; + } catch (error) { + hide(); + message.error('配置失败请重试!'); + return false; + } + }; + + //主页表格 + const columns: ProColumns[] = [ + { title: '序号', valueType: 'index', width: 50, }, + { title: `${showName.bb}名称`, dataIndex: 'sectionName', }, + { title: '专家抽取数量', dataIndex: 'expertNumber', width: 120 }, + { title: `直接录入数量`, dataIndex: 'representativeNumber', width: 120 }, + { title: '预计开始时间', dataIndex: 'startTime', valueType: 'dateTime', width: '10%', }, + { title: '预计结束时间', dataIndex: 'endTime', valueType: 'dateTime', width: '10%', }, + { + title: '操作', dataIndex: 'option', width: '16%', + valueType: 'option', + render: (_, record) => { + if (record.status == 0 || record.status == 2) { + return ( + <> + {returnCheck(record, false)} + { + spinSet(true) + await del({ id: record.id }); + actionRef.current?.reload(); + spinSet(false) + }} + okText="确定" + cancelText="取消" + > + + + + + ) + } else if (record.status == 1) {//已提交申请 + return ( + <>{returnCheck(record, true)} + ) + } else if (record.status == 3) { + return ( + <> + {returnCheck(record, true)} + + + ); + } else { + return (<>) + } + } + }, + ]; + function returnCheck(record: any, check: any) {//返回操作列查看、修改按钮 + return ( + + ) + } + const handleUpdate = async (record: any) => { + form.resetFields(); + const res = await queryVoList({ id: record.id }); + + + // 提取专业抽取列表 + const extractSpecialityList = res.data.extractSpecialityList || []; + // 设置表格数据 + let specList = extractSpecialityList.map((item: any, index: number) => ({ + ...item, + uid: item.id || String(index + Date.now()) // 确保每个条目有唯一 key + })) + res.data.extractSpecialityList = specList; + setTableData(specList); + // 设置 editableKeys,确保每一行都能编辑 + setEditableRowKeys(specList.map((item: any, index: number) => item.uid)); + // setEditableRowKeys(specList.map(item => item.uid)); + updateDataSet(res.data); + + //剔除代表 + let list = [...res.data.juryCategoryVOList]; + list.map((item: any, index: any) => { + if (item.category == 1) { + list.splice(index, 1); + } + }); + cqDataSet(list); + setModalVis(true); + sectionCountSet(sectionCount + 1); + // readOnlySet(check); + checkSectionNameSet(res.data.sectionName); + + }; + const handleMember = async (record: any) => { + form.resetFields(); + const res = await queryVoList({ id: record.id }); + await queryOpenStatus(record.id); + categorySet(res.data.juryCategoryVOList); + juryIdSet(record.id); + memberCountSet(memberCount + 1); + setMemberVis(true); + }; + + //删除 + const del = async (fields: any) => { + const hide = message.loading('正在删除'); + try { + const success = await delOne({ ...fields }).then((res) => { + return res.success + }); + hide(); + if (success) { + message.success('删除成功'); + return true; + } else { + message.error('删除失败'); + return false; + } + } catch (error) { + hide(); + message.error('删除失败请重试!'); + actionRef.current?.reload(); + return false; + } + }; + //提交申请 + const apply = async (fields: any) => { + const hide = message.loading('正在提交'); + try { + const success = await await applyFor({ ...fields }).then((res) => { + return res.success + }); + hide(); + if (success) { + message.success('提交成功'); + return true; + } else { + message.error('提交失败'); + return false; + } + } catch (error) { + hide(); + message.error('提交失败请重试!'); + actionRef.current?.reload(); + return false; + } + }; + + //创建修改 标包方法 + const onChangeCheckBox = (checkedList: any[]) => { + // 获取当前选中的所有 section 对象 + const selectedSections = sections.filter((section: any) => + checkedList.includes(section.sectionId) + ); + + // 获取所有不同的 juryNumber 值 + const uniqueJuryNumbers = [...new Set(selectedSections.map((s: any) => s.juryNumber))]; + + if (uniqueJuryNumbers.length > 1) { + message.error('所选标段的评标委员会人数不一致,不能同时选择'); + return; // 阻止更新 + } + + setCheckedList(checkedList); + getEarliestTime(sections, checkedList); + setIndeterminate(!!checkedList.length && checkedList.length < sectionsVal.length); + setCheckAll(checkedList.length === sectionsVal.length); + }; + const onCheckAllChange = (e: { target: { checked: any; }; }) => { + + const uniqueJuryNumbers = [ + ...new Set(sections.map((s: any) => s.juryNumber)), + ]; + + if (e.target.checked && uniqueJuryNumbers.length > 1) { + message.error("存在不同评标委员会人数,不能全选"); + return; + } + setCheckedList(e.target.checked ? sectionsVal : []); + getEarliestTime(sections, e.target.checked ? sectionsVal : []); + setIndeterminate(false); + setCheckAll(e.target.checked); + }; + + + function disabledDate(current: any) {//日期选择 + return current && current < moment().startOf('day'); + } + + + const rule = (mes: any) => {//创建修改 规则 + return [ + { + required: true, + message: `请录入${mes}`, + }, + ] + } + //专家账号解锁 + const unlockExportAccount = async (record: any, juryId: any, proId: any) => { + try { + const res = await unlockAccount(record.id, juryId, proId); + if (res.success) { + message.success(res.data); + } + } catch (error) { + + } + } + + useEffect(() => {//获取标包信息 + + let params = { tpId: proId, roomType: roomType }; + let checked: any = []; + if (updateData !== undefined && JSON.stringify(updateData) !== "{}") { + params['juryId'] = updateData.id; + updateData.juryRoomList.map((item: any) => { + checked.push(item.sectionId); + }); + setCheckedList(checked); + } else { + params['juryId'] = ''; + } + getShouName();//根据采购类型变名字 + modalVis == true ? getSecs({ ...params }).then((res) => { + let data = []; + let secVals = []; + if (res.success) { + secVals = res.data.map((item: any) => { return item.sectionId }) + data = res.data; + } + setSections(data); + setSectionsVal(secVals); + setIndeterminate(!!checked.length && checked.length < secVals.length); + setCheckAll(checked.length === secVals.length); + updateData && String(updateData?.reserveStatus) == "1" && getEarliestTime(data, checked);//初始化赋值数据 + }) : null; + + }, [sectionCount]); + + useEffect(() => {//给表单赋值 + form.setFieldsValue({ + juryType: updateData != undefined ? updateData.juryType : null, + representativeNumber: updateData != undefined ? updateData.representativeNumber : null, + 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.reserveStatus == 1 ? updateData.elecEvalRoomReserve.areaAddress : updateData.evalLocation : null, + description: updateData != undefined ? updateData.description : null, + extractSpecialityList: updateData != undefined ? updateData.extractSpecialityList : null, + }) + }, [updateData]); + + const group = () => {//评审小组modal + return ( + <> + { + setModalVis(false); + updateDataSet({}); + setTableData([]); + setCheckedList([]); + form.resetFields(); + }} + > + {tab1()} + + + ) + } + //人数校验 + function checkMan(count: number, expCon: any) { + let res = true; + const defId = getDefId();//16 + const method = getProMethod();//9 + const yushenType = getProOpenTenderForm(); + let manNumT = 5; + + if (method === 'procurement_mode_1' || method === 'procurement_mode_2') { + if (roomType == '1' && yushenType == 'open_tender_form_2') {//资格预审 自愿招标为3 + manNumT = 3; + } + // if (expCon < count * 2 / 3) { + // res = false; + // message.error("专家人数不少于评委会总人数2/3") + // } + } else if (method === 'procurement_mode_3') {//比选 + if (expCon < count * 2 / 5) { + res = false; + message.error("专家人数不少于评委会总人数2/5") + } + } else if (method === 'procurement_mode_4') {//招募 + manNumT = 1; + if (count < manNumT) { + res = false; + message.error(`评委会总人数需大于1`) + } else { + return true; + } + } else if (method === 'procurement_mode_5') {//竞谈 + if (manNumT = 5) {//最低价 + manNumT = 3; + } + if (expCon < count * 1 / 3) { + res = false; + message.error("专家人数不少于评委会总人数1/3") + } + } else if (method === 'procurement_mode_6') {//单一 + manNumT = 3; + } else if (method === 'procurement_mode_9') {//单一 + manNumT = 3; + } else if (defId == 'inquiry') {//询价 + manNumT = 3; + } + if (count < manNumT || count % 2 == 0) {//校验总人数 + res = false; + message.error(`评委会总人数需大于等于${manNumT}人且为单数`) + } + return res + } + //添加抽取drawer + const formLayoutDrawer = { labelCol: { span: 8 }, wrapperCol: { span: 16 }, }; + const tailLayoutDrawer = { wrapperCol: { offset: 8, span: 20 }, }; + const [cqData, cqDataSet] = useState([]);//抽取表格,提交时需要 + // 在组件内定义函数 + const calculateExpertNumber = () => { + // 没有选中标段时直接返回,不清空 expertNumber 是为了兼容已有值的情况 + if (!checkedList || checkedList.length === 0) return; + + const selectedSections = sections.filter((section: any) => + checkedList.includes(section.sectionId) + ); + + const uniqueJuryNumbers = [...new Set(selectedSections.map((s: any) => s.juryNumber))]; + + if (uniqueJuryNumbers.length > 1) { + form.setFieldsValue({ expertNumber: undefined }); + message.error("所选标段评标委员会人数不一致"); + return; + } + + const juryNumber = parseInt(uniqueJuryNumbers[0]) || 0; + const repNumber = parseInt(form.getFieldValue('representativeNumber')) || 0; + + + if (repNumber < 0 || repNumber > juryNumber) { + message.error(`直接录入数量应在 0 ~ ${juryNumber} 之间`); + form.setFieldsValue({ representativeNumber: undefined, expertNumber: undefined }); + return; + } + + const expertNumber = Math.max(0, juryNumber - repNumber); + (expertNumber === 0) && setTableData([]); + form.getFieldValue('representativeNumber') && form.setFieldsValue({ expertNumber }); + }; + + // 在 useEffect 中监听依赖项 + useEffect(() => { + if (Array.isArray(sections) && sections.length > 0) { + calculateExpertNumber(); + } + }, [form.getFieldValue('representativeNumber'), checkedList, sections]); + const tab1 = () => {//cqtab1 + return ( + <> +

关联{showName.bb}

+
+ + + { return '1' } + }, + () => ({ + validator(rule, value,) { + let leg = 0; + checkedList != undefined ? leg = checkedList.length : leg = 0; + if (leg > 0) { + return Promise.resolve(); + } else { + message.error(`请选择${showName.bb}`) + return Promise.reject(`请选择${showName.bb}`); + } + }, + }), + ]} + > + { + disabled ? + {checkSectionName} + : <> + { + sections.length > 0 ? <> +
+ 全选 +
+
+ + + { + sections.map((item: any, index: any) => { + return ( + + {item.sectionName} + + + + ) + }) + } + + + + : 无可用{showName.bb} + } + + } +
+ +
+
+

评标时间和地点管理

+
+ + + + + + + + + + + + + +
+

专家申请基本信息

+
+ + + { + // const value = e.target.value; + // if (value && !checkedList?.length) { + // form.resetFields(['representativeNumber']); + // message.error("请先选择关联标段"); + // return; + // } + + // 继续触发计算 + // form.setFieldsValue({ representativeNumber: value }); + // calculateExpertNumber(); + // }} + /> + + + + + + + + + {() => { + const expertNumber = form.getFieldValue('expertNumber'); + if (!expertNumber || expertNumber <= 0) return null; + + return ( + + + rowKey="uid" + toolBarRender={false} + columns={professColumns} + dataSource={tableData} + recordCreatorProps={{ + newRecordType: 'dataSource', + hidden: disabled, + creatorButtonText: '新增', + record: () => ({ + uid: String(Date.now()), + // id: "", + // extractNumber: "", + // specialityId: "", + }), + }} + editable={{ + type: 'multiple', + editableKeys, + onChange: (keys, rows) => { + setEditableRowKeys(keys); + }, + onValuesChange: (record, recordList) => { + setTableData(recordList); + }, + actionRender: (row, _, dom) => { + return [dom.delete]; + }, + }} + /> + + ); + }} + + + {/* + + */} + +
+ + ) + } + //抽取专业-表格类型定义 + type DataSourceType = { + id?: string; + extractNumber: number; + specialityId?: string; + }; + const professColumns: ProColumns[] = [ + { + title: '主键', + dataIndex: 'id', + hideInTable: true, + }, + { + title: '专业名称', + dataIndex: 'specialityId', + valueType: 'select', + valueEnum: professionalMap, + width: '30%', + }, + { + title: '人数', + dataIndex: 'extractNumber', + width: '30%', + renderFormItem: (_, { record }) => { + return ; + }, + }, + { + title: '操作', + valueType: 'option', + hideInTable: disabled, + }, + ]; + /** + * 校验函数 + * @param schemaData + * @returns + */ + const checkData = (schemaData: any) => { + let res = true; + let spec = 0; + let specNum = 0; + for (let i = 0; i < schemaData?.extractSpecialityList?.length; i++) { + const item = schemaData?.extractSpecialityList?.[i]; + if ( + item.hasOwnProperty("specialityId") && + item.hasOwnProperty("extractNumber") + ) { + spec += 1; + } + if (item?.extractNumber) { + specNum += Number(item?.extractNumber); + } + } + if (Number(schemaData?.expertNumber) !== specNum) { + res = false; + message.error("抽取专业人数与专家需求人数不符!"); + } + return res; + } + const checkSpecialityUnique = () => { + let res = true; + const specialityIds = tableData.map(item => item.specialityId).filter(Boolean); + const unique = [...new Set(specialityIds)]; + if (specialityIds.length !== unique.length) { + res = false; + message.error('抽取专业名称不可重复选择'); + } + return res; + }; + const idToNameMap = Object.entries(professionalMap || {}).reduce((acc, [id, option]) => { + acc[id] = option.text; + return acc; + }, {} as Record); + const idToCodeMap = Object.entries(professionalMap || {}).reduce((acc, [id, option]) => { + acc[id] = option.text; + return acc; + }, {} as Record); + // 遍历表格数据并附加专业名称 + const enhancedData = tableData.map(item => { + const name = idToNameMap[item.specialityId] || ''; // 获取对应名称 + const code = idToCodeMap[item.specialityId] || ''; // 获取对应名称 + return { + ...item, + specialityName: name, // 添加专业名称字段 + specialityNo: code, + }; + }); + const renderFooter = () => {//评审小组footer + return ( + <> + + + + ) + }; + + //成员管理 + const [add, setAdd] = useState(false);//录入外部专家Drawer显隐 + const [changeMan, changeManSet] = useState(false);//更换Drawer显隐 + const [juryId, juryIdSet] = useState('');//更换专家所需评委会id + const [reason, reasonSet] = useState('');//更换专家原因 + const [category, categorySet] = useState([]);//类别 juryCategoryVOList + const [daibiao, daibiaoSet] = useState({});//代表 + const [jishu, jishuSet] = useState({});//技术 + const [shangwu, shangwuSet] = useState({});//商务 + const [falv, falvSet] = useState({});//法律 + const [qita, qitaSet] = useState({});//其它 + const [luru, luruSet] = useState(0);//录入外部传类别 + const [updateKeyMem, updateKeyMemSet] = useState(-1);//触发修改存key + const [memberCount, memberCountSet] = useState(0);//刷新成员管理页面 + const [checkBoxs, checkBoxsSet] = useState([]);//更换专家按钮组 + const [checkBoxsStatus, checkBoxsStatusSet] = useState({});//更换专家按钮组 + const [changeMemberId, changeMemberIdSet] = useState('');//更换专家id + const [changeBtn, changeBtnSet] = useState(true);//更换按钮显隐 + const [formMem] = Form.useForm(); + function reset() {//重置 + categorySet([]); + luruSet(0); + updateKeyMemSet(-1); + checkBoxsSet([]); + changeMemberIdSet(''); + setCheckedList([]); + form.resetFields(); + } + const columnsMember: ProColumns[] = [//成员管理页面表格 + { title: '序号', valueType: 'index', width: 50, }, + { title: '专家姓名', dataIndex: 'name', }, + { title: '手机号码', dataIndex: 'mobile', }, + { title: '证件号码', dataIndex: 'certificate', }, + { title: '工作单位', dataIndex: 'workunit', }, + // { title: '通知状态', dataIndex: 'status', }, + // { title: '通知结果备注', dataIndex: 'remark', }, + // { + // title: '照片', + // dataIndex: 'faceId', + // render: (_, record) => { + // if (record.faceId) { + // return { + return ( + <> + + { confirmMem(record); }} + okText="确定" + cancelText="取消" + > + + + + + + + ); + } + }, + ]; + function returnType(inId: any) {//修改时根据record.categoryId判断类别 + category != undefined ? category.map((item: any,) => { + if (item.id == inId) { + if (item.category == 1) { + luruSet(1); + } else if (item.category == 2 && item.subCategory == 1) { + luruSet(2); + } else if (item.category == 2 && item.subCategory == 2) { + luruSet(3); + } else if (item.category == 2 && item.subCategory == 3) { + luruSet(4); + } else if (item.category == 2 && item.subCategory == 4) { + luruSet(5); + } + } + }) : null; + } + function returnCate(luru: any) {//取data + switch (luru) { + case 1: return daibiao; + case 2: return jishu; + case 3: return shangwu; + case 4: return falv; + case 5: return qita; + default: break; + } + } + function dataSet(data: any, luru: any) {//塞data + let dataT = []; + switch (luru) { + case 1: dataT = daibiao; dataT.juryMemberList = data; daibiaoSet(dataT); break; + case 2: dataT = jishu; dataT.juryMemberList = data; jishuSet(dataT); break; + case 3: dataT = shangwu; dataT.juryMemberList = data; shangwuSet(dataT); break; + case 4: dataT = falv; dataT.juryMemberList = data; falvSet(dataT); break; + case 5: dataT = qita; dataT.juryMemberList = data; qitaSet(dataT); break; + default: break; + } + } + function returnHeader(name: any) { + return ( +

{name}

+ ) + } + function returnCheckBox(type: any) {//更改选人 + return ( + <> + {type != undefined ? + type.map((item: any) => { + return ( + { + let data = [...checkBoxs]; + let status = { ...checkBoxsStatus }; + if (e.target.checked) { + data.push({ memberId: item.id }); + status[item.id] = true; + } else { + data.map((item: any, index: any) => { + item.memberId == e.target.value ? data.splice(index, 1) : null; + }) + status[item.id] = false; + } + checkBoxsStatusSet(status); + checkBoxsSet(data); + }}>{item.name} + ) + }) : null + } + + ) + } + useEffect(() => {//拆类别 + daibiaoSet({}); + jishuSet({}); + shangwuSet({}); + falvSet({}); + qitaSet({}); + category.map((item: any) => { + if (item.category == 1) { + daibiaoSet(item); + } else { + if (item.subCategory == 1) { + jishuSet(item); + } else if (item.subCategory == 2) { + shangwuSet(item); + } else if (item.subCategory == 3) { + falvSet(item); + } else if (item.subCategory == 4) { + qitaSet(item); + } + } + }); + }, [memberCount]); + async function queryOpenStatus(id: any) {//查是否开启评标 id:评委会id + await roomStatus(id).then((res) => { + if (res.data) { + openSet(res.data.anyOpenRoom); + allEndSet(res.data.allEndRoom); + } + }) + } + const returnPanel = () => {//返回手风琴 + return ( + <> + {daibiao.juryMemberList != undefined ? + + [ + + ]} + /> + + : null} + {jishu.juryMemberList != undefined ? + + [ + + ]} + /> + + : null} + {shangwu.juryMemberList != undefined ? + + [ + + ]} + /> + + : null} + {falv.juryMemberList != undefined ? + + [ + + ]} + /> + + : null} + {qita.juryMemberList != undefined ? + + [ + // + ]} + /> + + : null} + + ) + } + function checkRe(data: any) {//查重 + let pass = true; + !checkReRoot(daibiao, data, 1) ? pass = false : null; + !checkReRoot(jishu, data, 2) ? pass = false : null; + !checkReRoot(shangwu, data, 3) ? pass = false : null; + !checkReRoot(falv, data, 4) ? pass = false : null; + !checkReRoot(qita, data, 5) ? pass = false : null; + return pass; + } + function checkReRoot(type: any, data: any, updateType: any) {//查重 + const { certificate, mobile, name } = data; + let pass = true; + if (certificate == '' || mobile == '' || name == '' || certificate == undefined || mobile == undefined || name == undefined) { + pass = false; + } else { + if (type.juryMemberList != undefined && updateType != luru) { + for (const item of type.juryMemberList) { + if (item.certificate == certificate) {//身份证号重复 + pass = false; + message.error('身份证号重复'); + break; + } + if (item.mobile == mobile) {//手机号重复 + pass = false; + message.error('手机号重复'); + break; + } + } + } else if (type.juryMemberList != undefined && updateType == luru) { + for (const item of type.juryMemberList) { + if (item.certificate == certificate && item.key != updateKeyMem) {//身份证号重复 + pass = false; + message.error('身份证号重复'); + break; + } + if (item.mobile == mobile && item.key != updateKeyMem) {//手机号重复 + pass = false; + message.error('手机号重复'); + break; + } + } + } + } + + return pass; + } + const returnDrawerMem = () => {//成员管理抽屉(专家信息)添加、修改 + return ( + <> + { + setAdd(false); + changeBtnSet(true); + // formMem.resetFields(); + }} + visible={add} + getContainer={false} + style={{ position: 'absolute' }} + > +
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + ) + } + const returnDrawerChange = () => {//更换专家抽屉 + return ( + <> + changeManSet(false)} + visible={changeMan} + getContainer={false} + style={{ position: 'absolute' }} + footer={
+    + +
} + > + {daibiao.juryMemberList != undefined ? <> + {returnHeader('直接录入专家')} + {returnCheckBox(daibiao.juryMemberList)} + : null} + {jishu.juryMemberList != undefined ? <> + {returnHeader('技术类专家')} + {returnCheckBox(jishu.juryMemberList)} + : null} + {shangwu.juryMemberList != undefined ? <> + {returnHeader('商务类专家')} + {returnCheckBox(shangwu.juryMemberList)} + : null} + {falv.juryMemberList != undefined ? <> + {returnHeader('法律类专家')} + {returnCheckBox(falv.juryMemberList)} + : null} + {qita.juryMemberList != undefined ? <> + {returnHeader('抽取专家')} + {returnCheckBox(qita.juryMemberList)} + : null} +

取消原因: +