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 { message, Spin } from 'antd';
import { history } from '@umijs/max';
import { history } from 'umi';
import { cloudReloadToken, cooperReloadToken, fgetUserMsg, getDictionaries, getTokenByCode } from './service';
import { getTotalURLInformation, getURLInformation, isNotEmpty } from '@/utils/CommonUtils';
import { refreshTokenApi } from '@/services/login';
@ -74,19 +74,7 @@ const Loading: React.FC<{}> = () => {
// return;
// }
// } else {
let role = userData.authorityList[0].roleCode;
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);
setUserData(userData, userData.authorityList[0].roleCode, userData.authorityList[0]);
// }
await setDict();//存字典
setTimeout(() => {
@ -101,189 +89,220 @@ const Loading: React.FC<{}> = () => {
//获取用户信息
async function getUserData(token: string, url: string, extra: any, status: number) {
// const res = {
// "userId": "ex-linjp29",
// "lastName": null,
// "firstName": null,
// "fullName": "林剑萍",
// "emailAddress": null,
// "loginName": "ex-linjp29",
// "mobilePhone": null,
// "officePhone": null,
// "sex": null,
// "employeeCategory": null,
// "userType": "1",
// "dateOfBirth": null,
// "age": null,
// "employeeNumber": "1743164896",
// "nationalityId": null,
// "nationality": null,
// "nationalIdentifier": null,
// "supervisorId": null,
// "organizationId": "101058278",
// "organizationName": "湖北信通通信有限公司",
// "orgCategory": null,
// "deptId": "101058278",
// "deptName": "湖北信通通信有限公司",
// "roleIds": null,
// "bussiGroupId": null,
// "positionId": null,
// "currentRoleCode": "undefined",
// "province": null,
// "authorityList": [
// {
// "roleId": "000009",
// "roleName": "代理机构业务经理",
// "roleCode": "ebtp-agency-project-manager",
// "roleScope": "EBTP",
// "authorities": [
// "ebtp-agency-project-manager",
// null,
// "ebtp-agency-project-manager",
// "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin",
// "ebtp-agency-project-manager",
// "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin",
// "ebtp-agency-project-manager",
// "ebtp-agency-project-manager",
// null,
// "ebtp-agency-project-manager",
// null,
// "ebtp-agency-project-manager",
// "ebtp-agency-project-manager",
// null,
// "ebtp-agency-project-manager,ebtp-expert,ebtp-agency-admin",
// null,
// null,
// "ebtp-agency-admin",
// null,
// null,
// null,
// null,
// null,
// null,
// null,
// "ebtp-agency-project-manager",
// "ebtp-agency-project-manager,ebtp-purchase",
// "ebtp-agency-project-manager,ebtp-purchase",
// "ebtp-agency-project-manager,ebtp-purchase",
// "ebtp-agency-project-manager,ebtp-purchase",
// "ebtp-agency-project-manager,ebtp-purchase",
// null,
// null,
// null,
// null,
// null,
// "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier",
// "ebtp-agency-project-manager,ebtp-supplier",
// "ebtp-agency-project-manager",
// "ebtp-agency-project-manager",
// null
// ]
// },
// {
// "roleId": "000006",
// "roleName": "供应商",
// "roleCode": "ebtp-supplier",
// "roleScope": "EBTP",
// "authorities": [
// "system:user:test",
// "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin",
// "system:user:test",
// "ebtp-agency-project-manager",
// "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin",
// "ebtp-supplier",
// "ebtp-supplier",
// "system:user:test",
// "system:user:test",
// "ebtp-agency-project-manager,ebtp-expert,ebtp-agency-admin",
// "ebtp-supplier",
// "system:user:test",
// "ebtp-supplier",
// "system:user:test",
// "ebtp-supplier",
// "ebtp-supplier",
// "ebtp-supplier",
// "ebtp-supplier",
// "ebtp-supplier",
// "ebtp-supplier",
// "ebtp-supplier",
// null,
// null,
// null,
// "ebtp-agency-project-manager,ebtp-expert,ebtp-supplier",
// "ebtp-agency-project-manager,ebtp-supplier",
// "ebtp-supplier",
// "system:user:test",
// "system:user:test",
// "system:user:test",
// "ebtp-agency-project-manager",
// "system:user:test"
// ]
// }
// ]
// }
// 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);
// }
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') {
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);
}
const res = {
"userId": "ex-wanghy623",
"lastName": null,
"firstName": null,
"fullName": "曹鹏",
"emailAddress": null,
"loginName": "ex-wanghy623",
"mobilePhone": null,
"officePhone": null,
"sex": null,
"employeeCategory": null,
"userType": "1",
"dateOfBirth": null,
"age": null,
"employeeNumber": "1753782355",
"nationalityId": null,
"nationality": null,
"nationalIdentifier": null,
"supervisorId": null,
"organizationId": "101152137",
"organizationName": "河北通信工程招投标有限公司",
"orgCategory": null,
"deptId": "101152137",
"deptName": "河北通信工程招投标有限公司",
"roleIds": null,
"bussiGroupId": null,
"positionId": null,
"currentRoleCode": "undefined",
"province": null,
"authorityList": [
{
"roleId": "000007",
"roleName": "代理机构管理员",
"roleCode": "ebtp-agency-admin",
"roleScope": "EBTP",
"authorities": [
"ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin",
"ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin",
null,
"ebtp-agency-admin",
null,
null,
"ebtp-agency-project-manager,ebtp-expert,ebtp-agency-admin",
null,
"ebtp-agency-admin",
null,
null,
null,
null,
"ebtp-agency-admin",
null,
"ebtp-agency-project-manager,ebtp-expert,ebtp-supplier",
"ebtp-agency-project-manager,ebtp-supplier",
"ebtp-agency-project-manager",
"ebtp-agency-project-manager"
]
},
{
"roleId": "000009",
"roleName": "代理机构业务经理",
"roleCode": "ebtp-agency-project-manager",
"roleScope": "EBTP",
"authorities": [
null,
"ebtp-agency-project-manager",
"ebtp-agency-project-manager",
null,
"ebtp-agency-project-manager",
null,
"ebtp-agency-project-manager",
"ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin",
null,
"ebtp-agency-project-manager",
"ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin",
"ebtp-agency-project-manager",
"ebtp-agency-project-manager",
null,
null,
"ebtp-agency-project-manager",
null,
"ebtp-agency-project-manager,ebtp-expert,ebtp-agency-admin",
null,
null,
"ebtp-agency-admin",
null,
null,
null,
null,
null,
null,
null,
"ebtp-agency-project-manager",
"ebtp-agency-project-manager,ebtp-purchase",
"ebtp-agency-project-manager,ebtp-purchase",
"ebtp-agency-project-manager,ebtp-purchase",
"ebtp-agency-project-manager,ebtp-purchase",
"ebtp-agency-project-manager,ebtp-purchase",
null,
null,
null,
null,
null,
null,
null,
"ebtp-agency-project-manager,ebtp-expert,ebtp-supplier",
"ebtp-agency-project-manager,ebtp-supplier",
"ebtp-agency-project-manager",
"ebtp-agency-project-manager",
null
]
},
{
"roleId": "000006",
"roleName": "供应商",
"roleCode": "ebtp-supplier",
"roleScope": "EBTP",
"authorities": [
"ebtp-supplier",
"system:user:test",
"ebtp-supplier",
"system:user:test",
"ebtp-agency-project-manager",
"system:user:test",
null,
"ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin",
"system:user:test",
"ebtp-agency-project-manager,ebtp-expert,ebtp-supplier,ebtp-agency-admin",
"ebtp-agency-project-manager,ebtp-expert,ebtp-agency-admin",
"system:user:test",
"ebtp-supplier",
null,
"ebtp-supplier",
"ebtp-supplier",
"ebtp-supplier",
"ebtp-supplier",
"system:user:test",
"ebtp-supplier",
"ebtp-supplier",
"ebtp-supplier",
"ebtp-supplier",
null,
null,
null,
null,
"ebtp-agency-project-manager,ebtp-expert,ebtp-supplier",
"ebtp-agency-project-manager,ebtp-supplier",
"ebtp-supplier",
"system:user:test",
"system:user:test",
"system:user:test",
"ebtp-agency-project-manager",
"system:user:test"
]
}
} 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
async function getToken(code: string, data: any) {

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
import {Button, message, Modal} from 'antd';
import React, { useRef } from 'react';
import { history } from 'umi';
import { history,useNavigate } from 'umi';
import { PageContainer } from '@ant-design/pro-layout';
import type { ProColumns, ActionType } 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 actionRef = useRef<ActionType>();
const navigate = useNavigate();
const columns: ProColumns<TableListItem>[] = [
{
title: '序号',
@ -93,40 +93,42 @@ const ProjectFiles: React.FC = () => {
render: (text: any, record: any) => (
<>
{(
<Button type="link" onClick={() =>
history.push({
pathname: '/ProjectLayout/ProjectFiles/file',
state: {
record: record,
opt: 'view',
myRoleCode: 'ebtp-agency-admin'
}
})
}>
<Button type="link" onClick={() =>{
clearSessionData();
navigate(
'/ProjectFiles/file', {
state: {
record: record,
opt: 'view',
myRoleCode: 'ebtp-agency-admin'
}
})
}}>
</Button>
)}
{(record.status=== 4) &&(
<Button type="link" onClick={() =>
history.push({
pathname: '/ProjectLayout/ProjectFiles/file',
state: {
record: record,
opt: 'edit'
}
})
}>
<Button type="link" onClick={() => {
clearSessionData();
navigate(
'/ProjectFiles/file', {
state: {
record: record,
opt: 'edit'
}
})
}}>
</Button>
)}
{(record.status=== 1) && (
<Button type="link" onClick={() => {
history.push({
pathname: '/ProjectLayout/ProjectFiles/file',
state: {
record: record,
opt: 'assign',
myRoleCode: 'ebtp-agency-admin'
}
})
navigate(
'/ProjectFiles/file', {
state: {
record: record,
opt: 'assign',
myRoleCode: 'ebtp-agency-admin'
}
})
}
}>
</Button>
@ -195,6 +197,11 @@ const ProjectFiles: React.FC = () => {
};
}
const clearSessionData = () => {
sessionStorage.removeItem("projectData");
sessionStorage.removeItem("opt");
}
return (
<div className="project-file-container" style={{ backgroundColor: '#f8f8f8' }}>
<PageContainer title="委托管理">
@ -209,6 +216,7 @@ const ProjectFiles: React.FC = () => {
type="primary"
key="primary"
onClick={() => {
clearSessionData();
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 type { FormInstance } from 'antd';
import { history, useLocation } from '@umijs/max';
import type { Location } from '@umijs/max';
import React, {useState, Fragment, useRef} from 'react';
import ProForm, {
@ -15,7 +14,7 @@ import ProForm, {
} from '@ant-design/pro-form';
import { PageContainer, FooterToolbar } from '@ant-design/pro-layout';
import {
dispatch, getProjectOne, initProjectEntrustForCosco,
dispatch, initProjectEntrustForCosco,
updateProjectEntrust
} from './service';
import styles from './style.less';
@ -40,7 +39,8 @@ import {
currencyCodeMap,
fundsProviderOptionsMap,
suppQualifyEnumContent,
openTenderFormMap
openTenderFormMap,
evalMethodDictMap
} from './dict';
import CitySelect from '@/components/CitySelect';
import {useEffect} from "react";
@ -130,43 +130,13 @@ const map = new Map([
//模拟当前登录用户信息
const getUserMock = () => {
return {
"userId": "xiaorui",
"fullName": "萧睿",
"loginName": "萧睿",
"organizationId": '001',
"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"
}
]
const user = sessionStorage.getItem('userData')?JSON.parse(sessionStorage.getItem('userData')):null;
if(!user){
message.error("请先登录系统再进行操作!").then()
return;
}
return user;
}
//模拟代理机构管理员信息
const getAgencyManagerMock = () => {
@ -184,7 +154,8 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
const [suppQualifyDisabled,setSuppQualifyDisabled] = useState(false);
const formRef = useRef<FormInstance>();
const [form] = Form.useForm();
const location = useLocation();
const [labelValue,setLabelValue] = useState('标段预算');
const location: any = useLocation();
const projectData: any | null = sessionStorage.getItem('projectData');
const recordInfo = location?.state?.record?location?.state?.record: projectData?JSON.parse(projectData): undefined;
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 isEntrustProject = recordInfo?.organization === 'organization_1';
// 查看或者分派的时候只读
const isView = opt === 'view';
const isEdit = opt === 'edit';
const isView = opt === 'view';//列表页查看
const iView = opt === 'iview';//内嵌别的页面查看
const isEdit = opt === 'edit';//编辑
const isUpgrade = opt === 'upgrade';//是否是 版本升级
const isAssignOpt = opt ==='assign';//分派
const readOnly = (isView || isAssignOpt);
const readOnly = (isView || isAssignOpt || iView);
// 编辑或者代理管理员分派的时候显示
const isAssign = isAssignOpt && isAgencyAdmin;
// const id = query?.id; // 文件 id
@ -362,7 +334,6 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
}
try {
console.log(values);
const sectionList = values?.bidSection;
for(const j in sectionList){
const section = sectionList[j];
@ -370,6 +341,8 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
section.currencyName = values.currencyName;
const categories = section.bidSectionCategory;
const categoryList: any = [];
const total = 100;
let actTotal = 0;
for(const i in categories){
const category = categories[i];
const categoryListItem = {
@ -377,10 +350,17 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
subCategory: category.type[1],
percent: category.percent
}
actTotal += category.percent;
categoryList.push(categoryListItem);
}
section.categoryList = categoryList;
if(total!= actTotal){
message.error("任意标段中主要标的类别占比总和应为100")
return;
}
}
delete values.bidSection;
delete values.regionDict;
values.projectEntrustExpand = {
@ -463,11 +443,14 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
},
render: (props, dom) => {
if (readOnly && !isAssign) {
if(iView){
return null;
}
return (
<FooterToolbar className={styles.footerToolbar}>
<Button key="cancel" onClick={() => {
if(recordInfo.bidOrgDict === '002' || recordInfo.organization == 'organization_1'){
history.goBack();
history.back();
}else{
history.replace('/ProjectFiles');
}
@ -538,7 +521,7 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
<Button key="cancel" onClick={() => {
if(recordInfo.bidOrgDict === '002' || recordInfo.organization =='organization_1'){
history.goBack();
history.back();
}else{
history.replace('/ProjectFiles');
}
@ -598,7 +581,7 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
labelCol={{ span: 5 }}
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}>
<Row gutter={16}>
<Col span={12}>
@ -643,10 +626,10 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
<ProFormText
label={fieldLabels.projectNumber}
name="projectNumber"
rules={[{ required: true, message: '请输入项目编号' }]}
// rules={[{ required: true, message: '请输入项目编号' }]}
placeholder="请输入"
fieldProps={{
disabled: readOnly,
disabled: true,
}}
/>
</Col>
@ -691,7 +674,15 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
<ProFormText
label={fieldLabels.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={{
disabled: readOnly,
}}
@ -731,6 +722,13 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
options={budgetTypeOptions}
fieldProps={{
disabled: readOnly,
onChange: (value) => {
if(value != 1){
setLabelValue('估算规模金额');
}else{
setLabelValue('标段预算');
}
}
}}
/>
</Col>
@ -956,7 +954,7 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
</Col>
<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>)}
</Col>
@ -978,10 +976,13 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
return (
<>
<ProFormDigit
label="标段预算"
label={labelValue}
name={[field.name, 'bidSectContractPrice']}
rules={[{ required: true, message: '请输入标段预算' }]}
fieldProps={{ precision: 2, style: { width: '80%' } }}
fieldProps={{
precision: 2,
style: { width: '80%' }
}}
disabled={readOnly}
/>
<span style={{ position: 'absolute', right: '6%', top: 5 }}>{currencyCode}</span>
@ -1012,11 +1013,17 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
valueEnum={evalMethodDictEnum}
fieldProps={{
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 span={8}>
<ProFormSelect
{suppQualifyContentShow && (<ProFormSelect
label="资格审查方法"
name={[field.name, 'ptcpMode']}
rules={[{ required: true, message: '请选择资格审查方法' }]}
@ -1024,7 +1031,7 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
fieldProps={{
disabled: readOnly,
}}
/>
/>)}
</Col>
<Col span={8}>
<ProFormSelect
@ -1033,7 +1040,7 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
rules={[{ required: true, message: '请选择流程类型' }]}
valueEnum={chooseProcessEnum}
fieldProps={{
disabled: readOnly,
disabled: true,
}}
/>
</Col>
@ -1041,8 +1048,24 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
<ProFormDigit
label="评标专家人数"
name={[field.name, 'juryNumber']}
rules={[{ required: true, message: '请输入评标专家人数' }]}
fieldProps={{ precision: 0, disabled: readOnly }}
rules={[{ required: true, message: '请输入评标专家人数' },
{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}
/>
</Col>
@ -1112,6 +1135,7 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
<Form.Item name="remarks" labelCol={{ span: 0 }} wrapperCol={{ span: 24 }}>
<Input.TextArea
autoSize={{ minRows: 3 }}
maxLength={200}
placeholder="请输入备注"
onPressEnter={(e) => {
e.preventDefault();
@ -1123,7 +1147,7 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
<Card title="附件信息" className={styles.card} bordered={false}>
<Form.Item name="attachments" labelCol={{ span: 0 }} wrapperCol={{ span: 24 }} valuePropName="fileList" getValueFromEvent={normFile}>
<ProFormUploadButton
extra="支持格式:.rar .zip .doc .docx .pdf, 单个文件不超过20M"
extra="支持格式:.rar .zip .doc .docx .pdf, 单个文件不超过50M"
name="file"
title="上传文件"
accept='.rar,.zip,.doc,.docx,.pdf'
@ -1142,9 +1166,9 @@ const ProjectFileCreate: React.FC<Record<string, any>> = () => {
return Upload.LIST_IGNORE;
}
const isLt20M = file.size / 1024 / 1024 < 20;
const isLt20M = file.size / 1024 / 1024 < 50;
if (!isLt20M) {
message.error('文件大小不能超过 20MB!');
message.error('文件大小不能超过 50MB!');
return Upload.LIST_IGNORE;
}

View File

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

View File

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

View File

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

View File

@ -56,8 +56,28 @@ const request = extend({
// errorHandler, // 默认错误处理
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.interceptors.request.use(async (url, options) => {
isLoginTimeOut();
if (
options.method === 'post' ||
options.method === 'put' ||

View File

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