1.增加30分钟超时退出 (需修改 并不是无操作30分钟)

2.修改项目管理建档和暂存功能按钮失效问题
3.修改页面联动以及小bug
4.添加预审专家人数为5+奇数判断 以及后审 专家人数和建档 标段专家人数对应问题
5.修改项目跟进看不到项目建档信息问题
This commit is contained in:
32503
2025-08-04 15:48:43 +08:00
parent fda9237e0a
commit 188b034a24
13 changed files with 515 additions and 362 deletions

View File

@ -1,6 +1,6 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import { message, Spin } from 'antd'; import { message, Spin } from 'antd';
import { history } from '@umijs/max'; import { history } from 'umi';
import { cloudReloadToken, cooperReloadToken, fgetUserMsg, getDictionaries, getTokenByCode } from './service'; import { cloudReloadToken, cooperReloadToken, fgetUserMsg, getDictionaries, getTokenByCode } from './service';
import { getTotalURLInformation, getURLInformation, isNotEmpty } from '@/utils/CommonUtils'; import { getTotalURLInformation, getURLInformation, isNotEmpty } from '@/utils/CommonUtils';
import { refreshTokenApi } from '@/services/login'; import { refreshTokenApi } from '@/services/login';
@ -74,19 +74,7 @@ const Loading: React.FC<{}> = () => {
// return; // return;
// } // }
// } else { // } else {
let role = userData.authorityList[0].roleCode; setUserData(userData, userData.authorityList[0].roleCode, userData.authorityList[0]);
let roleData = userData.authorityList[0];
const loginType = localStorage.getItem('loginType');
if (loginType) {
const roleCode = `ebtp-${loginType}`
const targetRole = userData.authorityList.find((ite: any) => ite.roleCode == roleCode);
if (targetRole) {
role = targetRole.roleCode;
roleData = targetRole;
}
}
setUserData(userData, role, roleData);
// } // }
await setDict();//存字典 await setDict();//存字典
setTimeout(() => { setTimeout(() => {
@ -101,189 +89,220 @@ const Loading: React.FC<{}> = () => {
//获取用户信息 //获取用户信息
async function getUserData(token: string, url: string, extra: any, status: number) { async function getUserData(token: string, url: string, extra: any, status: number) {
// const res = { const res = {
// "userId": "ex-linjp29", "userId": "ex-wanghy623",
// "lastName": null, "lastName": null,
// "firstName": null, "firstName": null,
// "fullName": "林剑萍", "fullName": "曹鹏",
// "emailAddress": null, "emailAddress": null,
// "loginName": "ex-linjp29", "loginName": "ex-wanghy623",
// "mobilePhone": null, "mobilePhone": null,
// "officePhone": null, "officePhone": null,
// "sex": null, "sex": null,
// "employeeCategory": null, "employeeCategory": null,
// "userType": "1", "userType": "1",
// "dateOfBirth": null, "dateOfBirth": null,
// "age": null, "age": null,
// "employeeNumber": "1743164896", "employeeNumber": "1753782355",
// "nationalityId": null, "nationalityId": null,
// "nationality": null, "nationality": null,
// "nationalIdentifier": null, "nationalIdentifier": null,
// "supervisorId": null, "supervisorId": null,
// "organizationId": "101058278", "organizationId": "101152137",
// "organizationName": "湖北信通通信有限公司", "organizationName": "河北通信工程招投标有限公司",
// "orgCategory": null, "orgCategory": null,
// "deptId": "101058278", "deptId": "101152137",
// "deptName": "湖北信通通信有限公司", "deptName": "河北通信工程招投标有限公司",
// "roleIds": null, "roleIds": null,
// "bussiGroupId": null, "bussiGroupId": null,
// "positionId": null, "positionId": null,
// "currentRoleCode": "undefined", "currentRoleCode": "undefined",
// "province": null, "province": null,
// "authorityList": [ "authorityList": [
// { {
// "roleId": "000009", "roleId": "000007",
// "roleName": "代理机构业务经理", "roleName": "代理机构管理员",
// "roleCode": "ebtp-agency-project-manager", "roleCode": "ebtp-agency-admin",
// "roleScope": "EBTP", "roleScope": "EBTP",
// "authorities": [ "authorities": [
// "ebtp-agency-project-manager", "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin",
// null, "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin",
// "ebtp-agency-project-manager", null,
// "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin", "ebtp-agency-admin",
// "ebtp-agency-project-manager", null,
// "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin", null,
// "ebtp-agency-project-manager", "ebtp-agency-project-manager,ebtp-expert,ebtp-agency-admin",
// "ebtp-agency-project-manager", null,
// null, "ebtp-agency-admin",
// "ebtp-agency-project-manager", null,
// null, null,
// "ebtp-agency-project-manager", null,
// "ebtp-agency-project-manager", null,
// null, "ebtp-agency-admin",
// "ebtp-agency-project-manager,ebtp-expert,ebtp-agency-admin", null,
// null, "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier",
// null, "ebtp-agency-project-manager,ebtp-supplier",
// "ebtp-agency-admin", "ebtp-agency-project-manager",
// null, "ebtp-agency-project-manager"
// null, ]
// null, },
// null, {
// null, "roleId": "000009",
// null, "roleName": "代理机构业务经理",
// null, "roleCode": "ebtp-agency-project-manager",
// "ebtp-agency-project-manager", "roleScope": "EBTP",
// "ebtp-agency-project-manager,ebtp-purchase", "authorities": [
// "ebtp-agency-project-manager,ebtp-purchase", null,
// "ebtp-agency-project-manager,ebtp-purchase", "ebtp-agency-project-manager",
// "ebtp-agency-project-manager,ebtp-purchase", "ebtp-agency-project-manager",
// "ebtp-agency-project-manager,ebtp-purchase", null,
// null, "ebtp-agency-project-manager",
// null, null,
// null, "ebtp-agency-project-manager",
// null, "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin",
// null, null,
// "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier", "ebtp-agency-project-manager",
// "ebtp-agency-project-manager,ebtp-supplier", "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin",
// "ebtp-agency-project-manager", "ebtp-agency-project-manager",
// "ebtp-agency-project-manager", "ebtp-agency-project-manager",
// null null,
// ] null,
// }, "ebtp-agency-project-manager",
// { null,
// "roleId": "000006", "ebtp-agency-project-manager,ebtp-expert,ebtp-agency-admin",
// "roleName": "供应商", null,
// "roleCode": "ebtp-supplier", null,
// "roleScope": "EBTP", "ebtp-agency-admin",
// "authorities": [ null,
// "system:user:test", null,
// "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin", null,
// "system:user:test", null,
// "ebtp-agency-project-manager", null,
// "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin", null,
// "ebtp-supplier", null,
// "ebtp-supplier", "ebtp-agency-project-manager",
// "system:user:test", "ebtp-agency-project-manager,ebtp-purchase",
// "system:user:test", "ebtp-agency-project-manager,ebtp-purchase",
// "ebtp-agency-project-manager,ebtp-expert,ebtp-agency-admin", "ebtp-agency-project-manager,ebtp-purchase",
// "ebtp-supplier", "ebtp-agency-project-manager,ebtp-purchase",
// "system:user:test", "ebtp-agency-project-manager,ebtp-purchase",
// "ebtp-supplier", null,
// "system:user:test", null,
// "ebtp-supplier", null,
// "ebtp-supplier", null,
// "ebtp-supplier", null,
// "ebtp-supplier", null,
// "ebtp-supplier", null,
// "ebtp-supplier", "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier",
// "ebtp-supplier", "ebtp-agency-project-manager,ebtp-supplier",
// null, "ebtp-agency-project-manager",
// null, "ebtp-agency-project-manager",
// null, null
// "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier", ]
// "ebtp-agency-project-manager,ebtp-supplier", },
// "ebtp-supplier", {
// "system:user:test", "roleId": "000006",
// "system:user:test", "roleName": "供应商",
// "system:user:test", "roleCode": "ebtp-supplier",
// "ebtp-agency-project-manager", "roleScope": "EBTP",
// "system:user:test" "authorities": [
// ] "ebtp-supplier",
// } "system:user:test",
// ] "ebtp-supplier",
// } "system:user:test",
// if (res?.authorityList == null || res?.authorityList?.length == 0) { "ebtp-agency-project-manager",
// if (url == 'ExamineAndApprove/Announcement' || "system:user:test",
// url == 'ExamineAndApprove/ChangeTheAnnouncement' || null,
// url == 'ExamineAndApprove/Publicity' || "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin",
// url == 'ExamineAndApprove/InvitationLetter' || "system:user:test",
// url == 'ExamineAndApprove/ExternalReference' || "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin",
// url == 'ExamineAndApprove/FailureAnnouncement') { "ebtp-agency-project-manager,ebtp-expert,ebtp-agency-admin",
// let newAuthority: any[] = [] "system:user:test",
// newAuthority.push({ "ebtp-supplier",
// authorities: [null, "system:user:test", "system:user:test", "system:user:test", "system:user:test", null, null], null,
// roleCode: "ebtp-unicom-default", "ebtp-supplier",
// roleId: "20004", "ebtp-supplier",
// roleName: "联通普通用户", "ebtp-supplier",
// roleScope: "EBTP" "ebtp-supplier",
// }) "system:user:test",
// res.authorityList = [...newAuthority]; "ebtp-supplier",
// await redirect(res, url, extra); "ebtp-supplier",
// } "ebtp-supplier",
// }else { "ebtp-supplier",
// await redirect(res, url, extra); null,
// } null,
fgetUserMsg(token).then(async res => { null,
if (res) { null,
if (res?.userType == null) { "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier",
error('401'); "ebtp-agency-project-manager,ebtp-supplier",
} else { "ebtp-supplier",
if (res?.authorityList == null || res?.authorityList?.length == 0) { "system:user:test",
if (url == 'ExamineAndApprove/Announcement' || "system:user:test",
url == 'ExamineAndApprove/ChangeTheAnnouncement' || "system:user:test",
url == 'ExamineAndApprove/Publicity' || "ebtp-agency-project-manager",
url == 'ExamineAndApprove/InvitationLetter' || "system:user:test"
url == 'ExamineAndApprove/ExternalReference' || ]
url == 'ExamineAndApprove/FailureAnnouncement') {
const newAuthority: any[] = []
debugger
newAuthority.push({
authorities: [null, "system:user:test", "system:user:test", "system:user:test", "system:user:test", null, null],
roleCode: "ebtp-cosco-default",
roleId: "20004",
roleName: "普通用户",
roleScope: "EBTP"
})
res.authorityList = [...newAuthority];
await redirect(res, url, extra);
} else {
if (status == 0) {
// await refreshUserData(res?.userType, token, url, extra);
message.error("角色身份信息不存在").then(() => {
history.replace('/login');
});
} else {
error('401');
}
}
} else {
await redirect(res, url, extra);
}
} }
} else { ]
message.error("登录信息有误,请重新登录") }
if (res?.authorityList == null || res?.authorityList?.length == 0) {
if (url == 'ExamineAndApprove/Announcement' ||
url == 'ExamineAndApprove/ChangeTheAnnouncement' ||
url == 'ExamineAndApprove/Publicity' ||
url == 'ExamineAndApprove/InvitationLetter' ||
url == 'ExamineAndApprove/ExternalReference' ||
url == 'ExamineAndApprove/FailureAnnouncement') {
let newAuthority: any[] = []
newAuthority.push({
authorities: [null, "system:user:test", "system:user:test", "system:user:test", "system:user:test", null, null],
roleCode: "ebtp-unicom-default",
roleId: "20004",
roleName: "联通普通用户",
roleScope: "EBTP"
})
res.authorityList = [...newAuthority];
await redirect(res, url, extra);
} }
}) }else {
await redirect(res, url, extra);
}
// await fgetUserMsg(token).then(async res => {
// if (res) {
// if (res?.userType == null) {
// error('401');
// } else {
// if (res?.authorityList == null || res?.authorityList?.length == 0) {
// if (url == 'ExamineAndApprove/Announcement' ||
// url == 'ExamineAndApprove/ChangeTheAnnouncement' ||
// url == 'ExamineAndApprove/Publicity' ||
// url == 'ExamineAndApprove/InvitationLetter' ||
// url == 'ExamineAndApprove/ExternalReference' ||
// url == 'ExamineAndApprove/FailureAnnouncement') {
// let newAuthority: any[] = []
// newAuthority.push({
// authorities: [null, "system:user:test", "system:user:test", "system:user:test", "system:user:test", null, null],
// roleCode: "ebtp-unicom-default",
// roleId: "20004",
// roleName: "联通普通用户",
// roleScope: "EBTP"
// })
// res.authorityList = [...newAuthority];
// await redirect(res, url, extra);
// } else {
// if (status == 0) {
// await refreshUserData(res?.userType, token, url, extra);
// } else {
// error('401');
// }
// }
// } else {
// await redirect(res, url, extra);
// }
// }
// } else {
// message.error("登录信息有误,请重新登录")
// }
// })
} }
//通过code取token //通过code取token
async function getToken(code: string, data: any) { async function getToken(code: string, data: any) {

View File

@ -274,7 +274,7 @@ class manager extends PureComponent {
<> <>
<Button type="link" onClick={() => { <Button type="link" onClick={() => {
sessionStorage.setItem("projectData",JSON.stringify(record)) sessionStorage.setItem("projectData",JSON.stringify(record))
sessionStorage.setItem("opt","view") sessionStorage.setItem("opt","iview")
history.push({ history.push({
pathname: '/ProjectLayout/Manager/HomePageSectionList' pathname: '/ProjectLayout/Manager/HomePageSectionList'
}); });

View File

@ -37,7 +37,7 @@ const ProjectDocumentation: React.FC = () => {
//获取字典 //获取字典
const getDict: any = getDicData(); const getDict: any = getDicData();
const dictData = JSON.parse(getDict); const dictData = JSON.parse(getDict);
/** /**
* proList信息 * proList信息
*/ */
@ -96,7 +96,11 @@ const ProjectDocumentation: React.FC = () => {
key="followUpProject" key="followUpProject"
type="link" type="link"
danger danger
onClick={() => followUpProject(record)} onClick={() => {
sessionStorage.setItem("projectData",JSON.stringify(record));
sessionStorage.setItem("opt","iview");
followUpProject(record)
}}
> >
</Button> </Button>
@ -157,8 +161,8 @@ const ProjectDocumentation: React.FC = () => {
} }
/** /**
* 加载标段数据 * 加载标段数据
* @param record * @param record
* @returns * @returns
*/ */
const createSection = (record: any, openingName: string) => { const createSection = (record: any, openingName: string) => {
//标段信息 //标段信息
@ -244,8 +248,8 @@ const ProjectDocumentation: React.FC = () => {
} }
/** /**
* 开标时间,评审开始时间字段显示 * 开标时间,评审开始时间字段显示
* @param bidMethod * @param bidMethod
* @param examinationMethod * @param examinationMethod
*/ */
const openingTimeText = (bidMethod: string, examinationMethod: string | null) => { const openingTimeText = (bidMethod: string, examinationMethod: string | null) => {
const bid = '开标'; const bid = '开标';
@ -410,7 +414,7 @@ const ProjectDocumentation: React.FC = () => {
/** /**
* 获取返回路径 * 获取返回路径
* @returns * @returns
*/ */
const getReturnURL = () => { const getReturnURL = () => {
let projectURLParams = JSON.parse(projectParams); let projectURLParams = JSON.parse(projectParams);

View File

@ -54,13 +54,13 @@ const regionOutsideOptions = [
// 币种 // 币种
const currencyCodeOptions = [ const currencyCodeOptions = [
{ label: 'CNY', value: 'CNY' }, { label: 'CNY', value: 'CNY' },
{ label: 'EUR', value: 'EUR' }, // { label: 'EUR', value: 'EUR' },
{ label: 'USD', value: 'USD' }, { label: 'USD', value: 'USD' },
]; ];
const currencyCodeMap = new Map([ const currencyCodeMap = new Map([
['CNY','CNY'], ['CNY','CNY'],
['EUR','EUR'], // ['EUR','EUR'],
['USD','USD'] ['USD','USD']
]) ])
@ -107,28 +107,35 @@ const tenderAgencyEnum = {
// 报价方式 // 报价方式
const quotationMethodDictEnum = { const quotationMethodDictEnum = {
1: '总价', 'quotation_method_1': '总价',
2: '单价', 'quotation_method_4': '单价',
3: '优惠率', 'quotation_method_3': '优惠率',
4: '折扣率', 'quotation_method_2': '折扣率',
}; };
// 评价方法 // 评价方法
const evalMethodDictEnum = { const evalMethodDictEnum = {
1: '最低价法', 'eval_method_1': '最低价法',
2: '综合评估法', 'eval_method_2': '综合评估法',
3: '合理低价法', 'eval_method_3': '合理低价法',
};
const evalMethodDictMap = new Map([
['eval_method_1','1'],
['eval_method_2','2'],
['eval_method_3','2']
])
// 流程类型
const chooseProcessEnum = {
'1': '第一轮初审,固定流程',
'2': '第一轮初审详审,固定流程'
}; };
// 资格审查方法 // 资格审查方法
const ptcpModeEnum = { const ptcpModeEnum = {
1: '合格制', 'ptcp_mode_1': '合格制',
2: '有限数量制', 'ptcp_mode_2': '有限数量制',
};
// 流程类型
const chooseProcessEnum = {
1: '第一轮初审详审,固定流程',
}; };
// 标的类别1 // 标的类别1
@ -166,5 +173,6 @@ export {
subjectType2Options, subjectType2Options,
currencyCodeMap, currencyCodeMap,
fundsProviderOptionsMap, fundsProviderOptionsMap,
openTenderFormMap openTenderFormMap,
evalMethodDictMap
}; };

View File

@ -1,6 +1,6 @@
import {Button, message, Modal} from 'antd'; import {Button, message, Modal} from 'antd';
import React, { useRef } from 'react'; import React, { useRef } from 'react';
import { history } from 'umi'; import { history,useNavigate } from 'umi';
import { PageContainer } from '@ant-design/pro-layout'; import { PageContainer } from '@ant-design/pro-layout';
import type { ProColumns, ActionType } from '@ant-design/pro-table'; import type { ProColumns, ActionType } from '@ant-design/pro-table';
import ProTable from '@ant-design/pro-table'; import ProTable from '@ant-design/pro-table';
@ -10,7 +10,7 @@ import { procurementMode } from './dict';
const ProjectFiles: React.FC = () => { const ProjectFiles: React.FC = () => {
const actionRef = useRef<ActionType>(); const actionRef = useRef<ActionType>();
const navigate = useNavigate();
const columns: ProColumns<TableListItem>[] = [ const columns: ProColumns<TableListItem>[] = [
{ {
title: '序号', title: '序号',
@ -93,40 +93,42 @@ const ProjectFiles: React.FC = () => {
render: (text: any, record: any) => ( render: (text: any, record: any) => (
<> <>
{( {(
<Button type="link" onClick={() => <Button type="link" onClick={() =>{
history.push({ clearSessionData();
pathname: '/ProjectLayout/ProjectFiles/file', navigate(
state: { '/ProjectFiles/file', {
record: record, state: {
opt: 'view', record: record,
myRoleCode: 'ebtp-agency-admin' opt: 'view',
} myRoleCode: 'ebtp-agency-admin'
}) }
}> })
}}>
</Button> </Button>
)} )}
{(record.status=== 4) &&( {(record.status=== 4) &&(
<Button type="link" onClick={() => <Button type="link" onClick={() => {
history.push({ clearSessionData();
pathname: '/ProjectLayout/ProjectFiles/file', navigate(
state: { '/ProjectFiles/file', {
record: record, state: {
opt: 'edit' record: record,
} opt: 'edit'
}) }
}> })
}}>
</Button> </Button>
)} )}
{(record.status=== 1) && ( {(record.status=== 1) && (
<Button type="link" onClick={() => { <Button type="link" onClick={() => {
history.push({ navigate(
pathname: '/ProjectLayout/ProjectFiles/file', '/ProjectFiles/file', {
state: { state: {
record: record, record: record,
opt: 'assign', opt: 'assign',
myRoleCode: 'ebtp-agency-admin' myRoleCode: 'ebtp-agency-admin'
} }
}) })
} }
}> }>
</Button> </Button>
@ -195,6 +197,11 @@ const ProjectFiles: React.FC = () => {
}; };
} }
const clearSessionData = () => {
sessionStorage.removeItem("projectData");
sessionStorage.removeItem("opt");
}
return ( return (
<div className="project-file-container" style={{ backgroundColor: '#f8f8f8' }}> <div className="project-file-container" style={{ backgroundColor: '#f8f8f8' }}>
<PageContainer title="委托管理"> <PageContainer title="委托管理">
@ -209,6 +216,7 @@ const ProjectFiles: React.FC = () => {
type="primary" type="primary"
key="primary" key="primary"
onClick={() => { onClick={() => {
clearSessionData();
history.push('/ProjectFiles/file?action=create'); history.push('/ProjectFiles/file?action=create');
}} }}
> >

View File

@ -2,7 +2,6 @@ import { CloseCircleOutlined, MinusCircleOutlined, PlusOutlined } from '@ant-des
import {Button, Card, Col, Form, Popover, Row, message, Divider, Select, Input, Upload, Modal, Table} from 'antd'; import {Button, Card, Col, Form, Popover, Row, message, Divider, Select, Input, Upload, Modal, Table} from 'antd';
import type { FormInstance } from 'antd'; import type { FormInstance } from 'antd';
import { history, useLocation } from '@umijs/max'; import { history, useLocation } from '@umijs/max';
import type { Location } from '@umijs/max';
import React, {useState, Fragment, useRef} from 'react'; import React, {useState, Fragment, useRef} from 'react';
import ProForm, { import ProForm, {
@ -15,7 +14,7 @@ import ProForm, {
} from '@ant-design/pro-form'; } from '@ant-design/pro-form';
import { PageContainer, FooterToolbar } from '@ant-design/pro-layout'; import { PageContainer, FooterToolbar } from '@ant-design/pro-layout';
import { import {
dispatch, getProjectOne, initProjectEntrustForCosco, dispatch, initProjectEntrustForCosco,
updateProjectEntrust updateProjectEntrust
} from './service'; } from './service';
import styles from './style.less'; import styles from './style.less';
@ -40,7 +39,8 @@ import {
currencyCodeMap, currencyCodeMap,
fundsProviderOptionsMap, fundsProviderOptionsMap,
suppQualifyEnumContent, suppQualifyEnumContent,
openTenderFormMap openTenderFormMap,
evalMethodDictMap
} from './dict'; } from './dict';
import CitySelect from '@/components/CitySelect'; import CitySelect from '@/components/CitySelect';
import {useEffect} from "react"; import {useEffect} from "react";
@ -130,43 +130,13 @@ const map = new Map([
//模拟当前登录用户信息 //模拟当前登录用户信息
const getUserMock = () => { const getUserMock = () => {
return { const user = sessionStorage.getItem('userData')?JSON.parse(sessionStorage.getItem('userData')):null;
"userId": "xiaorui",
"fullName": "萧睿", if(!user){
"loginName": "萧睿", message.error("请先登录系统再进行操作!").then()
"organizationId": '001', return;
"organizationName": '中远海运集团',
"deptId": "012",
"deptName": "采购部",
"mobilePhone": "13545674321",
"authorityList": [
{
"roleId": "000006",
"roleName": "供应商",
"roleCode": "ebtp-supplier"
},
{
"roleId": "000007",
"roleName": "代理机构管理员",
"roleCode": "ebtp-agency-admin"
},
{
"roleId": "000009",
"roleName": "代理机构业务经理",
"roleCode": "ebtp-agency-project-manager"
},
{
"roleId": "14",
"roleName": "采购经理(招标采购中心)",
"roleCode": "ebtp-purchase"
},
{
"roleId": "20005",
"roleName": "EBTP系统管理员",
"roleCode": "ebtp-system-admin"
}
]
} }
return user;
} }
//模拟代理机构管理员信息 //模拟代理机构管理员信息
const getAgencyManagerMock = () => { const getAgencyManagerMock = () => {
@ -184,7 +154,8 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
const [suppQualifyDisabled,setSuppQualifyDisabled] = useState(false); const [suppQualifyDisabled,setSuppQualifyDisabled] = useState(false);
const formRef = useRef<FormInstance>(); const formRef = useRef<FormInstance>();
const [form] = Form.useForm(); const [form] = Form.useForm();
const location = useLocation(); const [labelValue,setLabelValue] = useState('标段预算');
const location: any = useLocation();
const projectData: any | null = sessionStorage.getItem('projectData'); const projectData: any | null = sessionStorage.getItem('projectData');
const recordInfo = location?.state?.record?location?.state?.record: projectData?JSON.parse(projectData): undefined; const recordInfo = location?.state?.record?location?.state?.record: projectData?JSON.parse(projectData): undefined;
const myRoleCode = location?.state?.myRoleCode; const myRoleCode = location?.state?.myRoleCode;
@ -193,11 +164,12 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
const isDrafts = recordInfo?.status === 4;//ProjectEntrust表中 status 4 代表 草稿 const isDrafts = recordInfo?.status === 4;//ProjectEntrust表中 status 4 代表 草稿
const isEntrustProject = recordInfo?.organization === 'organization_1'; const isEntrustProject = recordInfo?.organization === 'organization_1';
// 查看或者分派的时候只读 // 查看或者分派的时候只读
const isView = opt === 'view'; const isView = opt === 'view';//列表页查看
const isEdit = opt === 'edit'; const iView = opt === 'iview';//内嵌别的页面查看
const isEdit = opt === 'edit';//编辑
const isUpgrade = opt === 'upgrade';//是否是 版本升级 const isUpgrade = opt === 'upgrade';//是否是 版本升级
const isAssignOpt = opt ==='assign';//分派 const isAssignOpt = opt ==='assign';//分派
const readOnly = (isView || isAssignOpt); const readOnly = (isView || isAssignOpt || iView);
// 编辑或者代理管理员分派的时候显示 // 编辑或者代理管理员分派的时候显示
const isAssign = isAssignOpt && isAgencyAdmin; const isAssign = isAssignOpt && isAgencyAdmin;
// const id = query?.id; // 文件 id // const id = query?.id; // 文件 id
@ -362,7 +334,6 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
} }
try { try {
console.log(values);
const sectionList = values?.bidSection; const sectionList = values?.bidSection;
for(const j in sectionList){ for(const j in sectionList){
const section = sectionList[j]; const section = sectionList[j];
@ -370,6 +341,8 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
section.currencyName = values.currencyName; section.currencyName = values.currencyName;
const categories = section.bidSectionCategory; const categories = section.bidSectionCategory;
const categoryList: any = []; const categoryList: any = [];
const total = 100;
let actTotal = 0;
for(const i in categories){ for(const i in categories){
const category = categories[i]; const category = categories[i];
const categoryListItem = { const categoryListItem = {
@ -377,10 +350,17 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
subCategory: category.type[1], subCategory: category.type[1],
percent: category.percent percent: category.percent
} }
actTotal += category.percent;
categoryList.push(categoryListItem); categoryList.push(categoryListItem);
} }
section.categoryList = categoryList; section.categoryList = categoryList;
if(total!= actTotal){
message.error("任意标段中主要标的类别占比总和应为100")
return;
}
} }
delete values.bidSection; delete values.bidSection;
delete values.regionDict; delete values.regionDict;
values.projectEntrustExpand = { values.projectEntrustExpand = {
@ -463,11 +443,14 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
}, },
render: (props, dom) => { render: (props, dom) => {
if (readOnly && !isAssign) { if (readOnly && !isAssign) {
if(iView){
return null;
}
return ( return (
<FooterToolbar className={styles.footerToolbar}> <FooterToolbar className={styles.footerToolbar}>
<Button key="cancel" onClick={() => { <Button key="cancel" onClick={() => {
if(recordInfo.bidOrgDict === '002' || recordInfo.organization == 'organization_1'){ if(recordInfo.bidOrgDict === '002' || recordInfo.organization == 'organization_1'){
history.goBack(); history.back();
}else{ }else{
history.replace('/ProjectFiles'); history.replace('/ProjectFiles');
} }
@ -538,7 +521,7 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
<Button key="cancel" onClick={() => { <Button key="cancel" onClick={() => {
if(recordInfo.bidOrgDict === '002' || recordInfo.organization =='organization_1'){ if(recordInfo.bidOrgDict === '002' || recordInfo.organization =='organization_1'){
history.goBack(); history.back();
}else{ }else{
history.replace('/ProjectFiles'); history.replace('/ProjectFiles');
} }
@ -598,7 +581,7 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
labelCol={{ span: 5 }} labelCol={{ span: 5 }}
wrapperCol={{ span: 19 }} wrapperCol={{ span: 19 }}
> >
<PageContainer title="新建项目" style={{ paddingBottom: 50 }}> <PageContainer title={iView||isView?false:'新建项目'} className={iView||isView?styles.pageContainer:''} style={{ paddingBottom: 50 }}>
{(isAssign || (isEntrustProject && isDrafts) || (isView && isEntrustProject)) && (<Card title="委托信息" className={styles.card} bordered={false}> {(isAssign || (isEntrustProject && isDrafts) || (isView && isEntrustProject)) && (<Card title="委托信息" className={styles.card} bordered={false}>
<Row gutter={16}> <Row gutter={16}>
<Col span={12}> <Col span={12}>
@ -643,10 +626,10 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
<ProFormText <ProFormText
label={fieldLabels.projectNumber} label={fieldLabels.projectNumber}
name="projectNumber" name="projectNumber"
rules={[{ required: true, message: '请输入项目编号' }]} // rules={[{ required: true, message: '请输入项目编号' }]}
placeholder="请输入" placeholder="请输入"
fieldProps={{ fieldProps={{
disabled: readOnly, disabled: true,
}} }}
/> />
</Col> </Col>
@ -691,7 +674,15 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
<ProFormText <ProFormText
label={fieldLabels.purchasingManagerPhone} label={fieldLabels.purchasingManagerPhone}
name="purchasingManagerPhone" name="purchasingManagerPhone"
rules={[{ required: true, message: '请输入联系电话' }]} rules={[{ required: true, message: '请输入联系电话' },{
validator: (_, value) => {
if (!value) return Promise.resolve();
if (/[a-zA-Z\u4e00-\u9fa5]/.test(value)) {
return Promise.reject('不能包含字母或汉字');
}
return Promise.resolve();
}
}]}
fieldProps={{ fieldProps={{
disabled: readOnly, disabled: readOnly,
}} }}
@ -731,6 +722,13 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
options={budgetTypeOptions} options={budgetTypeOptions}
fieldProps={{ fieldProps={{
disabled: readOnly, disabled: readOnly,
onChange: (value) => {
if(value != 1){
setLabelValue('估算规模金额');
}else{
setLabelValue('标段预算');
}
}
}} }}
/> />
</Col> </Col>
@ -956,7 +954,7 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
</Col> </Col>
<Col span={8}> <Col span={8}>
{!readOnly && (<Button danger onClick={() => remove(field.name)} style={{ marginLeft: 16 }} hidden={fields.length === 1}> {(!readOnly || isEdit) && (<Button danger onClick={() => remove(field.name)} style={{ marginLeft: 16 }} hidden={fields.length === 1}>
</Button>)} </Button>)}
</Col> </Col>
@ -978,10 +976,13 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
return ( return (
<> <>
<ProFormDigit <ProFormDigit
label="标段预算" label={labelValue}
name={[field.name, 'bidSectContractPrice']} name={[field.name, 'bidSectContractPrice']}
rules={[{ required: true, message: '请输入标段预算' }]} rules={[{ required: true, message: '请输入标段预算' }]}
fieldProps={{ precision: 2, style: { width: '80%' } }} fieldProps={{
precision: 2,
style: { width: '80%' }
}}
disabled={readOnly} disabled={readOnly}
/> />
<span style={{ position: 'absolute', right: '6%', top: 5 }}>{currencyCode}</span> <span style={{ position: 'absolute', right: '6%', top: 5 }}>{currencyCode}</span>
@ -1012,11 +1013,17 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
valueEnum={evalMethodDictEnum} valueEnum={evalMethodDictEnum}
fieldProps={{ fieldProps={{
disabled: readOnly, disabled: readOnly,
onChange: (value) => {
const chooseProcessValue = evalMethodDictMap.get(value);
const bidSection = form.getFieldValue('bidSection')
bidSection[field.name].chooseProcess = chooseProcessValue
form.setFieldValue(`bidSection`, bidSection);
}
}} }}
/> />
</Col> </Col>
<Col span={8}> <Col span={8}>
<ProFormSelect {suppQualifyContentShow && (<ProFormSelect
label="资格审查方法" label="资格审查方法"
name={[field.name, 'ptcpMode']} name={[field.name, 'ptcpMode']}
rules={[{ required: true, message: '请选择资格审查方法' }]} rules={[{ required: true, message: '请选择资格审查方法' }]}
@ -1024,7 +1031,7 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
fieldProps={{ fieldProps={{
disabled: readOnly, disabled: readOnly,
}} }}
/> />)}
</Col> </Col>
<Col span={8}> <Col span={8}>
<ProFormSelect <ProFormSelect
@ -1033,7 +1040,7 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
rules={[{ required: true, message: '请选择流程类型' }]} rules={[{ required: true, message: '请选择流程类型' }]}
valueEnum={chooseProcessEnum} valueEnum={chooseProcessEnum}
fieldProps={{ fieldProps={{
disabled: readOnly, disabled: true,
}} }}
/> />
</Col> </Col>
@ -1041,8 +1048,24 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
<ProFormDigit <ProFormDigit
label="评标专家人数" label="评标专家人数"
name={[field.name, 'juryNumber']} name={[field.name, 'juryNumber']}
rules={[{ required: true, message: '请输入评标专家人数' }]} rules={[{ required: true, message: '请输入评标专家人数' },
fieldProps={{ precision: 0, disabled: readOnly }} {validator: (_,value) =>{
const valueInt = Number(value);
if(form.getFieldValue('bidSection')[field.name].evalMethodDict === 'eval_method_1'){
if(valueInt % 2 == 0 || valueInt < 3){
return Promise.reject(new Error('评价方式为最低价发要求专家人数为3人以上奇数!'));
}
}else {
if(valueInt % 2 == 0 || valueInt < 5){
return Promise.reject(new Error('评价方式不是最低价发要求专家人数为5人以上奇数!'));
}
}
return Promise.resolve();
}}]}
fieldProps={{
precision: 0, disabled: readOnly
}}
min={0} min={0}
/> />
</Col> </Col>
@ -1112,6 +1135,7 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
<Form.Item name="remarks" labelCol={{ span: 0 }} wrapperCol={{ span: 24 }}> <Form.Item name="remarks" labelCol={{ span: 0 }} wrapperCol={{ span: 24 }}>
<Input.TextArea <Input.TextArea
autoSize={{ minRows: 3 }} autoSize={{ minRows: 3 }}
maxLength={200}
placeholder="请输入备注" placeholder="请输入备注"
onPressEnter={(e) => { onPressEnter={(e) => {
e.preventDefault(); e.preventDefault();
@ -1123,7 +1147,7 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
<Card title="附件信息" className={styles.card} bordered={false}> <Card title="附件信息" className={styles.card} bordered={false}>
<Form.Item name="attachments" labelCol={{ span: 0 }} wrapperCol={{ span: 24 }} valuePropName="fileList" getValueFromEvent={normFile}> <Form.Item name="attachments" labelCol={{ span: 0 }} wrapperCol={{ span: 24 }} valuePropName="fileList" getValueFromEvent={normFile}>
<ProFormUploadButton <ProFormUploadButton
extra="支持格式:.rar .zip .doc .docx .pdf, 单个文件不超过20M" extra="支持格式:.rar .zip .doc .docx .pdf, 单个文件不超过50M"
name="file" name="file"
title="上传文件" title="上传文件"
accept='.rar,.zip,.doc,.docx,.pdf' accept='.rar,.zip,.doc,.docx,.pdf'
@ -1142,9 +1166,9 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
return Upload.LIST_IGNORE; return Upload.LIST_IGNORE;
} }
const isLt20M = file.size / 1024 / 1024 < 20; const isLt20M = file.size / 1024 / 1024 < 50;
if (!isLt20M) { if (!isLt20M) {
message.error('文件大小不能超过 20MB!'); message.error('文件大小不能超过 50MB!');
return Upload.LIST_IGNORE; return Upload.LIST_IGNORE;
} }

View File

@ -1,6 +1,6 @@
import {Button, message, Modal, Table} from 'antd'; import {Button, message, Modal, Table} from 'antd';
import React, {useEffect, useRef, useState} from 'react'; import React, {useEffect, useRef, useState} from 'react';
import { history } from '@umijs/max'; import { history,useNavigate } from '@umijs/max';
import { PageContainer } from '@ant-design/pro-layout'; import { PageContainer } from '@ant-design/pro-layout';
import type { ProColumns, ActionType } from '@ant-design/pro-table'; import type { ProColumns, ActionType } from '@ant-design/pro-table';
import ProTable from '@ant-design/pro-table'; import ProTable from '@ant-design/pro-table';
@ -17,6 +17,7 @@ interface VersionData {
versionNo: string; versionNo: string;
} }
const ProjectFiles: React.FC = () => { const ProjectFiles: React.FC = () => {
const navigate = useNavigate();
const actionRef = useRef<ActionType>(); const actionRef = useRef<ActionType>();
const [versionData, setVersionData] = useState<VersionData[]>([]); const [versionData, setVersionData] = useState<VersionData[]>([]);
const [isModalOpen, setIsModalOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false);
@ -132,13 +133,13 @@ const ProjectFiles: React.FC = () => {
<> <>
{( {(
<Button type="link" onClick={() => <Button type="link" onClick={() =>
history.push({ navigate(
pathname: '/ProjectFiles/file', '/ProjectFiles/file', {
state: { state: {
record: record, record: record,
opt: 'view' opt: 'view'
} }
}) })
}> }>
</Button> </Button>
)} )}
@ -151,39 +152,39 @@ const ProjectFiles: React.FC = () => {
)} )}
{(record.status === 4) &&( {(record.status === 4) &&(
<Button type="link" onClick={() => <Button type="link" onClick={() =>
history.push({ navigate(
pathname: '/ProjectFiles/file', '/ProjectFiles/file', {
state: { state: {
record: record, record: record,
opt: 'edit' opt: 'edit'
} }
}) })
}> }>
</Button> </Button>
)} )}
{(record.status=== 9) && ( {(record.status=== 9) && (
<Button type="link" onClick={() => { <Button type="link" onClick={() => {
history.push({ navigate(
pathname: '/ProjectFiles/file', '/ProjectFiles/file', {
state: { state: {
record: record, record: record,
opt: 'upgrade' opt: 'update'
} }
}) })
} }
}> }>
</Button> </Button>
)} )}
{(record.status=== 1) && ( {(record.status=== 1) && (
<Button type="link" onClick={() => { <Button type="link" onClick={() => {
history.push({ navigate(
pathname: '/ProjectFiles/file', '/ProjectFiles/file', {
state: { state: {
record: record, record: record,
opt: 'assign', opt: 'edit',
myRoleCode: 'ebtp-agency-admin' myRoleCode: 'ebtp-agency-admin'
} }
}) })
} }
}> }>
</Button> </Button>

View File

@ -1,6 +1,7 @@
// @ts-ignore // @ts-ignore
/* eslint-disable */ /* eslint-disable */
import { request } from '@umijs/max'; // import { request } from '@umijs/max';
import request from '@/utils/request';
// import { TableListItem } from './data'; // import { TableListItem } from './data';
const prefix = '/api/biz-service-ebtp-project/'; const prefix = '/api/biz-service-ebtp-project/';

View File

@ -67,4 +67,12 @@
} }
} }
} }
} }
.pageContainer {
:global {
.ant-pro-page-container-warp {
display: none;
}
}
}

View File

@ -35,6 +35,7 @@ const JudgingPanel: React.FC<{}> = () => {
const [loading, loadingSet] = useState<any>(false); const [loading, loadingSet] = useState<any>(false);
const [sections, setSections] = useState<any>([]); const [sections, setSections] = useState<any>([]);
const [sectionsVal, setSectionsVal] = useState<any>([]); const [sectionsVal, setSectionsVal] = useState<any>([]);
const [maxJuryNumber, setMaxJuryNumber] = useState(0);
const [modalVis, setModalVis] = useState<boolean>(false);//新增评委会 const [modalVis, setModalVis] = useState<boolean>(false);//新增评委会
const [updateData, updateDataSet] = useState<any>();//评委会modal数据 const [updateData, updateDataSet] = useState<any>();//评委会modal数据
const [memberVis, setMemberVis] = useState<boolean>(false); const [memberVis, setMemberVis] = useState<boolean>(false);
@ -53,6 +54,10 @@ const JudgingPanel: React.FC<{}> = () => {
//当前可编辑的行 //当前可编辑的行
const [editableKeys, setEditableRowKeys] = useState<any[]>([]); const [editableKeys, setEditableRowKeys] = useState<any[]>([]);
const [tableData, setTableData] = useState<DataSourceType[]>([]); const [tableData, setTableData] = useState<DataSourceType[]>([]);
const tableDataRef = useRef([])
useEffect(() => {
tableDataRef.current = tableData
}, [tableData])
function getShouName() { function getShouName() {
const method = getProMethod(); const method = getProMethod();
let showNameT: any = { zbr: '', bb: '', pb: '', }//相关标段 标书费 保证金 服务费 let showNameT: any = { zbr: '', bb: '', pb: '', }//相关标段 标书费 保证金 服务费
@ -338,6 +343,9 @@ const JudgingPanel: React.FC<{}> = () => {
} }
setSections(data); setSections(data);
setSectionsVal(secVals); setSectionsVal(secVals);
//获取所有标段中 专家数量得最大值
const maxJuryNumber = Math.max(...sections.map((section: { juryNumber: any; }) => section.juryNumber));
setMaxJuryNumber(maxJuryNumber);
setIndeterminate(!!checked.length && checked.length < secVals.length); setIndeterminate(!!checked.length && checked.length < secVals.length);
setCheckAll(checked.length === secVals.length); setCheckAll(checked.length === secVals.length);
updateData && String(updateData?.reserveStatus) == "1" && getEarliestTime(data, checked);//初始化赋值数据 updateData && String(updateData?.reserveStatus) == "1" && getEarliestTime(data, checked);//初始化赋值数据
@ -591,7 +599,7 @@ const JudgingPanel: React.FC<{}> = () => {
</FormItem></Col> </FormItem></Col>
</Row> </Row>
</Form> </Form>
<h3 className="first-title"></h3> <h3 className="first-title"><span style={{marginLeft:'32px',color: 'black'}}>{{maxJuryNumber}}</span></h3>
<Form form={form}> <Form form={form}>
<Row> <Row>
<Col span={12}><FormItem <Col span={12}><FormItem
@ -629,7 +637,7 @@ const JudgingPanel: React.FC<{}> = () => {
<Form.Item shouldUpdate noStyle > <Form.Item shouldUpdate noStyle >
{() => { {() => {
const expertNumber = form.getFieldValue('expertNumber'); const expertNumber = form.getFieldValue('expertNumber');
if (!expertNumber || expertNumber <= 0) return null; // if (!expertNumber || expertNumber <= 0) return null;
return ( return (
<Form.Item label="抽取专业" name="extractSpecialityList" {...form24Layout}> <Form.Item label="抽取专业" name="extractSpecialityList" {...form24Layout}>
@ -656,7 +664,25 @@ const JudgingPanel: React.FC<{}> = () => {
setEditableRowKeys(keys); setEditableRowKeys(keys);
}, },
onValuesChange: (record, recordList) => { onValuesChange: (record, recordList) => {
setTableData(recordList); let expertNumberInTable = 0;
const newTableData = []
recordList.forEach((item) => {
if (item.extractNumber !== undefined) {
newTableData.push(item)
expertNumberInTable += item.extractNumber || 0
} else {
const _item = tableDataRef.current.find(it => it.uid === item.uid)
if (_item) {
newTableData.push(_item)
expertNumberInTable += _item.extractNumber || 0
} else {
newTableData.push(item)
expertNumberInTable += item.extractNumber || 0
}
}
})
form.setFieldValue('expertNumber',expertNumberInTable)
setTableData(newTableData);
}, },
actionRender: (row, _, dom) => { actionRender: (row, _, dom) => {
return [dom.delete]; return [dom.delete];
@ -712,7 +738,8 @@ const JudgingPanel: React.FC<{}> = () => {
dataIndex: 'extractNumber', dataIndex: 'extractNumber',
width: '30%', width: '30%',
renderFormItem: (_, { record }) => { renderFormItem: (_, { record }) => {
return <InputNumber min={1} addonAfter="人" />; return <InputNumber min={1} addonAfter="人"
/>;
}, },
formItemProps: { formItemProps: {
rules: [ rules: [
@ -736,8 +763,8 @@ const JudgingPanel: React.FC<{}> = () => {
]; ];
/** /**
* 校验函数 * 校验函数
* @param schemaData * @param schemaData
* @returns * @returns
*/ */
const checkData = (schemaData: any) => { const checkData = (schemaData: any) => {
let res = true; let res = true;
@ -819,6 +846,7 @@ const JudgingPanel: React.FC<{}> = () => {
//原下一步逻辑开始 //原下一步逻辑开始
let juryRoomList: any = []; let juryRoomList: any = [];
form.validateFields().then(async (formVals) => { form.validateFields().then(async (formVals) => {
// const formVals = form.getFieldsValue()
const finalVals = { const finalVals = {
...formVals, ...formVals,
extractSpecialityList: tableData, extractSpecialityList: tableData,
@ -835,6 +863,10 @@ const JudgingPanel: React.FC<{}> = () => {
}) : pass = false; }) : pass = false;
//招标人数需要大于5 需要取项目类型 //招标人数需要大于5 需要取项目类型
const bidCount = parseInt(formVals.representativeNumber) + parseInt(formVals.expertNumber); const bidCount = parseInt(formVals.representativeNumber) + parseInt(formVals.expertNumber);
if(maxJuryNumber != bidCount){
pass = false;
message.error("【直接录入专家数量】和【抽取专家数量】总和与建档信息标段设置专家最大数量不符!").then();
}
if (pass) { if (pass) {
pass = checkMan(bidCount, parseInt(formVals.expertNumber)); pass = checkMan(bidCount, parseInt(formVals.expertNumber));
} }
@ -1766,4 +1798,4 @@ const JudgingPanel: React.FC<{}> = () => {
</div> </div>
) )
} }
export default JudgingPanel; export default JudgingPanel;

View File

@ -52,6 +52,10 @@ const JudgingPanel: React.FC<{}> = () => {
//当前可编辑的行 //当前可编辑的行
const [editableKeys, setEditableRowKeys] = useState<any[]>([]); const [editableKeys, setEditableRowKeys] = useState<any[]>([]);
const [tableData, setTableData] = useState<DataSourceType[]>([]); const [tableData, setTableData] = useState<DataSourceType[]>([]);
const tableDataRef = useRef([])
useEffect(() => {
tableDataRef.current = tableData
}, [tableData])
function getShouName() { function getShouName() {
const method = getProMethod(); const method = getProMethod();
let showNameT: any = { zbr: '', bb: '', pb: '', }//相关标段 标书费 保证金 服务费 let showNameT: any = { zbr: '', bb: '', pb: '', }//相关标段 标书费 保证金 服务费
@ -329,6 +333,7 @@ const JudgingPanel: React.FC<{}> = () => {
} }
getShouName();//根据采购类型变名字 getShouName();//根据采购类型变名字
modalVis == true ? getSecs({ ...params }).then((res) => { modalVis == true ? getSecs({ ...params }).then((res) => {
let data = []; let data = [];
let secVals = []; let secVals = [];
if (res.success) { if (res.success) {
@ -615,7 +620,7 @@ const JudgingPanel: React.FC<{}> = () => {
<Form.Item shouldUpdate noStyle > <Form.Item shouldUpdate noStyle >
{() => { {() => {
const expertNumber = form.getFieldValue('expertNumber'); const expertNumber = form.getFieldValue('expertNumber');
if (!expertNumber || expertNumber <= 0) return null; // if (!expertNumber || expertNumber <= 0) return null;
return ( return (
<Form.Item label="抽取专业" name="extractSpecialityList" {...form24Layout}> <Form.Item label="抽取专业" name="extractSpecialityList" {...form24Layout}>
@ -642,7 +647,25 @@ const JudgingPanel: React.FC<{}> = () => {
setEditableRowKeys(keys); setEditableRowKeys(keys);
}, },
onValuesChange: (record, recordList) => { onValuesChange: (record, recordList) => {
setTableData(recordList); let expertNumberInTable = 0;
const newTableData = []
recordList.forEach((item) => {
if (item.extractNumber !== undefined) {
newTableData.push(item)
expertNumberInTable += item.extractNumber || 0
} else {
const _item = tableDataRef.current.find(it => it.uid === item.uid)
if (_item) {
newTableData.push(_item)
expertNumberInTable += _item.extractNumber || 0
} else {
newTableData.push(item)
expertNumberInTable += item.extractNumber || 0
}
}
})
form.setFieldValue('expertNumber',expertNumberInTable)
setTableData(newTableData);
}, },
actionRender: (row, _, dom) => { actionRender: (row, _, dom) => {
return [dom.delete]; return [dom.delete];
@ -697,8 +720,8 @@ const JudgingPanel: React.FC<{}> = () => {
]; ];
/** /**
* 校验函数 * 校验函数
* @param schemaData * @param schemaData
* @returns * @returns
*/ */
const checkData = (schemaData: any) => { const checkData = (schemaData: any) => {
let res = true; let res = true;
@ -781,6 +804,10 @@ const JudgingPanel: React.FC<{}> = () => {
}) : pass = false; }) : pass = false;
//招标人数需要大于5 需要取项目类型 //招标人数需要大于5 需要取项目类型
const bidCount = parseInt(formVals.representativeNumber) + parseInt(formVals.expertNumber); const bidCount = parseInt(formVals.representativeNumber) + parseInt(formVals.expertNumber);
if(bidCount % 2 == 0 || bidCount <5){
pass = false;
message.error("专家人数应为5人以上奇数");
}
if (pass) { if (pass) {
pass = checkMan(bidCount, parseInt(formVals.expertNumber)); pass = checkMan(bidCount, parseInt(formVals.expertNumber));
} }
@ -1709,4 +1736,4 @@ const JudgingPanel: React.FC<{}> = () => {
</div> </div>
) )
} }
export default JudgingPanel; export default JudgingPanel;

View File

@ -56,8 +56,28 @@ const request = extend({
// errorHandler, // 默认错误处理 // errorHandler, // 默认错误处理
credentials: 'include', // 默认请求是否带上cookie credentials: 'include', // 默认请求是否带上cookie
}); });
/**
* 是否登录超时 限时30分钟
*/
const isLoginTimeOut = () => {
const currentTime = new Date();
if(sessionStorage.getItem('loginTime')){
const loginTimeISOString = sessionStorage.getItem('loginTime');
const loginTime = new Date(loginTimeISOString);
const diffInMinutes = (currentTime.getTime() - loginTime.getTime()) / (1000 * 60);
if (diffInMinutes > 30) { // 超过 30 分钟
sessionStorage.removeItem('loginTime'); // 清除登录时间
sessionStorage.removeItem('userData'); // 清除登录用户
history.replace({
pathname: '/internal-login'
})
}
}
}
// request拦截器, 改变url 或 options. // request拦截器, 改变url 或 options.
request.interceptors.request.use(async (url, options) => { request.interceptors.request.use(async (url, options) => {
isLoginTimeOut();
if ( if (
options.method === 'post' || options.method === 'post' ||
options.method === 'put' || options.method === 'put' ||

View File

@ -373,7 +373,7 @@ export function removePurchaseCanOperate() {
} }
/** /**
* 获取returnURL * 获取returnURL
* @returns * @returns
*/ */
export function getReturnURL() { export function getReturnURL() {
let returnURL = sessionStorage.getItem('returnURL'); let returnURL = sessionStorage.getItem('returnURL');
@ -382,7 +382,7 @@ export function getReturnURL() {
/** /**
* 获取getRoomReturnURL * 获取getRoomReturnURL
* @returns * @returns
*/ */
export function getRoomReturnURL() { export function getRoomReturnURL() {
let roomReturnURL = sessionStorage.getItem('roomReturnURL'); let roomReturnURL = sessionStorage.getItem('roomReturnURL');
@ -391,7 +391,7 @@ export function getRoomReturnURL() {
/** /**
* 获取当前评审室对应标段的报价类型(只能在评审室内使用) * 获取当前评审室对应标段的报价类型(只能在评审室内使用)
* @returns * @returns
*/ */
export function getSectionQuot() { export function getSectionQuot() {
let returnURL = sessionStorage.getItem('sectionQuot'); let returnURL = sessionStorage.getItem('sectionQuot');
@ -400,7 +400,7 @@ export function getSectionQuot() {
/** /**
* 根据评审室id获取标段的报价类型 * 根据评审室id获取标段的报价类型
* @param roomId * @param roomId
* @returns 1-%(优惠率,折扣率) 0-元(总价,单价) * @returns 1-%(优惠率,折扣率) 0-元(总价,单价)
*/ */
export async function getQuotationMethodById(roomId: any) { export async function getQuotationMethodById(roomId: any) {
@ -427,7 +427,7 @@ export async function getQuotationMethodById(roomId: any) {
/** /**
* 根据评审室id获取是否开启线下评审 * 根据评审室id获取是否开启线下评审
* @param roomId * @param roomId
* @returns 1-%(优惠率,折扣率) 0-元(总价,单价) * @returns 1-%(优惠率,折扣率) 0-元(总价,单价)
*/ */
export async function getOfflineStatusById(roomId: any) { export async function getOfflineStatusById(roomId: any) {
@ -446,12 +446,13 @@ export async function getOfflineStatusById(roomId: any) {
} }
/** /**
* 存储角色信息 * 存储角色信息
* @param {总数据} userData * @param {总数据} userData
* @param {权限} role * @param {权限} role
* @param {当前角色} roleData * @param {当前角色} roleData
*/ */
export function setUserData(userData: any, role: string, roleData: any): void { export function setUserData(userData: any, role: string, roleData: any): void {
sessionStorage.setItem('userData', JSON.stringify(userData)); sessionStorage.setItem('userData', JSON.stringify(userData));
sessionStorage.setItem('loginTime',new Date().toISOString());
sessionStorage.setItem('roleAuthority', JSON.stringify([role])); sessionStorage.setItem('roleAuthority', JSON.stringify([role]));
sessionStorage.setItem('roleData', JSON.stringify(roleData)); sessionStorage.setItem('roleData', JSON.stringify(roleData));
} }