确认定标结果--定标结果审批弹窗
This commit is contained in:
@ -1,12 +1,30 @@
|
|||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import { Button, Card, Collapse, Form, Input, List, message, Popover, Select, Space, Spin, Typography } from "antd";
|
import {
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
Collapse,
|
||||||
|
Form,
|
||||||
|
Input,
|
||||||
|
List,
|
||||||
|
message,
|
||||||
|
Modal,
|
||||||
|
Popover,
|
||||||
|
Select,
|
||||||
|
Space,
|
||||||
|
Spin,
|
||||||
|
Typography,
|
||||||
|
Checkbox
|
||||||
|
} from "antd";
|
||||||
import ProTable from "@ant-design/pro-table";
|
import ProTable from "@ant-design/pro-table";
|
||||||
import { getBidAssessmentResultList, getBidAssessmentResultsList, pushBidAssessmentResult, saveResult } from "./service"
|
import { getBidAssessmentResultList, getBidAssessmentResultsList, pushBidAssessmentResult, saveResult ,saveReviewResultDetail} from "./service"
|
||||||
import CurrentTable from "./components/currentTable"
|
import CurrentTable from "./components/currentTable"
|
||||||
import { getDefId, getProId, getProMethod } from "@/utils/session";
|
import { getDefId, getProId, getProMethod } from "@/utils/session";
|
||||||
import { btnAuthority } from "@/utils/authority";
|
import { btnAuthority } from "@/utils/authority";
|
||||||
import { isEmpty } from '@/utils/CommonUtils';
|
import { isEmpty } from '@/utils/CommonUtils';
|
||||||
|
|
||||||
|
const CheckboxGroup = Checkbox.Group
|
||||||
|
const defaultCheckedList: any[] = [];
|
||||||
|
const plainOptions: any[] = [];
|
||||||
|
|
||||||
const BidAssessmentResults: React.FC<{}> = (props) => {
|
const BidAssessmentResults: React.FC<{}> = (props) => {
|
||||||
const [Refresh, setRefresh] = useState<number>(0);
|
const [Refresh, setRefresh] = useState<number>(0);
|
||||||
@ -19,6 +37,14 @@ const BidAssessmentResults: React.FC<{}> = (props) => {
|
|||||||
const [name, setName] = useState<string>('');
|
const [name, setName] = useState<string>('');
|
||||||
//折叠面板
|
//折叠面板
|
||||||
const [collapseActiveKeys, setCollapseActiveKeys] = useState<any[]>(['0']);
|
const [collapseActiveKeys, setCollapseActiveKeys] = useState<any[]>(['0']);
|
||||||
|
// 用于控制定标结果审批弹窗的显示与隐藏
|
||||||
|
const [isCalibrationModalVisible, setIsCalibrationModalVisible] = useState(false);
|
||||||
|
|
||||||
|
const [indeterminate, setIndeterminate] = useState<boolean>(false); // 复选框全选
|
||||||
|
const [checkAll, setCheckAll] = useState<boolean>(false); // 复选框全选
|
||||||
|
const [checkedList, setCheckedList] = useState(defaultCheckedList); // 全选选中数组
|
||||||
|
const [sectionsVal, setSectionsVal] = useState<any>([]); // 选中数组id
|
||||||
|
const [plainList, setPlainList] = useState(plainOptions); // 选择标段
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
@ -77,13 +103,64 @@ const BidAssessmentResults: React.FC<{}> = (props) => {
|
|||||||
/*projectType :2 评标 1 资审*/
|
/*projectType :2 评标 1 资审*/
|
||||||
getBidAssessmentResultsList({ "projectId": proID, "roomType": "2", "sectionName": name }).then(res => {
|
getBidAssessmentResultsList({ "projectId": proID, "roomType": "2", "sectionName": name }).then(res => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
|
// 关键:把接口返回的 res.data 赋值给 ListData
|
||||||
setListData(res.data);
|
setListData(res.data);
|
||||||
|
const newPlainList = res.data.map(item => ({
|
||||||
|
sectionId: item.sectionId,
|
||||||
|
sectionName: item.sectionName
|
||||||
|
}));
|
||||||
|
setPlainList(newPlainList);
|
||||||
|
// 初始化 sectionsVal:所有标段的 ID 数组
|
||||||
|
setSectionsVal(newPlainList.map(item => item.sectionId));
|
||||||
}
|
}
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
setSpintype(false);
|
setSpintype(false);
|
||||||
})
|
})
|
||||||
}, [proID, Refresh])
|
}, [proID, Refresh])
|
||||||
|
|
||||||
|
// 重置全选相关状态
|
||||||
|
const resetCalibrationStates = () => {
|
||||||
|
setCheckedList(defaultCheckedList); // 清空已选
|
||||||
|
setCheckAll(false); // 取消全选
|
||||||
|
setIndeterminate(false); // 取消半选
|
||||||
|
};
|
||||||
|
|
||||||
|
// 定标结果审批方法,点击按钮时调用,显示弹窗
|
||||||
|
const calibrationResult = () => {
|
||||||
|
setIsCalibrationModalVisible(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 假设点击确定按钮的回调,可根据实际需求处理选中的标段逻辑,这里简单打印
|
||||||
|
const handleCalibrationModalOk = () => {
|
||||||
|
setIsCalibrationModalVisible(false);
|
||||||
|
console.log('点击了确定,可处理标段选择逻辑');
|
||||||
|
resetCalibrationStates(); // 确定后也重置(可选,看业务需求)
|
||||||
|
};
|
||||||
|
|
||||||
|
// 关闭定标结果审批弹窗的方法
|
||||||
|
const handleCalibrationModalCancel = () => {
|
||||||
|
setIsCalibrationModalVisible(false);
|
||||||
|
resetCalibrationStates(); // 关键:关闭时重置
|
||||||
|
};
|
||||||
|
|
||||||
|
// 全选事件
|
||||||
|
const onCheckAllChange = (e: any) => {
|
||||||
|
// 全选:checkedList = 所有标段 ID(sectionsVal)
|
||||||
|
// 取消全选:checkedList = []
|
||||||
|
setCheckedList(e.target.checked ? sectionsVal : []);
|
||||||
|
setIndeterminate(false);
|
||||||
|
setCheckAll(e.target.checked);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 子选项改变事件
|
||||||
|
const onChange = (checkedList: any) => {
|
||||||
|
setCheckedList(checkedList);
|
||||||
|
// 半选状态:已选数量 >0 且 < 总数量
|
||||||
|
setIndeterminate(!!checkedList.length && checkedList.length < sectionsVal.length);
|
||||||
|
// 全选状态:已选数量 === 总数量
|
||||||
|
setCheckAll(checkedList.length === sectionsVal.length);
|
||||||
|
};
|
||||||
|
|
||||||
/*推送评标结果*/
|
/*推送评标结果*/
|
||||||
const pushResult = (record: any) => {
|
const pushResult = (record: any) => {
|
||||||
setSpintype(true);
|
setSpintype(true);
|
||||||
@ -117,7 +194,7 @@ const BidAssessmentResults: React.FC<{}> = (props) => {
|
|||||||
const [expandTotalScore, setExpandTotalScore] = useState<boolean>(proDict == "procurement_mode_7" ? false : true);
|
const [expandTotalScore, setExpandTotalScore] = useState<boolean>(proDict == "procurement_mode_7" ? false : true);
|
||||||
|
|
||||||
//单一简化
|
//单一简化
|
||||||
function returnInput(name: any, name2: any, val: any, must: boolean, pattern?: boolean, hid?: boolean) {
|
function returnInput(name: any, name2: any, val: any, must: boolean, pattern?: boolean, hid?: boolean,id?: any) {
|
||||||
let rule = [
|
let rule = [
|
||||||
{ required: must },
|
{ required: must },
|
||||||
{ pattern: /^.{0,21}$/, message: '超长' }
|
{ pattern: /^.{0,21}$/, message: '超长' }
|
||||||
@ -173,6 +250,36 @@ const BidAssessmentResults: React.FC<{}> = (props) => {
|
|||||||
</span>)
|
</span>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function transformData(data) {
|
||||||
|
const result = [];
|
||||||
|
const idMap = {};
|
||||||
|
|
||||||
|
// 遍历对象的每个属性
|
||||||
|
for (const key in data) {
|
||||||
|
if (data.hasOwnProperty(key)) {
|
||||||
|
// 分割字段名,获取属性类型和ID
|
||||||
|
const [type, id] = key.split('_');
|
||||||
|
if (!idMap[id]) {
|
||||||
|
idMap[id] = { id };
|
||||||
|
result.push(idMap[id]);
|
||||||
|
}
|
||||||
|
// 处理值的类型转换
|
||||||
|
let value = data[key];
|
||||||
|
if (value === "null") {
|
||||||
|
value = null;
|
||||||
|
} else if (type === 'contractedMoney' || type === 'taxRatePrice') {
|
||||||
|
// 确保金额字段是数字类型
|
||||||
|
value = parseFloat(value) || null;
|
||||||
|
} else if (type === 'winnerBidder') {
|
||||||
|
// 将"是/否"转换为1/0
|
||||||
|
value = value === "是" ? 1 : 0;
|
||||||
|
}
|
||||||
|
idMap[id][type] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<List
|
<List
|
||||||
grid={{
|
grid={{
|
||||||
@ -339,7 +446,25 @@ const BidAssessmentResults: React.FC<{}> = (props) => {
|
|||||||
width: 80,
|
width: 80,
|
||||||
dataIndex: 'winnerBidder',
|
dataIndex: 'winnerBidder',
|
||||||
render: (_: any, record: any) => {
|
render: (_: any, record: any) => {
|
||||||
return record.winnerBidder === 1 ? '是' : record.winnerBidder === 0 ? '否' : '-'
|
// const isEditable = defId === 'negotiation_single_simple' && record.pushStatus === "0";
|
||||||
|
// if (isEditable) {
|
||||||
|
return returnSelect('winnerBidder_'+record.id, record.winnerBidder)
|
||||||
|
// return (
|
||||||
|
// <Select
|
||||||
|
// value={record.winnerBidder === 1 ? '是' : record.winnerBidder === 0 ? '否' : '-'}
|
||||||
|
// onChange={(value) => {
|
||||||
|
// // 这里需要根据你的数据更新逻辑,比如触发表格数据更新
|
||||||
|
// // 假设你有个方法 updateRecord 用于更新当前行记录
|
||||||
|
// const newWinnerBidder = value === '是' ? 1 : 0;
|
||||||
|
// // updateRecord(record.id, { winnerBidder: newWinnerBidder });
|
||||||
|
// }}
|
||||||
|
// >
|
||||||
|
// <Select.Option value="是">是</Select.Option>
|
||||||
|
// <Select.Option value="否">否</Select.Option>
|
||||||
|
// </Select>
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// return record.winnerBidder === 1 ? '是' : record.winnerBidder === 0 ? '否' : '-';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -348,19 +473,19 @@ const BidAssessmentResults: React.FC<{}> = (props) => {
|
|||||||
width: 150,
|
width: 150,
|
||||||
dataIndex: 'contractedMoney',
|
dataIndex: 'contractedMoney',
|
||||||
render: (_: any, record: any) => {
|
render: (_: any, record: any) => {
|
||||||
if (defId === 'negotiation_single_simple' && record.pushStatus == "0") {
|
// if (defId === 'negotiation_single_simple' && record.pushStatus == "0") {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{returnInput('contractedMoney', '拟签约金额', record.contractedMoney, false, true)}
|
{returnInput('contractedMoney_'+record.id, '拟签约金额', record.contractedMoney, false, true,false,record.id)}
|
||||||
{returnInput('id', '供应商id', record.id, false, false, true)}
|
{/*{returnInput('id', '供应商id', record.id, false, false, true,record.id)}*/}
|
||||||
{returnInput('resultId', '结果id', record.resultId, false, false, true)}
|
{/*{returnInput('resultId', '结果id', record.resultId, false, false, true,record.id)}*/}
|
||||||
{returnInput('companyId', '公司id', record.companyId, false, false, true)}
|
{/*{returnInput('companyId', '公司id', record.companyId, false, false, true,record.id)}*/}
|
||||||
{returnInput('companyName', '公司名称', record.companyName, false, false, true)}
|
{/*{returnInput('companyName', '公司名称', record.companyName, false, false, true,record.id)}*/}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
} else {
|
// } else {
|
||||||
return record.contractedMoney
|
// return record.contractedMoney
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -369,11 +494,11 @@ const BidAssessmentResults: React.FC<{}> = (props) => {
|
|||||||
width: 150,
|
width: 150,
|
||||||
dataIndex: 'taxRatePrice',
|
dataIndex: 'taxRatePrice',
|
||||||
render: (_: any, record: any) => {
|
render: (_: any, record: any) => {
|
||||||
if (defId === 'negotiation_single_simple' && record.pushStatus == "0") {
|
// if (defId === 'negotiation_single_simple' && record.pushStatus == "0") {
|
||||||
return returnInput('taxRatePrice', '增值税金额', record.taxRatePrice, false, true)
|
return returnInput('taxRatePrice_'+record.id, '增值税金额', record.taxRatePrice, false, true,false,record.id)
|
||||||
} else {
|
// } else {
|
||||||
return record.taxRatePrice
|
// return record.taxRatePrice
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@ -429,6 +554,18 @@ const BidAssessmentResults: React.FC<{}> = (props) => {
|
|||||||
<Button hidden={btnAuthority(['ebtp-agency-project-manager', 'ebtp-purchase'])} disabled={item1.pushStatus == "1" ? true : false} key={"1"} onClick={() => pushResult(item1)} type="primary"> 确认{name2}结果 </Button>
|
<Button hidden={btnAuthority(['ebtp-agency-project-manager', 'ebtp-purchase'])} disabled={item1.pushStatus == "1" ? true : false} key={"1"} onClick={() => pushResult(item1)} type="primary"> 确认{name2}结果 </Button>
|
||||||
}
|
}
|
||||||
<Button key={"2"} onClick={() => getResultList(item1)}>查看日志</Button>
|
<Button key={"2"} onClick={() => getResultList(item1)}>查看日志</Button>
|
||||||
|
<Button key={"3"} onClick={() => {
|
||||||
|
form.validateFields().then(res => {
|
||||||
|
let data = transformData(res);
|
||||||
|
console.log(data)
|
||||||
|
saveReviewResultDetail(data).then((res) => {
|
||||||
|
if (res.success) {
|
||||||
|
message.success('保存成功!');
|
||||||
|
setRefresh();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}}>保存</Button>
|
||||||
</>
|
</>
|
||||||
]}
|
]}
|
||||||
pagination={{
|
pagination={{
|
||||||
@ -443,12 +580,66 @@ const BidAssessmentResults: React.FC<{}> = (props) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const calibrationResultsModal = (
|
||||||
|
<Modal
|
||||||
|
title="选择标段"
|
||||||
|
visible={isCalibrationModalVisible}
|
||||||
|
width="70%"
|
||||||
|
centered
|
||||||
|
destroyOnClose={true}
|
||||||
|
bodyStyle={{
|
||||||
|
maxHeight: window.innerHeight * 0.96 - 108,
|
||||||
|
overflowY: 'auto',
|
||||||
|
paddingTop: 0
|
||||||
|
}}
|
||||||
|
onOk={handleCalibrationModalOk}
|
||||||
|
onCancel={handleCalibrationModalCancel}
|
||||||
|
>
|
||||||
|
<div style={{ padding: '16px' }}>
|
||||||
|
{/* 全选 - 单独一行 */}
|
||||||
|
<div style={{ marginBottom: '8px', display: 'flex', alignItems: 'center' }}>
|
||||||
|
<Checkbox
|
||||||
|
indeterminate={indeterminate}
|
||||||
|
onChange={onCheckAllChange}
|
||||||
|
checked={checkAll}
|
||||||
|
style={{ marginRight: '8px' }}
|
||||||
|
>
|
||||||
|
全选
|
||||||
|
</Checkbox>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 子选项 - 统一缩进 */}
|
||||||
|
<div style={{ marginLeft: '24px' }}>
|
||||||
|
<CheckboxGroup
|
||||||
|
value={checkedList}
|
||||||
|
onChange={onChange}
|
||||||
|
>
|
||||||
|
{plainList.map((item, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
style={{ display: 'flex', alignItems: 'center', marginBottom: '8px' }}
|
||||||
|
>
|
||||||
|
<Checkbox
|
||||||
|
value={item.sectionId}
|
||||||
|
style={{ marginRight: '8px' }}
|
||||||
|
>
|
||||||
|
{item.sectionName}
|
||||||
|
</Checkbox>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</CheckboxGroup>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Spin spinning={spintype}>
|
<Spin spinning={spintype}>
|
||||||
<Card bordered={false} bodyStyle={{ padding: '0px 24px' }}>
|
<Card bordered={false} bodyStyle={{ padding: '0px 24px' }}>
|
||||||
<div style={{ textAlign: 'right' }}>
|
<div style={{ textAlign: 'right' }}>
|
||||||
<Space style={{ margin: '16px 0px' }}>
|
<Space style={{ margin: '16px 0px' }}>
|
||||||
|
<Button type="primary" onClick={calibrationResult}>定标结果审批</Button>
|
||||||
<Input type="text" placeholder={`${name3}名称`} value={name} onChange={(event) => setName(event.target.value)} />
|
<Input type="text" placeholder={`${name3}名称`} value={name} onChange={(event) => setName(event.target.value)} />
|
||||||
<Button type="primary" key='c' onClick={() => {
|
<Button type="primary" key='c' onClick={() => {
|
||||||
setRefresh(Refresh + 1);
|
setRefresh(Refresh + 1);
|
||||||
@ -468,6 +659,7 @@ const BidAssessmentResults: React.FC<{}> = (props) => {
|
|||||||
</Collapse>
|
</Collapse>
|
||||||
<CurrentTable assessRoomId={assessRoomId} ChangeNoticeListVisible={currentTable}
|
<CurrentTable assessRoomId={assessRoomId} ChangeNoticeListVisible={currentTable}
|
||||||
onCancel={() => setCurrentTable(false)} />
|
onCancel={() => setCurrentTable(false)} />
|
||||||
|
{calibrationResultsModal}
|
||||||
</Card>
|
</Card>
|
||||||
</Spin>
|
</Spin>
|
||||||
</>
|
</>
|
||||||
|
@ -32,3 +32,13 @@ export async function saveResult(params?: any) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//保存 列表后三项
|
||||||
|
export async function saveReviewResultDetail(data?: any) {
|
||||||
|
return request('/api/biz-service-ebtp-rsms/v1/reviewresult/save/saveReviewResultDetail', {
|
||||||
|
method: 'POST',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user