Files
fe_service_ebtp_frontend/src/components/LayLeftMenu/index.tsx

628 lines
22 KiB
TypeScript
Raw Normal View History

2021-01-16 11:29:42 +08:00
import React, { useState, useEffect } from 'react';
2022-03-10 14:24:13 +08:00
import { history } from 'umi';
import {
getLeftMenu,
getBtnText,
nextNode,
getLeader,
finishTurn,
openTurn,
getGys,
finishFlow,
getOfferUserId,
getSingIds,
firstNextNode,
queryGys
} from './service';
import { Menu, Button, Modal, message, Spin, Transfer, Tooltip, Tag, Select } from 'antd';
import { getRoomId, getSessionUserData, getSessionRoleData } from '@/utils/session';
2021-01-16 11:29:42 +08:00
import './index.less';
2022-03-10 14:24:13 +08:00
import { CarryOutOutlined, DownOutlined, ExclamationCircleOutlined, ReloadOutlined } from '@ant-design/icons';
import { btnAuthority } from '@/utils/authority';
//评审室内流程菜单
2021-01-16 11:29:42 +08:00
const Index: React.FC<{}> = () => {
2022-03-10 14:24:13 +08:00
const { confirm } = Modal;
const { SubMenu } = Menu;
2021-01-16 11:29:42 +08:00
const [data, setData] = React.useState<any>([]);
2022-03-10 14:24:13 +08:00
const [spin, spinSet] = useState<boolean>(false);
2021-01-16 11:29:42 +08:00
const [leader, setLeader] = useState('');
2022-03-10 14:24:13 +08:00
const [nodeId, nodeIdSet] = useState('');//节点id
const [turnId, turnIdSet] = useState('');//轮次id
const [btnText, btnTextSet] = useState(''); //按钮文字
const [firstNextStep, firstNextStepSet] = useState(false); //是否轮次第一个节点
const [instTurnName, instTurnNameSet] = useState(''); //第几轮
const [btnMes, btnMesSet] = useState('');
const [flowFinish, flowFinishSet] = useState<boolean>(false); //流程是否结束
const [stop, stopSet] = useState<boolean>(false); //终止流程 按钮显隐
const [finishAllTurn, finishAllTurnSet] = useState<boolean>(false); //所有轮次是否结束
const [menuShow, menuShowSet] = useState<string[]>([]);
const [count, countSet] = useState<any>(0); //触发useEffect
const [chooseGys, chooseGysSet] = useState<any>(false); //选择供应商
const [offerUserId, offerUserIdSet] = useState<any>(''); //评审专家id
const [singUserId, singUserIdSet] = useState<any>([]); //评审专家id
const userId = getSessionUserData().userId;
const role = getSessionRoleData().roleCode;
//获取比选一阶段二次项目,自定义流程,当前供应商
const isBxOneSecondCustom = sessionStorage.getItem("isBxOneSecondCustom");
2022-03-10 14:24:13 +08:00
function showConfirm(mes?: any, confirmFlag?: boolean) {
//环节流转提示
mes == '是否开启' ? (mes = mes + instTurnName + '') : mes;
confirm({
title: mes,
icon: <ExclamationCircleOutlined />,
centered: true,
okText: '确定',
cancelText: '取消',
async onOk() {
await handleOk(confirmFlag);
},
onCancel() {
spinSet(false);
},
});
}
function overConfirm(mes?: any) {
//结束流程提示
confirm({
title: mes,
icon: <ExclamationCircleOutlined />,
okText: '确定',
cancelText: '取消',
centered: true,
async onOk() {
await finishFlowFc();
},
onCancel() {
spinSet(false);
},
});
}
const handleOk = async (confirmFlag?: boolean) => {
if (btnText == '开启') {
await getGysData();
}
if (btnText == '结束轮次') {
await finishTurnFc(confirmFlag);
}
2021-01-16 11:29:42 +08:00
if (btnText == '下一步') {
2022-03-10 14:24:13 +08:00
await nextStep(confirmFlag);
2021-01-16 11:29:42 +08:00
}
2022-03-10 14:24:13 +08:00
return;
2021-01-16 11:29:42 +08:00
};
2022-03-10 14:24:13 +08:00
//下一步方法
async function nextStep(confirmFlag?: boolean) {
spinSet(true);
if (firstNextStep) {
await firstNextNode(turnId, confirmFlag).then((res: any) => {
if (res.code === 200) {
if (res.data.result) {
message.success('成功进入下一节点');
countSet(count + 1);
} else {
if (res.data.confirmFlag) {
showConfirm(res.data.message, true);
}
}
} else {
countSet(count + 1);
2021-01-16 11:29:42 +08:00
}
2022-03-10 14:24:13 +08:00
});
} else {
await nextNode(nodeId, confirmFlag).then((res) => {
if (res.code === 200) {
if (res.data.result) {
message.success('成功进入下一节点');
countSet(count + 1);
} else {
if (res.data.confirmFlag) {
showConfirm(res.data.message, true);
}
}
} else {
countSet(count + 1);
}
});
2021-01-16 11:29:42 +08:00
}
2022-03-10 14:24:13 +08:00
}
//开启轮次方法
async function openTurnFc() {
spinSet(true);
await openTurn({ assessRoomId: getRoomId(), roundIdList: targetKeys }).then((res) => {
if (res.code === 200) {
message.success('开启轮次成功');
chooseGysSet(false);
}
});
countSet(count + 1); //触发useEffect
}
//结束轮次方法
async function finishTurnFc(confirmFlag?: boolean) {
spinSet(true);
await finishTurn(turnId, confirmFlag).then((res) => {
if (res.code === 200) {
if (res.data.result) {
message.success('结束轮次成功');
countSet(count + 1); //触发useEffect
} else {
if (res.data.confirmFlag) {
showConfirm(res.data.message, true);
}
}
} else {
countSet(count + 1); //触发useEffect
}
});
}
//结束流程方法
async function finishFlowFc() {
spinSet(true);
await finishFlow(getRoomId()).then((res) => {
if (res.code === 200) {
message.success('结束流程成功');
}
});
countSet(count + 1); //触发useEffect
}
//取数据
async function getData(leader?: any, offerUserId?: any, ids?: any) {
let nowTurn: string[] = [];
let name: any = '';
let indexT: any = 0;
let url = '';
let nodeIdT = '';
let turnIdT = '';
spinSet(true);
await getLeftMenu(getRoomId()).then((res) => {
2021-01-16 11:29:42 +08:00
if (res.code == 200) {
2022-03-10 14:24:13 +08:00
res.data.map((item: any, index: any) => {
//跳转当前节点页面
if (item.status == 1) {
turnIdT = item.id;
}
item.nodeVOList.map((item: any) => {
if (item.status == 1 && item.moduleUrl != null) {
nodeIdT = item.id;
url =
makeUrl(item.moduleUrl, leader) +
`?turnId=${item.instTurnId}&nodeId=${item.id}&turnSort=${item.instTurnSort}`;
if (item.moduleUrl === '/EvaRoom/Eva/BidOffer' && userId != offerUserId) {
//报价评审 只有评审分工分到的专家能点
url = '';
}
if (item.moduleUrl === '/EvaRoom/Eva/Sing' || item.moduleUrl === '/EvaRoom/Eva/Openning') {
//唱价(询价)、唱价 只有可查看报价的专家可看
if (role == 'ebtp-expert' && ids.findIndex((item: any) => item == userId) == -1) {
url = '';
}
}
}
});
if (item.status == 1) {
nowTurn.push(`${item.instTurnSort}SubMenu`);
}
//获取要开启的轮次名
if (item.status == 2) {
indexT = index + 1;
}
if (index == indexT) {
name = item.instTurnName;
}
});
menuShowSet(nowTurn);
setData(res.data);
nodeIdSet(nodeIdT);
turnIdSet(turnIdT);
instTurnNameSet(name);
2021-01-16 11:29:42 +08:00
} else {
2022-03-10 14:24:13 +08:00
message.info('请联系管理员');
2021-01-16 11:29:42 +08:00
}
2022-03-10 14:24:13 +08:00
});
//取按钮
await getBtnText(getRoomId()).then((res) => {
let btntxt = '';
let btnMesT = '';
let flowFinishT = false;
let stopT = true;
let finishAllTurnT = false;
2021-01-16 11:29:42 +08:00
if (res.code == 200) {
if (res.data.openTurnButton) {
2022-03-10 14:24:13 +08:00
btntxt = '开启';
btnMesT = '是否开启';
stopT = false;
} else if (res.data.finishTurnButton) {
btntxt = '结束轮次';
btnMesT = '是否结束轮次?';
} else if (res.data.firstNextStepButton) {
btntxt = '下一步';
btnMesT = '是否进入下一环节?';
} else if (res.data.nextStepButton) {
btntxt = '下一步';
btnMesT = '是否进入下一环节?';
2021-01-16 11:29:42 +08:00
}
2022-03-10 14:24:13 +08:00
if (res.data.flowFinish) {
flowFinishT = true;
2021-01-16 11:29:42 +08:00
}
2022-03-10 14:24:13 +08:00
if (res.data.finishAllTurn) {
finishAllTurnT = true;
stopT = false;
2021-01-16 11:29:42 +08:00
}
}
btnTextSet(btntxt);
2022-03-10 14:24:13 +08:00
btnMesSet(btnMesT);
firstNextStepSet(res?.data?.firstNextStepButton);
flowFinishSet(flowFinishT);
finishAllTurnSet(finishAllTurnT);
stopSet(stopT);
});
spinSet(false);
url != '' && history.push(url);
}
//专家获取数据
async function expertGetData(ids: any) {
let leader = '';
let offerUserId = '';
await getLeader(getRoomId(), getSessionUserData().userId).then((res) => {
if (res.code == 200) {
leader = res.data;
setLeader(res.data);
}
});
await getOfferUserId(getRoomId()).then((res) => {
if (res.code == 200) {
offerUserId = res.data[0];
offerUserIdSet(res.data[0]);
}
});
getData(leader, offerUserId, ids);
}
//处理url
function makeUrl(url: any, leader: any) {
if (
url == '/EvaRoom/Eva/BidPreliminary' ||
url == '/EvaRoom/Eva/BidDetailed' ||
url == '/EvaRoom/Eva/BidOffer' ||
url == '/EvaRoom/Eva/BidNumber'
) {
url = url + leader;
}
return url;
}
//初始化
useEffect(() => {
spinSet(true);
let ids: any;
if (getSessionRoleData().roleCode === 'ebtp-expert') {
//ebtp-expert
//可查看报价专家ids
getSingIds(getRoomId()).then((res: any) => {
if (res.code == 200) {
ids = res.data;
singUserIdSet(res.data);
}
}).then(() => {
expertGetData(ids);
})
} else {
getData();
2021-01-16 11:29:42 +08:00
}
}, [count]);
2022-03-10 14:24:13 +08:00
//选择供应商
const [gysData, gysDataSet] = useState<any>([]);
const [firstRvwScs, firstRvwScsSet] = useState<any>([]);//初审合格的
const [firstRvwFail, firstRvwFailSet] = useState<any>([]);//初审不合格的
const [targetKeys, setTargetKeys] = useState<any>([]);
const [firstRvw, firstRvwSet] = useState<any>(false);//是否经历初审 控制显示合格不合格数量显隐
const [targetCount, targetCountSet] = useState<any>({ scsCount: 0, failCount: 0 });//进入下一轮的 合格的数量 不合格的数量
const [selectedKeys, setSelectedKeys] = useState<any>([]);
const [selectedKeysTransfer, setSelectedKeysTransfer] = useState<any>([]);//穿梭框用
const [chooseTurn, chooseTurnSet] = useState<boolean>(false);//查看供应商选择情况vis
const modalHeight = (window.innerHeight * 96) / 100;
const onChange = (nextTargetKeys: any, direction: any, moveKeys: any) => {
if (chooseTurn) return;
setTargetKeys(nextTargetKeys);
//遍历移动的数据 控制合格不合格显示数量
if (firstRvw) {
let scsChange: number = 0;
let failChange: number = 0;
moveKeys.map((item: any) => {
firstRvwScs.includes(item) && scsChange++;
firstRvwFail.includes(item) && failChange++;
});
if (direction === 'left') {
targetCountSet({ scsCount: targetCount.scsCount - scsChange, failCount: targetCount.failCount - failChange })
} else {
targetCountSet({ scsCount: targetCount.scsCount + scsChange, failCount: targetCount.failCount + failChange })
}
}
};
const onSelectChange = (sourceSelectedKeys: any, targetSelectedKeys: any) => {
if (chooseTurn) return;
setSelectedKeysTransfer([...sourceSelectedKeys, ...targetSelectedKeys]);
};
//取当前轮次所有供应商
async function getGysData() {
let dataT: any = [];
let _scs: any = [];
let _fail: any = [];
let target: any = [];
let firstRvw = false;//是否经历初审
await getGys(getRoomId()).then((res) => {
if (res.code == 200) {
res.data.map((item: any, index: number) => {
let one = {
key: item.id,
title: item.companyName,
firstRvwResult: item.firstRvwResult,//0 未通过 1通过 2没经历初审
}
dataT.push(one);
item.firstRvwResult === 0 && _fail.push(one.key);//按类别存key
item.firstRvwResult === 1 && _scs.push(one.key);
item.firstRvwResult !== 0 && target.push(item.id);//右侧数据
index === 1 && item.firstRvwResult < 2 && (firstRvw = true);//是否经历初审
});
}
});
gysDataSet(dataT);
setTargetKeys(target);
firstRvwScsSet(_scs);
firstRvwFailSet(_fail);
firstRvwSet(firstRvw);
targetCountSet({ scsCount: target.length, failCount: 0 })
chooseGysSet(true);
countSet(count + 1); //触发useEffect
}
const { Option } = Select;
function returnGysModal() {
const select = <Select
style={{ width: 100 }}
placeholder={'请选择'}
onChange={async (value: any) => {
spinSet(true);
let thisTurnId = data[value].id;
let preTurnId = data[value - 1].id;
await queryGys(thisTurnId, preTurnId).then((res) => {
if (res?.code == 200) {
let all = [...res?.data[thisTurnId], ...res?.data[preTurnId]]
let target: any[] = [];
res?.data[thisTurnId].map((i: { key: any; }) => {
target.push(i.key)
})
gysDataSet(all);//穿梭框数据源
setTargetKeys(target);//穿梭框右侧数据 keys
targetCountSet({ scsCount: target.length, failCount: 0 })
}
}).finally(() => spinSet(false))
}}
>
{
data?.map((i: any, index: any) => {
if (index == 0 || i.status === 3) return;//1:进行中2:已结束3:未开启
return <Option key={i.id + 'option'} value={index}>{i.instTurnName}</Option>
})
}
</Select >
const footer = chooseTurn ? { footer: <Button type='primary' onClick={() => closeFc()}></Button> } : {};
2022-03-10 14:24:13 +08:00
const closeFc = async () => {
chooseGysSet(false);
chooseTurnSet(false);
gysDataSet([]);
firstRvwSet(false);
}
return (
<Modal
visible={chooseGys}
centered
width={1200}
style={{ maxHeight: modalHeight }}
destroyOnClose
{...footer}
okButtonProps={{ disabled: spin }}
bodyStyle={{ maxHeight: modalHeight - 107, overflowY: 'auto' }}
title={chooseTurn ? '查看已开启轮次所选供应商' : '选择进入下一轮次的供应商'}
onCancel={() => closeFc()}
onOk={() => {
if (chooseTurn) {
closeFc();
return
}
if (targetKeys.length > 0) {
openTurnFc();
} else {
message.error('未选中供应商');
}
}}
>
<Spin spinning={spin}>
{
chooseTurn ?
<div style={{ fontSize: 16, fontWeight: 'bold', marginBottom: 16 }}>&nbsp;{select}&nbsp;</div>
:
<p style={{ fontSize: 16, fontWeight: 'bold' }}></p>
}
<Transfer
dataSource={gysData}
listStyle={{ width: '50%', height: 400 }}
titles={[chooseTurn ? '未进入所选轮次的供应商' : '可选供应商(不进入下一轮)', chooseTurn ? '已进入所选轮次的供应商' : '进入下一轮供应商']}
targetKeys={targetKeys}
selectedKeys={selectedKeysTransfer}
onChange={onChange}
onSelectChange={onSelectChange}
disabled={isBxOneSecondCustom == "1"}
2022-03-10 14:24:13 +08:00
selectAllLabels={[, (info: { selectedCount: number, totalCount: number }) => <>
{
info.selectedCount != 0 && `${info.selectedCount}/`
}
{info.totalCount}&nbsp;&nbsp;&nbsp;
{firstRvw &&
<>
{targetCount.scsCount > 0 &&
<><Tag color="success"></Tag>{targetCount.scsCount} &nbsp;&nbsp;</>
}
{targetCount.failCount > 0 &&
<><Tag color="error"></Tag>{targetCount.failCount} </>
}
</>
}
</>]}
render={(item: any) => {
return (
<>
{item.firstRvwResult === 1 && <Tag color="success"></Tag>}
{item.firstRvwResult === 0 && <Tag color="error"></Tag>}
{item.title}
</>
)
}}
/>
</Spin>
</Modal>
);
}
function onOpenChange(openKeys: any) {
menuShowSet([openKeys[openKeys.length - 1]]);
}
function onSelect({ selectedKeys }: any) {
setSelectedKeys(selectedKeys);
}
2021-01-16 11:29:42 +08:00
return (
<>
2022-03-10 14:24:13 +08:00
<div className="myselfContent xsy-menu-style" style={{ height: innerHeight - 106 }}>
<Spin spinning={spin} wrapperClassName="xsy-spin">
<div>
<Tooltip placement="top" title={'刷新流程'}>
<a
style={{ float: 'right', marginRight: '10px' }}
onClick={async () => {
spinSet(true);
setSelectedKeys([]);
menuShowSet([]);
await getData();
// await getBtn();
// history.push('/EvaRoom/Eva');
spinSet(false);
}}
>
<ReloadOutlined spin={spin} />
</a>
</Tooltip>
{
data?.length > 1 && <Tooltip placement="top" title={'查看已开启轮次所选供应商'}>
<a
style={{ float: 'right', marginRight: '10px' }}
onClick={async () => {
gysDataSet([]);//穿梭框数据源
setTargetKeys([]);//穿梭框右侧数据 keys
chooseGysSet(true);
chooseTurnSet(true);
}}
>
<CarryOutOutlined />
</a>
</Tooltip>
}
</div>
<div>
<Menu
// defaultSelectedKeys={['1SubMenu']}
openKeys={menuShow}
expandIcon={() => <DownOutlined style={{ fontSize: '10px', fontWeight: 'bolder' }} />}
mode="inline"
onOpenChange={onOpenChange}
selectedKeys={selectedKeys}
onSelect={onSelect}
className="xsy-menu-style"
style={{ height: innerHeight - 325, paddingBottom: '' }}
inlineIndent={58}
>
{data.map((item: any) => (
<SubMenu key={`${item.instTurnSort}SubMenu`} title={item.instTurnName}>
{item.nodeVOList.map((item2: any, index: any) => {
//可查看报价的专家 (唱价节点)
let singDis;
if (item2.moduleUrl === '/EvaRoom/Eva/Sing') {
singDis = item2.moduleUrl === '/EvaRoom/Eva/Sing' && role == 'ebtp-expert' && singUserId.findIndex((item: any) => item == userId) == -1;
}
if (item2.moduleUrl === '/EvaRoom/Eva/Openning') {
singDis = item2.moduleUrl === '/EvaRoom/Eva/Openning' && role == 'ebtp-expert' && singUserId.findIndex((item: any) => item == userId) == -1;
}
//修改跳转地址并加参数 轮次id 节点id 轮次号
let url = makeUrl(item2.moduleUrl, leader) + `?turnId=${item2.instTurnId}&nodeId=${item2.id}&turnSort=${item2.instTurnSort}`;
//报价评审 只有评审分工分到的专家能点
let offerDis = item2.moduleUrl === '/EvaRoom/Eva/BidOffer' && userId != offerUserId;
//是否跳过节点 0-不跳过 1-跳过节点
let skipStatus = item2.skipStatus == 1;
2022-03-10 14:24:13 +08:00
let disabled = item2.status == 3 ||
item2.moduleUrl == null ||
item2.moduleUrl == undefined ||
offerDis ||
singDis ||
skipStatus
2022-03-10 14:24:13 +08:00
return (
<Menu.Item
key={`${item.instTurnSort}${index}MenuItem`}
disabled={disabled}
onClick={() => {
let empty = new Promise(function (resolve, reject) {
if (makeUrl(item2.moduleUrl, leader) === window.location.pathname && !disabled) {
history.push('/EvaRoom/Eva')
}
resolve(true);
});
empty.finally(() => history.push(url));
}}
>
{item2.instNodeName}
</Menu.Item>
);
})}
</SubMenu>
))}
</Menu>
</div>
<div className="xsy-spin-div">
<div>
<Button
type="primary"
hidden={
flowFinish || btnAuthority(['ebtp-agency-project-manager', 'ebtp-purchase'])
}
onClick={() => showConfirm(btnMes, false)}
className="xsy-next-btn"
>
{btnText == '开启' ? btnText + instTurnName : btnText}
</Button>
</div>
<div>
<Button
hidden={
stop ||
flowFinish ||
btnAuthority(['ebtp-agency-project-manager', 'ebtp-purchase'])
}
className="xsy-over-btn"
onClick={() => {
overConfirm('是否要终止流程?');
}}
>
</Button>
</div>
</div>
</Spin>
2021-01-16 11:29:42 +08:00
</div>
2022-03-10 14:24:13 +08:00
{/* 选择供应商 */}
{returnGysModal()}
2021-01-16 11:29:42 +08:00
</>
2022-03-10 14:24:13 +08:00
);
};
export default Index;