This commit is contained in:
jlzhangyx5
2025-07-10 17:09:54 +08:00
4 changed files with 230 additions and 26 deletions

View File

@ -45,17 +45,19 @@ const SelectProvider: React.FC<SelectProviderProps> = ({ onSelect, visible = fal
const columns: ProColumns<any>[] = [
{ title: '序号', valueType: 'index', width: 50, search: false, },
{ title: '供应商名称', dataIndex: 'name', },//, ellipsis: true
{ title: '供应商分类code', dataIndex: 'kindCode', hideInTable:true,
valueEnum: { 'EBTP': { text: '招标采购中心', status: 'EBTP' }, },
{ title: '供应商分类', dataIndex: 'kindCode',
valueEnum: { 'dvs': { text: '境内企业/机构', status: 'dvs' }, 'ovs': { text: '境外企业', status: 'ovs' },'pe': { text: '个人/机构', status: 'pe' },},
},
{ title: '供应商分类', dataIndex: 'kindName',
{ title: '供应商分类', dataIndex: 'kindName',
hideInTable:true,
},//, ellipsis: true//, ellipsis: true
{ title: '品类', dataIndex: 'goodsTypeName', },
{ title: '准入时间', dataIndex: 'accessTime', },//, ellipsis: true
{ title: '准入人', dataIndex: 'accessUser', search: false, hideInTable:true,},//, ellipsis: true
{ title: '状态', dataIndex: 'agent', },//, ellipsis: true
{ title: '状态', dataIndex: 'agent',
valueEnum: { 0: { text: '未合作', status: 0 }, 1: { text: '已合作', status: 1 },2: { text: '失效', status: 2 },},
},//, ellipsis: true
{ title: 'id', dataIndex: 'id', search: false,hideInTable:true,},//, ellipsis: true
// { title: '创建时间', dataIndex: 'createDate', width: '10%', valueType: 'dateTime', search: false },

View File

@ -319,7 +319,7 @@ const [currentProviderId, setCurrentProviderId] = useState<string>('');
</div>
<div className="info-item" style={{ flex: '0 0 48%', margin: '0 1% 1rem', display: 'flex' }}>
<span className="info-label" style={{ flex: '0 0 30%', textAlign: 'right', marginRight: '2%' }}></span>
<span className="info-content" style={{ flex: '1' }}>{userData?.fullName || '-'}</span>
<span className="info-content" style={{ flex: '1' }}>{userData?.employeeNumber || '-'}</span>
</div>
<div className="info-item" style={{ flex: '0 0 48%', margin: '0 1% 1rem', display: 'flex' }}>
<span className="info-label" style={{ flex: '0 0 30%', textAlign: 'right', marginRight: '2%' }}></span>
@ -327,11 +327,11 @@ const [currentProviderId, setCurrentProviderId] = useState<string>('');
</div>
<div className="info-item" style={{ flex: '0 0 48%', margin: '0 1% 1rem', display: 'flex' }}>
<span className="info-label" style={{ flex: '0 0 30%', textAlign: 'right', marginRight: '2%' }}></span>
<span className="info-content" style={{ flex: '1' }}>{userData?.fullName || '-'}</span>
<span className="info-content" style={{ flex: '1' }}>{userData?.organizationName || '-'}</span>
</div>
<div className="info-item" style={{ flex: '0 0 48%', margin: '0 1% 1rem', display: 'flex' }}>
<span className="info-label" style={{ flex: '0 0 30%', textAlign: 'right', marginRight: '2%' }}></span>
<span className="info-content" style={{ flex: '1' }}>{userData?.fullName || '-'}</span>
<span className="info-content" style={{ flex: '1' }}>{userData?.deptName || '-'}</span>
</div>
</div>

View File

@ -1,12 +1,30 @@
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 { getBidAssessmentResultList, getBidAssessmentResultsList, pushBidAssessmentResult, saveResult } from "./service"
import { getBidAssessmentResultList, getBidAssessmentResultsList, pushBidAssessmentResult, saveResult ,saveReviewResultDetail} from "./service"
import CurrentTable from "./components/currentTable"
import { getDefId, getProId, getProMethod } from "@/utils/session";
import { btnAuthority } from "@/utils/authority";
import { isEmpty } from '@/utils/CommonUtils';
const CheckboxGroup = Checkbox.Group
const defaultCheckedList: any[] = [];
const plainOptions: any[] = [];
const BidAssessmentResults: React.FC<{}> = (props) => {
const [Refresh, setRefresh] = useState<number>(0);
@ -19,6 +37,14 @@ const BidAssessmentResults: React.FC<{}> = (props) => {
const [name, setName] = useState<string>('');
//折叠面板
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 { Option } = Select;
@ -77,13 +103,64 @@ const BidAssessmentResults: React.FC<{}> = (props) => {
/*projectType :2 评标 1 资审*/
getBidAssessmentResultsList({ "projectId": proID, "roomType": "2", "sectionName": name }).then(res => {
if (res.code == 200) {
// 关键:把接口返回的 res.data 赋值给 ListData
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(() => {
setSpintype(false);
})
}, [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 = 所有标段 IDsectionsVal
// 取消全选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) => {
setSpintype(true);
@ -117,7 +194,7 @@ const BidAssessmentResults: React.FC<{}> = (props) => {
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 = [
{ required: must },
{ pattern: /^.{0,21}$/, message: '超长' }
@ -173,6 +250,36 @@ const BidAssessmentResults: React.FC<{}> = (props) => {
</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 (
<List
grid={{
@ -339,7 +446,25 @@ const BidAssessmentResults: React.FC<{}> = (props) => {
width: 80,
dataIndex: 'winnerBidder',
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,
dataIndex: 'contractedMoney',
render: (_: any, record: any) => {
if (defId === 'negotiation_single_simple' && record.pushStatus == "0") {
// if (defId === 'negotiation_single_simple' && record.pushStatus == "0") {
return (
<>
{returnInput('contractedMoney', '拟签约金额', record.contractedMoney, false, true)}
{returnInput('id', '供应商id', record.id, false, false, true)}
{returnInput('resultId', '结果id', record.resultId, false, false, true)}
{returnInput('companyId', '公司id', record.companyId, false, false, true)}
{returnInput('companyName', '公司名称', record.companyName, false, false, true)}
{returnInput('contractedMoney_'+record.id, '拟签约金额', record.contractedMoney, false, true,false,record.id)}
{/*{returnInput('id', '供应商id', record.id, false, false, true,record.id)}*/}
{/*{returnInput('resultId', '结果id', record.resultId, false, false, true,record.id)}*/}
{/*{returnInput('companyId', '公司id', record.companyId, false, false, true,record.id)}*/}
{/*{returnInput('companyName', '公司名称', record.companyName, false, false, true,record.id)}*/}
</>
)
} else {
return record.contractedMoney
}
// } else {
// return record.contractedMoney
// }
}
},
{
@ -369,11 +494,11 @@ const BidAssessmentResults: React.FC<{}> = (props) => {
width: 150,
dataIndex: 'taxRatePrice',
render: (_: any, record: any) => {
if (defId === 'negotiation_single_simple' && record.pushStatus == "0") {
return returnInput('taxRatePrice', '增值税金额', record.taxRatePrice, false, true)
} else {
return record.taxRatePrice
}
// if (defId === 'negotiation_single_simple' && record.pushStatus == "0") {
return returnInput('taxRatePrice_'+record.id, '增值税金额', record.taxRatePrice, false, true,false,record.id)
// } else {
// 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 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={{
@ -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 (
<>
<Spin spinning={spintype}>
<Card bordered={false} bodyStyle={{ padding: '0px 24px' }}>
<div style={{ textAlign: 'right' }}>
<Space style={{ margin: '16px 0px' }}>
<Button type="primary" onClick={calibrationResult}></Button>
<Input type="text" placeholder={`${name3}名称`} value={name} onChange={(event) => setName(event.target.value)} />
<Button type="primary" key='c' onClick={() => {
setRefresh(Refresh + 1);
@ -468,6 +659,7 @@ const BidAssessmentResults: React.FC<{}> = (props) => {
</Collapse>
<CurrentTable assessRoomId={assessRoomId} ChangeNoticeListVisible={currentTable}
onCancel={() => setCurrentTable(false)} />
{calibrationResultsModal}
</Card>
</Spin>
</>

View File

@ -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
})
}