1.修改合同问题

2.项目建档
3.增加进行中的项目
This commit is contained in:
32503
2025-07-02 09:56:11 +08:00
parent 9eb6d1cd10
commit 6e1b1c8653
17 changed files with 1687 additions and 619 deletions

View File

@ -25,124 +25,70 @@ interface Province {
// 模拟省市区数据
const provinceData: Province[] = [
{
value: 'beijing',
value: '11',
label: '北京市',
cities: [
{
value: 'dongcheng',
label: '东城区',
value: '01',
label: '市辖区',
districts: [
{ value: 'chaoyangmen', label: '朝阳门街道' },
{ value: 'jianguomennei', label: '建国门内街道' },
{ value: 'donghuamen', label: '东华门街道' },
],
},
{
value: 'xicheng',
label: '西城区',
districts: [
{ value: 'xichang', label: '西长安街街道' },
{ value: 'xinjieku', label: '新街口街道' },
{ value: 'yuetan', label: '月坛街道' },
],
},
{
value: 'chaoyang',
label: '朝阳区',
districts: [
{ value: 'jianwai', label: '建外街道' },
{ value: 'chaowai', label: '朝外街道' },
{ value: 'hujialou', label: '呼家楼街道' },
],
},
],
{ value: '01', label: '东城区' },
{ value: '02', label: '西城区' },
{ value: '05', label: '朝阳区' },
]
}
]
},
{
value: 'shanghai',
value: '31',
label: '上海市',
cities: [
{
value: 'huangpu',
label: '黄浦区',
value: '10',
label: '市辖区',
districts: [
{ value: 'nanking', label: '南京东路街道' },
{ value: 'waitan', label: '外滩街道' },
{ value: 'yuyuan', label: '豫园街道' },
{ value: '02', label: '安次区' },
{ value: '03', label: '广阳区' },
{ value: '22', label: '固安县' },
],
},
{
value: 'xuhui',
label: '徐汇区',
districts: [
{ value: 'xujiahui', label: '徐家汇街道' },
{ value: 'tianlin', label: '田林街道' },
{ value: 'kangjianlou', label: '康健楼街道' },
],
},
{
value: 'changning',
label: '长宁区',
districts: [
{ value: 'huayang', label: '华阳路街道' },
{ value: 'jiangsu', label: '江苏路街道' },
{ value: 'xinhua', label: '新华路街道' },
],
},
}
],
},
{
value: 'guangdong',
value: '44',
label: '广东省',
cities: [
{
value: 'guangzhou',
value: '10',
label: '广州市',
districts: [
{ value: 'yuexiu', label: '越秀区' },
{ value: 'liwan', label: '荔湾区' },
{ value: 'haizhu', label: '海珠区' },
],
},
{
value: 'shenzhen',
label: '深圳市',
districts: [
{ value: 'futian', label: '福田区' },
{ value: 'luohu', label: '罗湖区' },
{ value: 'nanshan', label: '南山区' },
],
},
{
value: 'zhuhai',
label: '珠海市',
districts: [
{ value: 'xiangzhou', label: '香洲区' },
{ value: 'doumen', label: '斗门区' },
{ value: 'jinwan', label: '金湾区' },
{ value: '03', label: '荔湾区' },
{ value: '04', label: '越秀区' },
{ value: '05', label: '海珠区' },
],
},
],
},
{
value: 'jiangsu',
value: '32',
label: '江苏省',
cities: [
{
value: 'nanjing',
value: '01',
label: '南京市',
districts: [
{ value: 'xuanwu', label: '玄武区' },
{ value: 'qinhuai', label: '秦淮区' },
{ value: 'jianye', label: '建邺区' },
{ value: '02', label: '玄武区' },
{ value: '04', label: '秦淮区' },
{ value: '05', label: '建邺区' },
],
},
{
value: 'suzhou',
value: '05',
label: '苏州市',
districts: [
{ value: 'gusu', label: '姑苏区' },
{ value: 'wuzhong', label: '吴中区' },
{ value: 'xiangcheng', label: '相城区' },
{ value: '08', label: '姑苏区' },
{ value: '06', label: '吴中区' },
{ value: '07', label: '相城区' },
],
},
],
@ -171,7 +117,6 @@ export interface CitySelectProps {
const CitySelect: React.FC<CitySelectProps> = ({
value = {},
onChange,
form,
placeholder = {
province: '请选择省份',
city: '请选择城市',
@ -180,108 +125,59 @@ const CitySelect: React.FC<CitySelectProps> = ({
disabled = false,
size = 'middle',
}) => {
const [cities, setCities] = useState<City[]>([]);
const [districts, setDistricts] = useState<District[]>([]);
const [selectedProvince, setSelectedProvince] = useState<string | undefined>(value.province);
const [selectedCity, setSelectedCity] = useState<string | undefined>(value.city);
const [selectedDistrict, setSelectedDistrict] = useState<string | undefined>(value.district);
let cityData = provinceData?.find( item => {
return item.value === value?.province
})?.cities || [];
let districtData = cityData?.find( item => {
return item.value === value?.city
})?.districts || [];
// 处理省份选择变化
const handleProvinceChange = (provinceValue?: string) => {
setSelectedProvince(provinceValue);
setSelectedCity(undefined);
setSelectedDistrict(undefined);
setDistricts([]);
if (provinceValue) {
const province = provinceData.find(p => p.value === provinceValue);
setCities(province?.cities || []);
} else {
setCities([]);
}
// 清空城市和区域的表单字段
if (form) {
form.setFieldsValue({
city: undefined,
district: undefined,
});
}
// 触发变化回调
const newValue: CitySelectValue = {
province: provinceValue,
city: undefined,
district: undefined,
};
onChange?.(newValue);
};
// 处理城市选择变化
const handleCityChange = (cityValue?: string) => {
setSelectedCity(cityValue);
setSelectedDistrict(undefined);
if (cityValue && selectedProvince) {
const province = provinceData.find(p => p.value === selectedProvince);
const city = province?.cities.find(c => c.value === cityValue);
setDistricts(city?.districts || []);
} else {
setDistricts([]);
}
// 清空区域的表单字段
if (form) {
form.setFieldsValue({
district: undefined,
});
}
// 触发变化回调
const newValue: CitySelectValue = {
province: selectedProvince,
province: value?.province,
city: cityValue,
district: undefined,
};
// @ts-ignore
districtData = cityData.find( item => {
return item.value === cityValue
}).districts
onChange?.(newValue);
};
// 处理区域选择变化
const handleDistrictChange = (districtValue?: string) => {
setSelectedDistrict(districtValue);
// 触发变化回调
const newValue: CitySelectValue = {
province: selectedProvince,
city: selectedCity,
province: value?.province,
city: value?.city,
district: districtValue,
};
onChange?.(newValue);
};
// 监听外部值变化
useEffect(() => {
if (value.province !== selectedProvince) {
setSelectedProvince(value.province);
handleProvinceChange(value.province);
}
if (value.city !== selectedCity) {
setSelectedCity(value.city);
handleCityChange(value.city);
}
if (value.district !== selectedDistrict) {
setSelectedDistrict(value.district);
}
}, [value]);
return (
<Row gutter={8}>
<Col span={8}>
<Select
placeholder={placeholder.province}
value={selectedProvince}
value={value.province}
onChange={handleProvinceChange}
disabled={disabled}
size={size}
@ -298,14 +194,14 @@ const CitySelect: React.FC<CitySelectProps> = ({
<Col span={8}>
<Select
placeholder={placeholder.city}
value={selectedCity}
value={value.city}
onChange={handleCityChange}
disabled={disabled || !selectedProvince}
disabled={disabled || !value?.province}
size={size}
style={{ width: '100%' }}
allowClear
>
{cities.map(city => (
{cityData.map(city => (
<Option key={city.value} value={city.value}>
{city.label}
</Option>
@ -315,14 +211,14 @@ const CitySelect: React.FC<CitySelectProps> = ({
<Col span={8}>
<Select
placeholder={placeholder.district}
value={selectedDistrict}
value={value.district}
onChange={handleDistrictChange}
disabled={disabled || !selectedCity}
disabled={disabled || !value?.city}
size={size}
style={{ width: '100%' }}
allowClear
>
{districts.map(district => (
{districtData.map(district => (
<Option key={district.value} value={district.value}>
{district.label}
</Option>

View File

@ -1,6 +1,7 @@
import {
fetchDowntlist, fetchprojectRecords, fetchJuryUpList, fetchJuryDownlist, fetchSupplierUpList, fetchDisposalList, fetchParticipants,
fetchSupplierDownLeftList, fetchSupplierDownRightList, fetchtlist, fetchtlistre, fetchtPageList, fetchtShotList, fetchtClarify
fetchSupplierDownLeftList, fetchSupplierDownRightList, fetchtlist, fetchtlistre, fetchtPageList, fetchtShotList, fetchtClarify,
fetchProjectFileList
} from '../services/dashboard';
import { message } from 'antd';
import { getProId } from '@/utils/session';
@ -169,6 +170,8 @@ export default {
namespace: 'dashboard',
state: {
projectInProgressList: [],
projectInProgeressObj: {},
downlist: [],
projectlist: [],
Juryuplist: [],
@ -195,6 +198,13 @@ export default {
yield put({ type: 'save', payload: { downlist: response.data } })
}
},
*fetchProjectFileList({ payload, callback }, { call, put }) {
const response = yield call(fetchProjectFileList, payload)
console.log(123)
if (response.code == 200) {
yield put({ type: 'save', payload: { projectInProgressList: response.data.records } })
}
},
*fetchprojectRecords({ payload, callback }, { call, put }) {
const response = yield call(fetchprojectRecords, payload)
if (response.code == 200 && response.data.length > 0) {

View File

@ -1,4 +1,4 @@
import React, {useState, useRef, useCallback} from 'react';
import React, {useState, useRef} from 'react';
import { history } from 'umi';
import {Input, Button, Modal, Form, Select, message, DatePicker} from 'antd';
import { SearchOutlined , UndoOutlined} from '@ant-design/icons';
@ -43,7 +43,7 @@ const ContractList: React.FC = () => {
createDate: undefined
});
const actionRef = useRef<ActionType>();
const handleEdit = useCallback((selectedRecord: any, opt: string) => {
const handleEdit = (selectedRecord: any, opt: string) => {
getContract(selectedRecord.id).then((res) => {
history.push({
pathname: '/stepOne',
@ -53,7 +53,7 @@ const ContractList: React.FC = () => {
}
});
});
},[]);
}
// 选择合同类型
const handleChoose = () => {
@ -77,17 +77,25 @@ const ContractList: React.FC = () => {
};
// 处理搜索
const handleSearch = useCallback(() => {
if (searchParams.createDate) {
searchParams.createDate = saveDateTimeFormatter(moment(searchParams.createDate))
setSearchParams({
...searchParams
})
}
const handleSearch = () => {
actionRef.current?.reload()
}, []);
}
const goPerformance = useCallback((selectedRecord: any) => {
const goNegotiate = (selectedRecord: any) => {
getContract(selectedRecord.id).then((res) => {
if(res?.code === 200){
history.push({
pathname: '/negotiate',
state: {
contractInfo: res.data,
opt: 'edit'
}
});
}
});
}
const goPerformance = (selectedRecord: any) => {
getContract(selectedRecord.id).then((res) => {
if(res?.code === 200){
history.push({
@ -99,9 +107,9 @@ const ContractList: React.FC = () => {
});
}
});
},[])
}
const handleUpdate = useCallback((optRecord: any) => {
const handleUpdate = (optRecord: any) => {
updateContract(optRecord).then((r: any) => {
if (r?.code == 200) {
message.success('操作成功');
@ -109,9 +117,9 @@ const ContractList: React.FC = () => {
message.error('操作失败');
}
}).finally(() => actionRef.current?.reload());
},[])
}
const handleOperation = useCallback((optRecord: any, status: string) => {
const handleOperation = (optRecord: any, status: string) => {
optRecord.status = status;
const operation = status == '2' ? '中止' : status == '3' ? '终止' : '';
Modal.confirm({
@ -120,9 +128,9 @@ const ContractList: React.FC = () => {
await handleUpdate(optRecord);
}
})
},[])
}
const handleDelete = useCallback((id: string) => {
const handleDelete = (id: string) => {
Modal.confirm({
title: '确认删除该合同?',
onOk: async () => {
@ -136,7 +144,7 @@ const ContractList: React.FC = () => {
.finally(() => actionRef.current?.reload());
},
});
},[])
}
// 处理重置
const handleReset = () => {
@ -215,7 +223,13 @@ const ContractList: React.FC = () => {
<>
{optRecord.status === '0' && (<Button type="link" danger onClick={() => handleDelete(optRecord.id)}></Button>)}
{(optRecord.status === '0'|| optRecord.status === '2' )&& (<Button type="link" danger onClick={() => handleEdit(optRecord, 'edit')}></Button>)}
{optRecord.status === '1' && (<Button type="link" danger onClick={() => goPerformance(optRecord)}></Button>)}
{ optRecord.status === '1' && ((optRecord.contractType === '1' && Number(optRecord.step) >= 2 ) || (optRecord.contractType === '0' && Number(optRecord.step) >= 1))
&& (<Button type="link" danger onClick={() => goPerformance(optRecord)}></Button>)
}
{
optRecord.status === '1' && optRecord.contractType === '1' && optRecord.step === '1'
&& (<Button type="link" danger onClick={() => goNegotiate(optRecord)}></Button>)
}
{optRecord.status === '1' && (<Button type="link" danger onClick={() => handleOperation(optRecord, '2')}></Button>)}
{optRecord.status === '1' && (<Button type="link" danger onClick={() => handleOperation(optRecord, '3')}></Button>)}
{(<Button type="link" onClick={() => handleEdit(optRecord, 'detail')}></Button>)}
@ -227,6 +241,9 @@ const ContractList: React.FC = () => {
// 定义ProTable的请求函数
const request = async (params: any, sorter: any) => {
try {
if(searchParams.createDate){
searchParams.createDate = saveDateTimeFormatter(moment(searchParams.createDate))
}
// 构建请求参数,合并搜索参数
const requestParams = {
...params,
@ -330,7 +347,7 @@ const ContractList: React.FC = () => {
onChange={(e) => setSearchParams({...searchParams, biddingName: e.target.value})}
style={{ width: 200, marginRight: 16 }}
/>
<DatePicker placeholder="请选择创建时间" inputReadOnly={true} onChange={ (date, dateString) => {
<DatePicker placeholder="请选择创建时间" value={searchParams.createDate} inputReadOnly={true} onChange={ (date, dateString) => {
// @ts-ignore
setSearchParams({...searchParams, createDate: date})}
} style={{ width: 200, marginRight: 16 }}/>

View File

@ -1,8 +1,8 @@
import React, {useEffect, useState} from 'react';
import {Table, Button, Upload, message, Form} from 'antd';
import {Table, Button, Upload, message} from 'antd';
import {PlusOutlined, DeleteOutlined, SendOutlined, CheckOutlined} from '@ant-design/icons';
import moment, {Moment} from "moment";
import {createNegotiate, listNegotiate} from "@/pages/Contract/ContractService";
import {createNegotiate, listNegotiate,updateContract} from "@/pages/Contract/ContractService";
import {useLocation} from "umi";
import {saveDateTimeFormatter} from "@/utils/DateUtils";
import TextArea from "antd/es/input/TextArea";
@ -31,8 +31,10 @@ const tableData: any[] | (() => any[]) = [
// },
];
const Negotiate: React.FC = () => {
const step = '2';
const location = useLocation();
const contractInfo = location.state?.contractInfo;
const [isShow,setIsShow] = useState(false);
const opt = location.state?.opt;
let readOnly = false;
if (opt === 'detail') {
@ -128,7 +130,7 @@ const Negotiate: React.FC = () => {
message.success('文件上传成功');
}}
>
<Button type="primary"></Button>
<Button type="primary" hidden={readOnly}></Button>
</Upload>
)}
</span>
@ -145,6 +147,11 @@ const Negotiate: React.FC = () => {
key: 'createDate',
render: (value: Moment, record: any) => value ? moment(value).format('yyyy-MM-DD') : null
},
{
title: '版本号',
dataIndex: 'version',
key: 'version'
},
{
title: '备注',
dataIndex: 'note',
@ -154,7 +161,7 @@ const Negotiate: React.FC = () => {
<TextArea
placeholder="请输入备注"
value={text}
readOnly={readOnly}
disabled={readOnly}
onChange={(e) => handleNoteChange(e, record.key)}
/>
)
@ -177,7 +184,7 @@ const Negotiate: React.FC = () => {
hidden={readOnly || record.id}>
</Button>
<Button type="link" icon={<SendOutlined/>} disabled={readOnly}>
<Button type="link" icon={<SendOutlined/>} hidden={readOnly}>
</Button>
</div>
@ -199,9 +206,47 @@ const Negotiate: React.FC = () => {
setTableDataState(newTableData);
};
const saveAndCommit = async () => {
if(Number(contractInfo.step) <= Number(step)){
contractInfo.step = step;
}
contractInfo.status = '1';
await updateContract(contractInfo).then( (res: any) => {
if(res.code === 200){
message.success("当前数据更新成功").then(() => {
history.push({
pathname: '/contract',
});
}).then( () => {
})
}else {
message.error('合同信息更新失败');
}
});
}
const goPerformancePage = async () => {
// if(opt ==='detail'){
// history.push({
// pathname: '/performance',
// state: {
// contractInfo: contractInfo,
// opt: opt
// }
// });
// }else{
history.push({
pathname: '/performance',
state: {
contractInfo: contractInfo,
opt: opt
}
});
// }
}
const handleNegotiationEnd = () => {
console.log('磋商结束操作触发');
message.success('磋商结束');
setIsShow(true);
};
return (
@ -219,29 +264,57 @@ const Negotiate: React.FC = () => {
dataSource={tableDataState}/>
{/* 增加行按钮 */}
<Button type="primary" onClick={addRow} icon={<PlusOutlined/>} hidden={readOnly}>
<Button type="primary" onClick={addRow} icon={<PlusOutlined/>} hidden={readOnly || isShow}>
</Button>
<div hidden={readOnly || !isShow} style={{
borderLeft: '4px solid #0066cc',
paddingLeft: 16,
marginBottom: 16,
position: 'relative'
}}>
<span style={{ fontSize: 16, fontWeight: 'bold' }}></span>
</div>
<div hidden={!isShow} style={{ display: 'flex',marginLeft:30}}>
<Upload
name="file"
disabled={readOnly}
// listType="simple"
onChange={(info) => {
console.log('Uploaded file info:', info);
message.success('文件上传成功');
}}
>
<label style={{left: 40, marginRight: 20}}>: </label><Button type="primary"></Button>
<p></p>
<label style={{color: 'red'}}>.rar .zip .doc .docx .pdf 100MB</label>
</Upload>
</div>
{/* 居中的磋商结束按钮 */}
<div style={{textAlign: 'center', marginTop: 24}}>
<Button
type="primary"
onClick={handleNegotiationEnd}
style={{width: 160}}
hidden={readOnly}
style={{width: 120,marginRight:15}}
hidden={readOnly || isShow}
>
</Button>
<Form.Item label="">
<Button type="primary" hidden={!readOnly} onClick={() => {
history.push({
pathname: '/contract'
})
}}>
</Button>
</Form.Item>
<Button type="primary" style={{width: 120}} hidden={!isShow && readOnly} onClick={saveAndCommit}>
</Button>
<Button type="primary" style={{ marginLeft: 24 }} onClick={goPerformancePage} hidden={!isShow}>
</Button>
{/*<Form.Item label="">*/}
{/* <Button type="primary" hidden={!readOnly} onClick={() => {*/}
{/* goPerformancePage().then()*/}
{/* }}>*/}
{/* 查看履约信息*/}
{/* </Button>*/}
{/*</Form.Item>*/}
</div>
</div>
);

View File

@ -2,7 +2,6 @@ import React, {useEffect, useState} from 'react';
import {Form, Select, Input, Table, Button, message, DatePicker} from 'antd';
import {useLocation} from "umi";
const {Option} = Select;
import {
createPerformance,
updateContract,
@ -13,6 +12,7 @@ import {history} from "@@/core/history";
import {saveDateTimeFormatter} from "@/utils/DateUtils";
import moment, {Moment} from "moment";
const {Option} = Select;
const createDate = moment()
// 模拟合同履约状态选项
@ -49,10 +49,10 @@ const performanceStageDescOptions = [
];
// 模拟金额单位选项
const amountUnitOptions = [
{label: '元', value: '0'},
{label: '万元', value: '1'},
];
// const amountUnitOptions = [
// {label: '元', value: '0'},
// {label: '万元', value: '1'},
// ];
const initTableData = [
{
@ -60,14 +60,13 @@ const initTableData = [
id: '',
contractPerformanceId: '',
invoiceAmountItem: 0,
invoiceUnit: '0',
payAmountItem: 0,
payUnit: '0',
createDate: createDate
}
];
// @ts-ignore
const Performance: React.FC = () => {
const step = '3';
const [form] = Form.useForm();
const location = useLocation();
const contractInfo = location.state?.contractInfo;
@ -85,13 +84,10 @@ const Performance: React.FC = () => {
const [invoiceAmount, setInvoiceAmount] = useState(0);
// @ts-ignore
const [payAmount, setPayAmount] = useState(0);
let status0 = true;
let status1 = true;
let changeType0 = true;
let phaseDescriptionText0 = true;
// const [status0, setStatus0] = useState(true);
// const [status1, setStatus1] = useState(true);
// const [changeType0,setChangeType0] = useState(true);
const [status0, setStatus0] = useState(true);
const [status1, setStatus1] = useState(true);
const [changeType0,setChangeType0] = useState(true);
const [phaseDescriptionText0, setPhaseDescriptionText0] = useState(true);
// 计算总发票金额
const calculateTotalInvoiceAmount = (data: any) => {
return data.reduce((sum: number, row: { invoiceAmountItem: any; }) => sum + Number(row.invoiceAmountItem || 0), 0);
@ -125,13 +121,16 @@ const Performance: React.FC = () => {
changeDate: moment(contractInfo.performance.changeDate)
});
setStatus0(contractInfo.performance.status==='2'?false:true)
setStatus1(contractInfo.performance.status==='1'?false:true)
setChangeType0(contractInfo.performance.changeType=== '0'?false: true)
setPhaseDescriptionText0(contractInfo.performance.phase==='5'?false:true)
// 处理表格数据
if(contractInfo.performance.list){
const newTableData = contractInfo.performance.list.map((amountItem: any, index: number) => ({
...amountItem,
key: index + '',
invoiceUnit: '0',
payUnit: '0'
key: index + ''
}));
setTableData(newTableData);
@ -182,67 +181,67 @@ const Performance: React.FC = () => {
render: (_: any, record: any, index: number) => index + 1,
},
{
title: '发票金额(CNY)',
title: '发票金额(CNY) / 元',
dataIndex: 'invoiceAmountItem',
key: 'invoiceAmountItem',
render: (text: any, record: any) => (
<Input
readOnly={readOnly}
disabled={readOnly}
placeholder="请输入金额"
value={text}
onChange={(e) => handleInvoiceAmountItemChange(record.key, e.target.value)}
/>
),
},
// {
// title: '',
// dataIndex: 'invoiceUnit',
// key: 'invoiceUnit',
// render: (text: any, record: any) => (
// <Select
// defaultValue={'0'}
// disabled
// value={text}
// >
// {amountUnitOptions.map(({label, value}) => (
// <Option key={value} value={value}>
// {label}
// </Option>
// ))}
// </Select>
// ),
// },
{
title: '',
dataIndex: 'invoiceUnit',
key: 'invoiceUnit',
render: (text: any, record: any) => (
<Select
defaultValue={'0'}
disabled
value={text}
>
{amountUnitOptions.map(({label, value}) => (
<Option key={value} value={value}>
{label}
</Option>
))}
</Select>
),
},
{
title: '支付金额(CNY)',
title: '支付金额(CNY) / 元',
dataIndex: 'payAmountItem',
key: 'payAmountItem',
render: (text: any, record: any) => (
<Input
readOnly={readOnly}
disabled={readOnly}
placeholder="请输入金额"
value={text}
onChange={(e) => handlePayAmountItemChange(record.key, e.target.value)}
/>
),
},
{
title: '',
dataIndex: 'payUnit',
key: 'payUnit',
render: (text: any, record: any) => (
<Select
defaultValue={'0'}
disabled
value={text}
>
{amountUnitOptions.map(({label, value}) => (
<Option key={value} value={value}>
{label}
</Option>
))}
</Select>
),
},
// {
// title: '',
// dataIndex: 'payUnit',
// key: 'payUnit',
// render: (text: any, record: any) => (
// <Select
// defaultValue={'0'}
// disabled
// value={text}
// >
// {amountUnitOptions.map(({label, value}) => (
// <Option key={value} value={value}>
// {label}
// </Option>
// ))}
// </Select>
// ),
// },
{
title: '录入时间',
dataIndex: 'createDate',
@ -289,9 +288,9 @@ const Performance: React.FC = () => {
}
const statusChange = (value: any) => {
status0 = (value==='2'?false:true)
status1 = (value==='1'?false:true)
phaseDescriptionText0 = (true);
setStatus0(value==='2'?false:true)
setStatus1(value==='1'?false:true)
setPhaseDescriptionText0(true);
}
const onFinish = (values: any) => {
@ -299,11 +298,15 @@ const Performance: React.FC = () => {
values.contractId = contractInfo.id;
values.contractCode = contractInfo.contractCod;
values.contractName = contractInfo.contractName;
values.step = contractInfo.step;
const newValues = {
...values,
actualAmount: values.actualAmount?Number(values.actualAmount):0,
changeDate: saveDateTimeFormatter(values.changeDate)
}
if(Number(contractInfo.step) <= Number(step)){
newValues.step = step;
}
updatePerformance(newValues).then((res) => {
const performanceId = res.data.id;
if(performanceId){
@ -332,8 +335,10 @@ const Performance: React.FC = () => {
values.changeDate = saveDateTimeFormatter(values.changeDate)
try {
//修改合同信息状态为 进行中
contractInfo.status = 1;
updateContract(contractInfo);//更新合同状态
if(Number(contractInfo.step) <= Number(step)){
contractInfo.step = step;
}
updateContract(contractInfo).then();//更新合同状态
createPerformance(values).then((res: any) => {
const performanceId = res.data.id;
if (performanceId) {
@ -412,7 +417,7 @@ const Performance: React.FC = () => {
style={{width: '50%'}}
>
<Select placeholder="请选择" disabled={readOnly} onChange={ (value) => {
phaseDescriptionText0 = (value==='5'? false: true)
setPhaseDescriptionText0(value==='5'? false: true)
}}>
{performanceStageOptions.map(({label, value}) => (
<Option key={value} value={value}>
@ -429,7 +434,7 @@ const Performance: React.FC = () => {
style={{width: '50%'}}
>
<Select placeholder="请选择" disabled={readOnly} onChange={(value) => {
phaseDescriptionText0 = (value==='6'? false: true)
setPhaseDescriptionText0(value==='6'? false: true)
}}>
{performanceStageDescOptions.map(({label, value}) => (
<Option key={value} value={value}>
@ -447,7 +452,7 @@ const Performance: React.FC = () => {
>
<Input
placeholder="请输入合同履约阶段说明"
readOnly={readOnly}
disabled={readOnly}
/>
</Form.Item>
</div>
@ -460,7 +465,7 @@ const Performance: React.FC = () => {
style={{width: '50%', marginRight: 16}}
>
<Select placeholder="请选择" disabled={readOnly} onChange={ (value) => {
changeType0 = (value === '0'?false: true);
setChangeType0(value === '0'?false: true);
}}>
{yesOrNo.map(({label, value}) => (
<Option key={value} value={value}>
@ -472,21 +477,22 @@ const Performance: React.FC = () => {
</div>
<div style={{display: 'flex', flexWrap: 'wrap'}}>
{/* 合同实际金额 */}
<Form.Item
{!changeType0 && <Form.Item
name="amount"
label="合同金额(CNY) / 元"
hidden={changeType0}
style={{width: '50%'}}
rules={[{ pattern: /^[0-9]+(\.[0-9]{1,2})?$/, message: '请输入正确的金额格式,最多保留两位小数' },
{ validator: (_, value) => value > 0 ? Promise.resolve() : Promise.reject('金额必须大于0') }]}
rules={[
{required: false, pattern: /^[0-9]+(\.[0-9]{1,2})?$/, message: '请输入正确的金额格式,最多保留两位小数' },
{required: false,validator: (_, value) => value > 0 ? Promise.resolve() : Promise.reject('金额必须大于111110') }
]}
>
<Input
placeholder="请输入合同金额"
// value={actualAmount}
// onChange={handleActualAmountChange}
readOnly={readOnly}
disabled={readOnly}
/>
</Form.Item>
</Form.Item>}
{/* 合同是否有扣款 */}
<Form.Item
name="changeDate"
@ -503,14 +509,16 @@ const Performance: React.FC = () => {
name="actualAmount"
label="合同实际金额 / 元"
style={{width: '50%'}}
rules={[{ required: true ,pattern: /^[0-9]+(\.[0-9]{1,2})?$/, message: '请输入正确的金额格式,最多保留两位小数' },
{ validator: (_, value) => value > 0 ? Promise.resolve() : Promise.reject('金额必须大于0') }]}
rules={[
{ required: true ,pattern: /^[0-9]+(\.[0-9]{1,2})?$/, message: '请输入正确的金额格式,最多保留两位小数' },
{ validator: (_, value) => value > 0 ? Promise.resolve() : Promise.reject('金额必须大于0') }]
}
>
<Input
placeholder="请输入合同实际金额"
// value={actualAmount}
// onChange={handleActualAmountChange}
readOnly={readOnly}
disabled={readOnly}
/>
</Form.Item>
{/* 合同是否有扣款 */}
@ -542,7 +550,7 @@ const Performance: React.FC = () => {
>
<Input
value={invoiceAmount}
readOnly={totalReadOnly}
disabled={totalReadOnly}
placeholder="请输入金额"
/>
</Form.Item>
@ -555,7 +563,7 @@ const Performance: React.FC = () => {
>
<Input
value={payAmount}
readOnly={totalReadOnly}
disabled={totalReadOnly}
placeholder="请输入金额"
/>
</Form.Item>

View File

@ -14,6 +14,7 @@ const industryOptions = [
];
const StepOne: React.FC = () => {
const step = '0';
const [form] = Form.useForm();
let readOnly = false;
const location = useLocation();
@ -47,6 +48,9 @@ const StepOne: React.FC = () => {
try {
if (values.id) {
setLoading(true)
if(Number(values.step) <= Number(step)){
values.step = step;
}
updateContract(values).then((res: any) => {
if(res.code === 200){
// message.success("当前数据更新成功").then(() => {
@ -65,6 +69,7 @@ const StepOne: React.FC = () => {
}
})
} else {
values.step = step;
createContract(values).then( (res: any) => {
if(res.code === 200){
history.push({
@ -167,6 +172,7 @@ const StepOne: React.FC = () => {
</div>
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
<Form.Item hidden={true} name="id"></Form.Item>
<Form.Item hidden={true} name="step"></Form.Item>
<Form.Item
name="status"
label="合同状态"
@ -180,7 +186,7 @@ const StepOne: React.FC = () => {
rules={[{ required: true, message: '请输入项目名称' }]}
style={{ width: '50%', marginRight: 16 }}
>
<Input placeholder="请输入项目名称" readOnly={readOnly}/>
<Input placeholder="请输入项目名称" disabled={readOnly}/>
</Form.Item>
<Form.Item name="projectSelect" label="" style={{ width: '80%' }}>
<Button type="primary" hidden={readOnly}></Button>
@ -193,7 +199,7 @@ const StepOne: React.FC = () => {
rules={[{ required: true, message: '请输入标段名称' }]}
style={{ width: '50%', marginRight: 16 }}
>
<Input placeholder="请输入标段名称" readOnly={readOnly}/>
<Input placeholder="请输入标段名称" disabled={readOnly}/>
</Form.Item>
<Form.Item
name="biddingCode"
@ -201,7 +207,7 @@ const StepOne: React.FC = () => {
rules={[{ required: true, message: '请输入标段编号' }]}
style={{ width: '45%' }}
>
<Input placeholder="请输入标段编号" readOnly={readOnly} />
<Input placeholder="请输入标段编号" disabled={readOnly} />
</Form.Item>
</div>
<Form.Item name="sectionSelect" label="" style={{ width: '20%' }}>
@ -219,7 +225,7 @@ const StepOne: React.FC = () => {
rules={[{ required: true, message: '请输入采购单位' }]}
style={{ width: '50%', marginRight: 16 }}
>
<Input placeholder="请输入采购单位" readOnly={readOnly} />
<Input placeholder="请输入采购单位" disabled={readOnly} />
</Form.Item>
<Form.Item
name="purchaserCode"
@ -237,7 +243,7 @@ const StepOne: React.FC = () => {
]}
style={{ width: '50%', marginRight: 16 }}
>
<Input placeholder="请输入统一社会信用代码" readOnly={readOnly} />
<Input placeholder="请输入统一社会信用代码" disabled={readOnly} />
</Form.Item>
<Form.Item
name="industryCode"
@ -266,7 +272,7 @@ const StepOne: React.FC = () => {
rules={[{ required: true, message: '请输入供应商公司名称' }]}
style={{ width: '50%', marginRight: 16 }}
>
<Input placeholder="请输入供应商公司名称" readOnly={readOnly} />
<Input placeholder="请输入供应商公司名称" disabled={readOnly} />
</Form.Item>
<Form.Item
name="supplierCode"
@ -285,7 +291,7 @@ const StepOne: React.FC = () => {
]}
style={{ width: '45%' }}
>
<Input placeholder="请输入统一社会信用代码" readOnly={readOnly} />
<Input placeholder="请输入统一社会信用代码" disabled={readOnly} />
</Form.Item>
</div>
@ -312,7 +318,7 @@ const StepOne: React.FC = () => {
{ max: 20, message: '姓名长度不能超过20个字符' },
{ pattern: /^[\u4e00-\u9fa5a-zA-Z\s·]{2,20}$/, message: '请输入正确的姓名' }]}
>
<Input placeholder="" readOnly={readOnly}/>
<Input placeholder="" disabled={readOnly}/>
</Form.Item>
<Form.Item
name="signerContact"
@ -320,7 +326,7 @@ const StepOne: React.FC = () => {
style={{ width: '50%' }}
rules={ [{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码' }]}
>
<Input placeholder="" readOnly={readOnly} />
<Input placeholder="" disabled={readOnly} />
</Form.Item>
</div>

View File

@ -1,4 +1,4 @@
import React, {useState} from 'react';
import React, {useEffect, useState} from 'react';
import {Form, Input, Select, DatePicker, Button, message, Spin, Upload} from 'antd';
import {useLocation} from "umi";
import {updateContract} from "@/pages/Contract/ContractService";
@ -45,34 +45,35 @@ const guaranteeOptions = [
];
const StepTwo: React.FC = () => {
const step = '1';
const [loading, setLoading] = useState<boolean>(false);
// const [payType0,setPayType0] = useState(true);
let payType0 = true;
let valuationType0 = true;
// const [valuationType0,setValuationType0] = useState(true);
const [payType0,setPayType0] = useState(true);
const [valuationType0,setValuationType0] = useState(true);
const [form] = Form.useForm();
const location = useLocation();
const contractInfo = location.state?.contractInfo;
const opt = location.state?.opt;
const isShow = contractInfo? contractInfo.contractType=='0'? false: true: true;
let readOnly = false;
if(opt){
form.setFieldsValue({
...contractInfo,
endDatetime: contractInfo.endDatetime ? moment(contractInfo.endDatetime) : null,
startDatetime: contractInfo.startDatetime ? moment(contractInfo.startDatetime) : null,
signedDatetime: contractInfo.signedDatetime ? moment(contractInfo.signedDatetime) : null,
performancePlace: contractInfo.performancePlace ? contractInfo.performancePlace.split(",") : [],
mainType: contractInfo.mainType ? contractInfo.mainType.split(","): []
})
if(opt === 'detail'){
readOnly = true
}else if(opt ==='edit'){
readOnly = false
useEffect(() => {
if(opt && contractInfo){
form.setFieldsValue({
...contractInfo,
endDatetime: contractInfo.endDatetime ? moment(contractInfo.endDatetime) : null,
startDatetime: contractInfo.startDatetime ? moment(contractInfo.startDatetime) : null,
signedDatetime: contractInfo.signedDatetime ? moment(contractInfo.signedDatetime) : null,
performancePlace: contractInfo.performancePlace ? contractInfo.performancePlace.split(",") : [],
mainType: contractInfo.mainType ? contractInfo.mainType.split(","): []
})
setPayType0(form.getFieldValue("payType") === '2' ? false: true);
setValuationType0(form.getFieldValue("valuationType") === '3' ? false: true);
}
}, [opt, contractInfo, form]);
if(opt === 'detail'){
readOnly = true
}else if(opt ==='edit'){
readOnly = false
}
payType0 = (form.getFieldValue("payType") === '2' ? false: true);
valuationType0 = (form.getFieldValue("valuationType") === '3' ? false: true);
function assignMatchingProperties<T>(original: T, updates: Partial<T>): T {
const result: T = { ...original };
@ -89,21 +90,30 @@ const StepTwo: React.FC = () => {
return result;
}
const processContract = (contract: any) => {
contract.performancePlace = contract.performancePlace.join(',');
contract.mainType = contract.mainType.join(',');
contract.signedDatetime = saveDateTimeFormatter(contract.signedDatetime);
contract.startDatetime = saveDateTimeFormatter(contract.startDatetime);
contract.endDatetime = saveDateTimeFormatter(contract.endDatetime);
}
// 表单提交处理函数
const onFinish = (values: any) => {
let newContract = null;
if(opt){
newContract = values;
newContract.step = contractInfo.step;
}else{
const updatedContract = assignMatchingProperties(contractInfo, values);
newContract = updatedContract;
}
newContract.performancePlace = newContract.performancePlace.join(',');
newContract.mainType = newContract.mainType.join(',');
newContract.signedDatetime = saveDateTimeFormatter(newContract.signedDatetime);
newContract.startDatetime = saveDateTimeFormatter(newContract.startDatetime);
newContract.endDatetime = saveDateTimeFormatter(newContract.endDatetime);
newContract.status = '1';//项目进行中
processContract(newContract)
setLoading(true)
if(Number(newContract.step) <= Number(step)){
newContract.step = step;
}
updateContract(newContract).then( (res: any) => {
if(res?.code === 200){
setLoading(false)
@ -131,12 +141,11 @@ const StepTwo: React.FC = () => {
}else{
const values = await form.validateFields();
const updatedContract = assignMatchingProperties(contractInfo, values);
updatedContract.performancePlace = updatedContract.performancePlace.join(',')
updatedContract.mainType = updatedContract.mainType.join(',');
updatedContract.signedDatetime = saveDateTimeFormatter(updatedContract.signedDatetime);
updatedContract.startDatetime = saveDateTimeFormatter(updatedContract.startDatetime);
updatedContract.endDatetime = saveDateTimeFormatter(updatedContract.endDatetime);
processContract(updatedContract);
setLoading(true);
if(Number(updatedContract.step) <= Number(step)){
updatedContract.step = step;
}
updateContract(updatedContract).then( (res: any) => {
if(res.code === 200){
// message.success("当前数据更新成功").then(() => {
@ -169,12 +178,11 @@ const StepTwo: React.FC = () => {
}else{
const values = await form.validateFields();
const updatedContract = assignMatchingProperties(contractInfo, values);
updatedContract.performancePlace = updatedContract.performancePlace.join(',')
updatedContract.mainType = updatedContract.mainType.join(',');
updatedContract.signedDatetime = saveDateTimeFormatter(updatedContract.signedDatetime);
updatedContract.startDatetime = saveDateTimeFormatter(updatedContract.startDatetime);
updatedContract.endDatetime = saveDateTimeFormatter(updatedContract.endDatetime);
processContract(updatedContract);
setLoading(true);
if(Number(updatedContract.step) <= Number(step)){
updatedContract.step = step;
}
updateContract(updatedContract).then( (res: any) => {
if(res.code === 200){
message.success("当前数据更新成功").then(() => {
@ -196,10 +204,10 @@ const StepTwo: React.FC = () => {
}
const payTypeOnChange = (value: any) => {
payType0 = (value === '2' ? false: true);
setPayType0(value === '2' ? false: true);
};
const onValuationTypeChange = (value: any) => {
valuationType0 = (value === '3' ? false: true);
setValuationType0(value === '3' ? false: true);
};
return (
@ -245,7 +253,7 @@ const StepTwo: React.FC = () => {
label="框架协议编号"
style={{ width: '45%', marginRight: 16 }}
>
<Input placeholder="当合同为执行框架协议或执行统谈分签协议时,须填写对应的框架协议或统谈分签协议的编号。" readOnly={readOnly}/>
<Input placeholder="当合同为执行框架协议或执行统谈分签协议时,须填写对应的框架协议或统谈分签协议的编号。" disabled={readOnly}/>
</Form.Item>
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
{/* 合同编号和合同名称 */}
@ -255,7 +263,7 @@ const StepTwo: React.FC = () => {
rules={[{ required: true, message: '请输入合同编号' }]}
style={{ width: '45%', marginRight: 16 }}
>
<Input readOnly={readOnly}/>
<Input disabled={readOnly}/>
</Form.Item>
<Form.Item
name="contractName"
@ -263,7 +271,7 @@ const StepTwo: React.FC = () => {
rules={[{ required: true, message: '请输入合同名称' }]}
style={{ width: '45%' }}
>
<Input readOnly={readOnly}/>
<Input disabled={readOnly}/>
</Form.Item>
</div>
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
@ -314,7 +322,7 @@ const StepTwo: React.FC = () => {
hidden={valuationType0}
rules={[{ required: !valuationType0, message: '请填写备注' }]}
>
<Input placeholder="请输入备注" readOnly={readOnly}/>
<Input placeholder="请输入备注" disabled={readOnly}/>
</Form.Item>
</div>
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
@ -328,7 +336,7 @@ const StepTwo: React.FC = () => {
rules={[{ pattern: /^[0-9]+(\.[0-9]{1,2})?$/, message: '请输入正确的金额格式,最多保留两位小数' },
{ validator: (_, value) => value > 0 ? Promise.resolve() : Promise.reject('金额必须大于0') }]}
>
<Input placeholder="" readOnly={readOnly}/>
<Input placeholder="" disabled={readOnly}/>
</Form.Item>
{/*<Form.Item name="amountUnit" rules={[{ required: true, message: '请选合同金额单位' }]} initialValue={'0'} style={{ width: '5%',marginLeft:'20px'}}>*/}
{/* <Select placeholder="请选择" disabled={readOnly}>*/}
@ -363,7 +371,7 @@ const StepTwo: React.FC = () => {
hidden={payType0}
rules={[{ required: !payType0, message: '请填写备注' }]}
>
<Input placeholder="请输入备注" readOnly={readOnly}/>
<Input placeholder="请输入备注" disabled={readOnly}/>
</Form.Item>
</div>
<div style={{ display: 'flex', flexWrap: 'wrap' }}>

View File

@ -0,0 +1,22 @@
export type TableListItem = {
id: string;
name: string;
projectCode: string;
createTime: string;
bidMethodDict: string;
procurementType: string;
status: string;
version: string;
projectEntrustExpand: {
sectionList: [{
categoryList: []
}]
};
};
export type TableListPagination = {
total: number;
pageSize: number;
current: number;
};

View File

@ -11,9 +11,11 @@ import "./index.less";
import { getSessionRoleData } from '@/utils/session';
const MainPage: React.FC<any> = (props) => {
const [roleCode, setRoleCode] = useState<string>("");
const [roleCode, setRoleCode] = useState<string>(""); //TODO ling 暂时注掉
useEffect(() => {
let roleCode = getSessionRoleData().roleCode//daili 代理 gys 供应商
// let roleCode = getSessionRoleData().roleCode//daili 代理 gys 供应商
let roleCode = 'ebtp-purchase'
if (roleCode && roleCode != "") {
setRoleCode(roleCode)
}
@ -34,4 +36,4 @@ const MainPage: React.FC<any> = (props) => {
</>
)
}
export default MainPage
export default MainPage

View File

@ -1,6 +1,21 @@
import React, { PureComponent } from 'react';
import React, {PureComponent, useRef} from 'react';
import { history } from 'umi';
import { Row, Col, Tooltip, Card, List, DatePicker, Button, Statistic, Spin, Empty, message,Popconfirm, Space } from 'antd';
import {
Row,
Col,
Tooltip,
Card,
List,
DatePicker,
Button,
Statistic,
Spin,
Empty,
message,
Popconfirm,
Space,
Modal
} from 'antd';
// import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import { connect } from 'dva';
import './index.less';
@ -9,7 +24,7 @@ import { routerRedux } from 'dva/router';
import { RightOutlined } from '@ant-design/icons';
import moment from 'moment';
import { followUpAProjectManager, getRA, getSessionUserData } from '@/utils/session';
import { getDefId } from './service';
import { getDefId ,fetchProjectEntrustFileList} from './service';
import { getURLInformation } from '@/utils/CommonUtils';
import MessageDetail from '@/pages/SystemMessage/message/components/messageDetail'
import NoticeDetail from '@/pages/notice/noticeList/components/NoticeDetail'
@ -18,6 +33,10 @@ import { getQuestList } from '@/pages/SystemMessage/message/service'
import ApprovalDetail from '@/pages/SystemMessage/message/components/approvalDetail'
import {submitHiddenForm, createHiddenForm} from '@/utils/CustomerService' //智慧客服
import kefu from '@/assets/img/kefu.png' //智慧客服
import {getProjectInProgress} from '@/services/dashboard'
import {procurementMode} from "@/pages/ProjectFiles/dict";
import {agencyCompanyDispatch} from "@/pages/ProjectFiles/service";
import ProTable from '@ant-design/pro-table';
@connect(({ dashboard, loading }) => ({
...dashboard,
downlistLoading: loading.effects['dashboard/fetchDowntlist'],
@ -36,28 +55,33 @@ class manager extends PureComponent {
mainDetail: false, // 审批单消息弹窗
isModalVisible: false, //智慧客服
kefuTip: false, // 客服弹窗
projectInProgressObj: [],
}
componentDidMount() {
this.props.dispatch({
type: "dashboard/fetchDowntlist",
payload: { limit: 4 }
})
this.props.dispatch({
type: "dashboard/fetchprojectRecords",
payload: { selectDate: moment().format('YYYYMM') }
})
this.props.dispatch({
type: "dashboard/fetchtlist",
payload: { limit: 7 }
})
this.props.dispatch({
type: "dashboard/fetchtlistre",
payload: { pageNo: 1, pageSize: 7 }
})
this.props.dispatch({
type: "dashboard/fetchtClarify",
payload: { authorizestate: '0', templatetype: '4', size: 6 }
})
this.props.dispatch({
type: "dashboard/fetchDowntlist",
payload: {limit: 4}
})
this.props.dispatch({
type: "dashboard/fetchprojectRecords",
payload: {selectDate: moment().format('YYYYMM')}
})
this.props.dispatch({
type: "dashboard/fetchtlist",
payload: {limit: 7}
})
this.props.dispatch({
type: "dashboard/fetchtlistre",
payload: {pageNo: 1, pageSize: 7}
})
this.props.dispatch({
type: "dashboard/fetchtClarify",
payload: {authorizestate: '0', templatetype: '4', size: 6}
})
// this.props.dispatch({
// type: "dashboard/fetchProjectFileList",
// payload: {ownerContactId: 'xiaorui', status: 2}
// })
// NTKF_PARAM = {
// siteid: "bl_1000",                    //企业ID,为固定值
// settingid: "bl_1000_1492484340268",           //接待组ID为固定值必填
@ -69,6 +93,7 @@ class manager extends PureComponent {
// }
this.approvalDetail()
}
onChange = (date, dateString) => {
this.setState({
datevalue: moment(dateString, 'YYYY-MM'),
@ -185,10 +210,104 @@ class manager extends PureComponent {
createHiddenForm(inputList, window.location.pathname)
submitHiddenForm()
}
render() {
const { downlist, projectlist, staloading, tlist, trelist, idList, dateNum } = this.props;
const { datevalue, messId, messageDetail, detailId, noticeDetail, questData, questVisible, mainDetail, } = this.state; //智慧客服state
return (
const {downlist, projectlist, staloading, tlist, trelist, idList, dateNum,} = this.props;
// const {projectInProgressObj} = this.state;
// console.log(projectInProgressList);
const {datevalue, messId, messageDetail, detailId, noticeDetail, questData, questVisible, mainDetail,} = this.state; //智慧客服state
const columns = [
{
title: '序号',
dataIndex: 'index',
renderText: (text, record, index) => index + 1,
width: 50,
hideInSearch: true,
},
{
title: '项目名称',
dataIndex: 'projectName',
valueType: 'text',
},
{
title: '标段名称',
dataIndex: 'bidSectName',
hideInSearch: true,
},
{
title: '采购方式',
dataIndex: 'bidMethodDict',
valueType: 'select',
valueEnum: procurementMode,
},
{
title: '项目进度',
dataIndex: 'businessModule',
hideInSearch: true,
render: (_, record) => {
console.log(record.businessModule)
return businessModuleMap.get(record.businessModule + '');
}
},
{
/**
* 1 未分派 2 已分派/项目经理未同意 3 项目经理已同意
4 项目草稿 5 项目进行 9 拒绝
*/
title: '在此环节停留时间',
dataIndex: 'bidSectionStartDate',
valueType: 'select',
render: (_, record) => {
if(record.bidSectionStartDate){
const d1 = moment(record.bidSectionStartDate);
const now = moment(); // 使用moment获取当前时间
const daysDiff = Math.abs(now.diff(d1, 'days')); // 直接使用moment的diff方法
return daysDiff + '天';
}
return '-'
}
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (text, record) => (
<>
<Button type="link" onClick={() => {
}}>项目跟进
</Button>
</>
)
},
];
const businessModuleMap = new Map([
['1','建档'],
['2','资审招标'],
['3','资审投标'],
['4','资审开标'],
['5','资审评标'],
['6','资审定标'],
['7','招标'],
['8','投标'],
['9','开标'],
['10','评标'],
['11','定标'],
['12','归档'],
]);
const fetchData = async (params) => {
const { current, pageSize } = params;
const res = await getProjectInProgress({appManagerId: 'xiaorui', status: 2, pageNumber:(Number(current)-1)*pageSize,pageSize: pageSize})
const result = {
data: res.data.records,
total: res.data.total,
success: res.data.success,
};
return result;
}
// @ts-ignore
return (
<>
<a className="talk" onClick={() => {
this.setState({
@ -197,7 +316,7 @@ class manager extends PureComponent {
}}>平台操作咨询<span>8:30</span><span>|</span><span>12:30</span><span>13:00</span><span>|</span><span>17:00</span><img src={talkPng} /></a>
<div className="dashboard" style={{ height: innerHeight - 70, overflow: "hidden" }}>
<Row className="topt">
<Col span={8}><Card title="我的消息" bordered={false} className="cardtre" style={{ marginRight: "10px" }} extra={<div className="moret" onClick={() => history.push('/SystemMessage/message')}>更多<RightOutlined /></div>}>
<Col span={12}><Card title="我的消息" bordered={false} className="cardtre" style={{ marginRight: "10px" }} extra={<div className="moret" onClick={() => history.push('/SystemMessage/message')}>更多<RightOutlined /></div>}>
{trelist != [] && trelist.map((item, index) => {
return (
<div onClick={() => { item.templatetype == '3' ? this.toParticipate(item.servicecode) : this.lookDetail(item.msgId) }} className="messagetre" key={item.id}>
@ -208,37 +327,7 @@ class manager extends PureComponent {
)
})}
</Card></Col>
<Col span={8}><Card title="项目统计" bordered={false} className="cardtremanager" style={{ marginRight: "10px" }} loading={staloading} extra={<div style={{ marginTop: "-14px" }}>
<DatePicker showNow={false} picker="month" style={{ marginRight: "10px" }} value={datevalue} onChange={this.onChange} allowClear={false} /><Button type="primary" onClick={() => { this.onSearch() }}>确定</Button></div>}>
{projectlist != "" ? projectlist.map((item) => {
let routerPath = ''
if (item.title == '公开招标') {
routerPath = '/Bid/Manage'
} else if (item.title == '公开比选') {
routerPath = '/Comparison/Manage'
} else if (item.title == '谈判') {
routerPath = '/Negotiation/Manage'
} else if (item.title == '招募') {
routerPath = '/Recruit/Manage'
} else if (item.title == '询价') {
routerPath = '/Inquiry/Manage'
}
return (
<div className="boxrezt" key={item.id} style={{ height: "130px" }}>
<div className="boxtitle" title={item.title}>
{item.title}
<div className="yue"></div></div>
<div className="boxcount" onClick={() => history.push(routerPath)}><Statistic value={item.count} /></div>
<div className="boxdescription" title={item.description}>{item.description}</div>
</div>
)
}) :
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE}
description={<span style={{ color: '#BFBFBF' }}>暂无数据</span>} />
}
</Card>
</Col>
<Col span={8}><Card title="系统公告" bordered={false} className="cardtre" extra={<div className="moret" onClick={() => history.push('/notice/noticeList')}>更多<RightOutlined /></div>}>
<Col span={12}><Card title="系统通知" bordered={false} className="cardtre" extra={<div className="moret" onClick={() => history.push('/notice/noticeList')}>更多<RightOutlined /></div>}>
{tlist != [] && tlist.map((item, index) => {
return (
<div className="messagetre" onClick={() => { this.lookInfo(item.id) }} key={item.id}>
@ -251,63 +340,20 @@ class manager extends PureComponent {
</Col>
</Row>
<Row className="downt" type="flex" justify="space-around">
<Col span={8}><Card title="我的招标项目" className="cardtre" extra={<div className="moret" onClick={() => history.push('/Bid/Manage')}>更多<RightOutlined /></div>}>
<List
size="large"
bordered={false}
dataSource={downlist != [] && downlist["01"] && downlist["01"]}
renderItem={item => <List.Item className="pointer" key={item.id} onClick={() => {
this.followUpProject({
id: item.id,
bidMethodDict: item.bidMethodDict,
biddingSignDict: item.biddingSignDict,
isClientFile: item.isClientFile,
isIPassDecode: item.isIPassDecode,
isIPassFile: item.isIPassFile,
projectName: item.projectName,
openTenderForm: item.projectName
})
}} style={{ height: "25%" }}>
<div className="downround"></div><div className="downtitle" title={item.projectName}>{item.projectName}
<div className="downtime">建档时间{item.createDate}</div></div></List.Item>}
<Col span={24}>
<Card title="进行中的项目" className="cardtre">
<ProTable
rowKey="id"
pagination={{
pageSize: 5 ,
}}
options={false}
search={false}
request={fetchData}
columns={columns}
/>
</Card></Col>
<Col span={8}><Card title="我的招募项目" className="cardtre" extra={<div className="moret" onClick={() => history.push('/Recruit/Manage')}>更多<RightOutlined /></div>}>
<List
size="large"
bordered={false}
dataSource={downlist != [] && downlist["03"] && downlist["03"]}
renderItem={item => <List.Item className="pointer" key={item.id} onClick={() => {
this.followUpProject({
id: item.id,
bidMethodDict: item.bidMethodDict,
biddingSignDict: item.biddingSignDict,
isClientFile: item.isClientFile,
isIPassDecode: item.isIPassDecode,
isIPassFile: item.isIPassFile,
})
}} style={{ height: "25%" }}>
<div className="downround"></div><div className="downtitle" title={item.projectName}>{item.projectName}
<div className="downtime">建档时间{item.createDate}</div></div></List.Item>}
/></Card></Col>
<Col span={8}><Card title="我的谈判项目" className="cardtre" extra={<div className="moret" onClick={() => history.push('/Negotiation/Manage')}>更多<RightOutlined /></div>}>
<List
size="large"
bordered={false}
dataSource={downlist != [] && downlist["04"] && downlist["04"]}
renderItem={item => <List.Item className="pointer" key={item.id} onClick={() => {
this.followUpProject({
id: item.id,
bidMethodDict: item.bidMethodDict,
biddingSignDict: item.biddingSignDict,
isClientFile: item.isClientFile,
isIPassDecode: item.isIPassDecode,
isIPassFile: item.isIPassFile,
})
}} style={{ height: "25%" }}>
<div className="downround"></div><div className="downtitle" title={item.projectName}>{item.projectName}
<div className="downtime">建档时间{item.createDate}</div></div></List.Item>}
/></Card></Col>
</Card>
</Col>
</Row>
</div>
{messageDetail ? <MessageDetail messId={messId} onCancel={() => { this.closeModel(), this.props.dispatch({ type: "dashboard/fetchtlistre", payload: { pageNo: 1, pageSize: 7 } }) }} modalVisible={messageDetail} /> : null}
@ -329,13 +375,13 @@ class manager extends PureComponent {
<div style={{
//width:'200px',
position:'relative',
left:'50%',
left:'50%',
transform:'translateX(-50%)',
display: 'inline-block',
margin: '8px 4px',
padding: '4px'
}}>
<Space
align='center'
>
@ -347,7 +393,7 @@ class manager extends PureComponent {
})}>
</Button>
</Space>
</div>
</div>:null
}
@ -355,4 +401,4 @@ class manager extends PureComponent {
)
}
}
export default manager;
export default manager;

View File

@ -3,14 +3,20 @@ export type TableListItem = {
name: string;
projectCode: string;
createTime: string;
purchaseType: string;
purchaseType: string;
bidMethodDict: string;
procurementType: string;
status: string;
version: string;
projectEntrustExpand: {
sectionList: [{
categoryList: []
}]
};
};
export type TableListPagination = {
total: number;
pageSize: number;
current: number;
};
};

View File

@ -1,5 +1,5 @@
// 资金性质
const fundNatureOptions = [
const fundsNatureOptions = [
{ label: '固定资产投资', value: '1' },
{ label: '费用成本开支', value: '2' },
{ label: '通用物资固定资产投资为主', value: '3' },
@ -11,14 +11,23 @@ const fundNatureOptions = [
// 资金来源
const fundsProviderOptions = [
{ label: '国企自筹', value: '1' },
{ label: '中央投资', value: '2' },
{ label: '地方政府投资', value: '3' },
{ label: '财政资金', value: '4' },
{ label: '外贷', value: '5' },
{ label: '其他', value: '6' },
{ label: '国企自筹', value: 'funds_provider_2' },
{ label: '中央投资', value: 'funds_provider_1' },
{ label: '地方政府投资', value: 'funds_provider_3' },
{ label: '财政资金', value: 'funds_provider_4' },
{ label: '外贷', value: 'funds_provider_5' },
{ label: '其他', value: 'funds_provider_6' },
];
const fundsProviderOptionsMap = new Map([
['001','funds_provider_2'],
['002','funds_provider_1'],
['003','funds_provider_3'],
['004','funds_provider_4'],
['005','funds_provider_5'],
['006','funds_provider_6'],
])
// 预算类型
const budgetTypeOptions = [
{ label: '标段预算', value: '1' },
@ -49,37 +58,55 @@ const currencyCodeOptions = [
{ label: 'USD', value: 'USD' },
];
const currencyCodeMap = new Map([
['CNY','CNY'],
['EUR','EUR'],
['USD','USD']
])
// 招标类型
const openTenderFormEnum = {
1: '依法必招',
2: '自愿招标',
"001": '依法必招',
"002": '自愿招标',
};
const openTenderFormMap = new Map([
["open_tender_form_1",openTenderFormEnum["001"]],
["open_tender_form_2",openTenderFormEnum["002"]],
]);
// 采购方式
const purchaseTypeEnum = {
1: '公开招标',
2: '邀请招标',
const procurementMode = {
"procurement_mode_1": '公开招标',
"procurement_mode_2": '邀请招标',
};
// 资审方式
const reviewMethodEnum = {
1: '后审',
2: '资审',
const suppQualifyEnum = {
"001": '后审',
"002": '资审',
};
// 资审方式
const suppQualifyEnumContent = {
1: '资审全流程',
2: '资审短流程',
};
// 组织形式
const organizationFormEnum = {
1: '自主招标',
2: '委托代理',
'organization_1': '委托代理',
'organization_2': '自主招标',
};
// 招标代理机构
const tenderAgencyEnum = {
1: '广州中远海运建设实业有限公司',
123456: '广州中远海运建设实业有限公司',
};
// 报价方式
const bidMethodEnum = {
const quotationMethodDictEnum = {
1: '总价',
2: '单价',
3: '优惠率',
@ -87,20 +114,20 @@ const bidMethodEnum = {
};
// 评价方法
const evaluationMethodEnum = {
const evalMethodDictEnum = {
1: '最低价法',
2: '综合评估法',
3: '合理低价法',
};
// 资格审查方法
const reviewWayEnum = {
const ptcpModeEnum = {
1: '合格制',
2: '有限数量制',
};
// 流程类型
const processEnum = {
const chooseProcessEnum = {
1: '第一轮初审详审,固定流程',
};
@ -113,25 +140,31 @@ const subjectTypeOptions = [
// 标的类别2
const subjectType2Options = [
{ label: '土地、建筑物及构筑物', value: '1' },
{ label: '图书和档案', value: '1' },
{ label: '建筑建材', value: '2' },
{ label: '批发和零售服务', value: '3' },
];
export {
fundNatureOptions,
fundsNatureOptions,
fundsProviderOptions,
budgetTypeOptions,
regionDictTypeOptions,
regionOutsideOptions,
currencyCodeOptions,
purchaseTypeEnum,
procurementMode,
openTenderFormEnum,
reviewMethodEnum,
suppQualifyEnum,
suppQualifyEnumContent,
organizationFormEnum,
tenderAgencyEnum,
bidMethodEnum,
evaluationMethodEnum,
reviewWayEnum,
processEnum,
quotationMethodDictEnum,
evalMethodDictEnum,
ptcpModeEnum,
chooseProcessEnum,
subjectTypeOptions,
subjectType2Options,
currencyCodeMap,
fundsProviderOptionsMap,
openTenderFormMap
};

View File

@ -0,0 +1,227 @@
import {Button, message, Modal} from 'antd';
import React, { useRef } from 'react';
import { history } 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';
import { fetchProjectEntrustFileList, agencyCompanyDispatch} from './service';
import type { TableListItem, TableListPagination } from './data';
import { procurementMode } from './dict';
const ProjectFiles: React.FC = () => {
const actionRef = useRef<ActionType>();
const columns: ProColumns<TableListItem>[] = [
{
title: '序号',
dataIndex: 'index',
renderText: (text, record, index) => index + 1,
width: 50,
hideInSearch: true,
},
{
title: '委托方',
dataIndex: 'entrustDepartmentName',
valueType: 'text',
},
{
title: '项目名称',
dataIndex: 'projectName',
valueType: 'text',
},
{
title: '项目编号',
dataIndex: 'projectNumber',
hideInSearch: true,
},
{
title: '接收时间',
dataIndex: 'createDate',
hideInSearch: true,
},
{
title: '采购方式',
dataIndex: 'procurementMode',
valueType: 'select',
valueEnum: procurementMode,
},
{
title: '采购类型',
dataIndex: 'procurement_type',
hideInSearch: true,
render:(_, record) => {
const sectionList = record?.projectEntrustExpand?.sectionList;
const categoryArr: any[] = [];
for (const i in sectionList) {
const section = sectionList[i];
// @ts-ignore
const categoryList = section?.categoryList;
categoryList.forEach((item: any) => {
categoryArr.push(item['category']);
})
}
return categoryArr.join(',');
}
},
{
title: '状态',
dataIndex: 'status',
valueType: 'select',
render: (_, record) => {
const status = record.status;
if(Number(status) === 1){
return "未分派"
}else if(Number(status) === 2) {
return "已分派"
}else if(Number(status) === 3){
return "项目经理已同意"
}else if(Number(status) === 4){
return "草稿"
}else if(Number(status) === 5){
return "进行中"
}else if(Number(status) === 9){
return "拒绝"
}
return record.status;
}
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (text: any, record: any) => (
<>
{(
<Button type="link" onClick={() =>
history.push({
pathname: '/ProjectFiles/file',
state: {
record: record,
opt: 'view',
myRoleCode: 'ebtp-agency-admin'
}
})
}>
</Button>
)}
{(record.status=== 4) &&(
<Button type="link" onClick={() =>
history.push({
pathname: '/ProjectFiles/file',
state: {
record: record,
opt: 'edit'
}
})
}>
</Button>
)}
{(record.status=== 1) && (
<Button type="link" onClick={() => {
history.push({
pathname: '/ProjectFiles/file',
state: {
record: record,
opt: 'assign',
myRoleCode: 'ebtp-agency-admin'
}
})
}
}>
</Button>
)}
{(record.status=== 1) && (
<Button type="link" onClick={() => {
const params = {
id: record.id,
remarks: '测试拒绝'
}
Modal.confirm({
title: '确认拒绝该项目?',
onOk: async () => {
await agencyCompanyDispatch(params).then((r: any) => {
if (r?.code == 200) {
message.success('操作成功');
} else {
message.error('操作失败');
}
})
.finally(() => actionRef.current?.reload());
},
});
}
}>
</Button>
)}
</>
)
// render: (_, record) => (
// <>
// {(
// <Button onClick={() => {
//
// }}
// >查看
// </Button>
// )},
// {
// (record.status && Number(record.status) === 0) && (<Button type="link" onClick={() => { }}
// >
// 版本升级
// </Button>)}
// </>
// )
},
];
const request = async (params: any, sorter: any) => {
const requestParams = {
// ...params,
// ...searchParams,
purchasingManager: 'xiaorui',
status: 2,
organization: 'organization_1',
basePageRequest: {
pageNo: params.current || 1,
pageSize: params.pageSize || 10
},
};
const result = await fetchProjectEntrustFileList(requestParams);
return {
data: result.data.records,
total: result.data.total,
success: true,
};
}
return (
<div className="project-file-container" style={{ backgroundColor: '#f8f8f8' }}>
<PageContainer title="委托管理">
<ProTable<TableListItem, TableListPagination>
actionRef={actionRef}
rowKey="id"
search={{
labelWidth: 120,
}}
toolBarRender={() => [
<Button
type="primary"
key="primary"
onClick={() => {
history.push('/ProjectFiles/file?action=create');
}}
>
</Button>,
]}
options={{ density: false, reload: false, setting: false, fullScreen: false }}
request={request}
columns={columns}
/>
</PageContainer>
</div>
);
};
export default ProjectFiles;

View File

@ -1,11 +1,9 @@
import { CloseCircleOutlined, MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
import { Button, Card, Col, Form, Popover, Row, message, Divider, Select, Input, Upload } from 'antd';
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 'umi';
import type { Location } from 'umi';
import type { FC } from 'react';
import React, { useState, Fragment, useRef } from 'react';
import React, {useState, Fragment, useRef} from 'react';
import ProForm, {
ProFormSelect,
ProFormText,
@ -15,51 +13,60 @@ import ProForm, {
ProFormUploadButton,
} from '@ant-design/pro-form';
import { PageContainer, FooterToolbar } from '@ant-design/pro-layout';
import { submitForm } from './service';
import {
dispatch, initProjectEntrustForCosco,
updateProjectEntrust
} from './service';
import styles from './style.less';
import {
fundNatureOptions,
fundsNatureOptions,
fundsProviderOptions,
budgetTypeOptions,
regionDictTypeOptions,
regionOutsideOptions,
currencyCodeOptions,
purchaseTypeEnum,
procurementMode,
openTenderFormEnum,
reviewMethodEnum,
suppQualifyEnum,
organizationFormEnum,
tenderAgencyEnum,
bidMethodEnum,
evaluationMethodEnum,
reviewWayEnum,
processEnum,
quotationMethodDictEnum,
evalMethodDictEnum,
ptcpModeEnum,
chooseProcessEnum,
subjectTypeOptions,
subjectType2Options,
currencyCodeMap,
fundsProviderOptionsMap,
suppQualifyEnumContent,
openTenderFormMap
} from './dict';
import CitySelect from '@/components/CitySelect';
import {useEffect} from "react";
type InternalNamePath = (string | number)[];
const fieldLabels = {
projectName: '项目名称',
ProjectBizNo: '项目编号',
tendereeOrgId: '项目归属单位', //
tendereeId: '项目归属部门', //
appManagerId: '项目负责人',
appManagerTel: '联系电话',
fundNature: '资金性质', //
fundsProviderDict: '资金来源',
projectNumber: '项目编号',
entrustOrgName: '项目归属单位', //
entrustDepartmentName: '项目归属部门', //
purchasingManagerName: '项目负责人', //
purchasingManagerPhone: '联系电话', //
fundsNature: '资金性质', //
sourcesFunds: '资金来源',
budgetType: '预算类型', //
regionDictType: '项目所在行政区域类型', //?
regionDict: '项目所在行政区域', //?
budgetAmount: '项目预算',
currencyCode: '币种',
openTenderForm: '招标类型',
bidMethodDict: '采购方式',
reviewMethod: '资审方式', //
bidOrgDict: '组织形式', //
tenderAgencyId: '招标代理机构', //
procurementMode: '采购方式',
suppQualify: '资审方式', //
suppQualifyContent: '资审方式', //
organization: '组织形式', //
agencyCompany: '招标代理机构', //
};
@ -108,12 +115,156 @@ const normFile = (e: any) => {
return e?.fileList;
};
const ProjectFileCreate: FC<Record<string, any>> = () => {
const { query }: Location = useLocation();
const readOnly = query?.action === 'view';
const id = query?.id; // 文件 id
const agencyUserOption = [
{ label: '萧睿', value: 'xiaorui' },
{ label: '李明', value: 'liming' },
{ label: '张三', value: 'zhangsan' }
];
const map = new Map([
['xiaorui','13000000000'],
['liming','15066666666'],
['zhangsan','18088888888'],
])
//模拟当前登录用户信息
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 getAgencyManagerMock = () => {
return {
organizationId: '01',
deptId: '0101',
userId: '010101',
fullName: '代理机构管理员',
mobilePhone: '13888888888'
}
}
const ProjectFileCreate: React.FC<Record<string, any>> = () => {
const [agencyCompanyShow, setagencyCompanyShow] = useState(false);
const [suppQualifyContentShow,setSuppQualifyContentShow] = useState(false);
const [suppQualifyDisabled,setSuppQualifyDisabled] = useState(false);
const formRef = useRef<FormInstance>();
const [form] = Form.useForm();
const location = useLocation();
const recordInfo = location?.state?.record;
const myRoleCode = location?.state?.myRoleCode;
const opt = location?.state?.opt;
const isAgencyAdmin = myRoleCode === 'ebtp-agency-admin' || false;//是否是代理机构管理员
const isDrafts = recordInfo?.status === 4;//ProjectEntrust表中 status 4 代表 草稿
const isEntrustProject = recordInfo?.organization === 'organization_1';
// 查看或者分派的时候只读
const isView = opt === 'view';
const isEdit = opt === 'edit';
const isUpgrade = opt === 'upgrade';//是否是 版本升级
const isAssignOpt = opt ==='assign';//分派
const readOnly = (isView || isAssignOpt);
// 编辑或者代理管理员分派的时候显示
const isAssign = isAssignOpt && isAgencyAdmin;
// const id = query?.id; // 文件 id
useEffect(() => {
if(opt && recordInfo){
// getProjectOne(recordInfo).then((res) => {
const bidSections = recordInfo?.projectEntrustExpand?.sectionList || recordInfo?.sectionList;
const regionDictType = recordInfo.regionDictType;
const regionDictId = recordInfo.regionDictId;
for (const i in bidSections) {
const bidSection = bidSections[i];
bidSection.bidSectCode = Number(i) + 1;
const categoryList = bidSection.categoryList;
const bidSectionCategory = [];
for (const j in categoryList) {
const categoryItem = categoryList[j];
const obj = {
type: [categoryItem.category, categoryItem.subCategory],
percent: categoryItem.percent
}
bidSectionCategory.push(obj)
}
bidSection.bidSectionCategory = bidSectionCategory;
}
recordInfo.bidSection = bidSections;
let regionDict: any = null;
if (regionDictType === '1') {
const region = recordInfo.regionDictId;
const everyRegionLen = 2;
const times = region.length / everyRegionLen;
const regionDictIdArr = [];
for (let i = 0; i < times; i++) {
regionDictIdArr.push(region.substring((i * everyRegionLen), (i * everyRegionLen) + everyRegionLen));
}
regionDict = {
province: regionDictIdArr[0],
city: regionDictIdArr[1],
district: regionDictIdArr[2]
}
} else {
regionDict = regionDictId
}
if(recordInfo.bidOrgDict === 'organization_2'){
if(recordInfo.openTenderForm === 'open_tender_form_1'){
recordInfo.openTenderForm = '001'
}else if(recordInfo.openTenderForm === 'open_tender_form_2'){
recordInfo.openTenderForm = '002'
}
recordInfo.openTenderForm = openTenderFormMap.get(recordInfo.openTenderForm);
//委托代理项目表中 跟 项目建档 表字段数据统一
recordInfo.procurementMode = recordInfo.bidMethodDict ;
recordInfo.organization = recordInfo.bidOrgDict ;
recordInfo.agencyCompany = recordInfo.tenderAgencyId ;
recordInfo.projectNumber = recordInfo.ebpProjectNumber ;
recordInfo.sourcesFunds = recordInfo.fundsProviderDict;
recordInfo.remarks = recordInfo.remark ;
recordInfo.fundsProviderDict = fundsProviderOptionsMap.get(recordInfo.fundsProviderDict);
}
formRef?.current?.setFieldsValue({
...recordInfo,
regionDict: regionDict
})
setagencyCompanyShow(recordInfo.organization === 'organization_1' ? true : false);
setSuppQualifyContentShow(recordInfo.suppQualify === '002' ? true : false);
// })
}
}, [formRef, recordInfo, opt])
const [error, setError] = useState<ErrorField[]>([]);
const getErrorInfo = (errors: ErrorField[]) => {
const errorCount = errors.filter((item) => item.errors.length > 0).length;
@ -160,12 +311,96 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
);
};
const addLoginUserInfo = (values: Record<string, any>) => {
//自主招标
if (values?.organization === 'organization_2') {
//自主招标 项目经理就是 当前登陆人
values.projectManager = getUserMock().userId;
values.projectManagerName = getUserMock().fullName;
values.projectManagerPhone = getUserMock().mobilePhone;
} else if(values?.organization === 'organization_1') {
//代理招标
//委托代理 代理机构管理员设置 相关信息
//TODO ling 此处应该通过agencyCompany 关联查询出 对应的机构的管理员 暂时模拟
values.agencyProjectManagerId = getAgencyManagerMock().userId;
values.agencyProjectManagerName = getAgencyManagerMock().fullName;
values.agencyProjectManagerPhone = getAgencyManagerMock().mobilePhone;
}
values.purchasingManager = getUserMock().userId;//采购人
values.entrustDepartment = getUserMock().organizationId;
values.entrustDepartment = getUserMock().deptId;
return values;
}
const onFinish = async (values: Record<string, any>) => {
setError([]);
addLoginUserInfo(values);
if(isUpgrade){
//版本升级 把业务员相关信息置空
values.projectManager = '';
values.projectManagerName = '';
values.projectManagerPhone = '';
}
values.currencyName = currencyCodeMap.get(values.currencyCode);//币种编号对应的币种名称
//构建 项目所在行政区域 省,市,区
if(values.regionDict){
if(values.regionDictType === '1'){
const province = values?.regionDict.province
const city = values?.regionDict.city
const district = values?.regionDict.district
values.regionDictId = province + city + district;
values.province = '00' + province;
}else {
values.regionDictId = values.regionDict;
}
}
try {
console.log(values);
await submitForm(values);
message.success('提交成功');
const sectionList = values?.bidSection;
for(const j in sectionList){
const section = sectionList[j];
section.currencyCode = values.currencyCode;
section.currencyName = values.currencyName;
const categories = section.bidSectionCategory;
const categoryList: any = [];
for(const i in categories){
const category = categories[i];
const categoryListItem = {
category: category.type[0],
subCategory: category.type[1],
percent: category.percent
}
categoryList.push(categoryListItem);
}
section.categoryList = categoryList;
}
delete values.bidSection;
delete values.regionDict;
values.projectEntrustExpand = {
sectionList: sectionList
}
if(isEdit || isUpgrade){
await updateProjectEntrust(values).then( (res: any) => {
if(res.code === 200){
message.success('保存成功').then( () => {
history.push(`/ProjectFiles`);
});
}else{
message.error('更新失败!');
}
})
}else{
await initProjectEntrustForCosco(values).then( (res: any) => {
if(res.code === 200){
message.success('提交成功').then( () => {
history.push(`/ProjectFiles`);
});
}else{
message.error('建档失败!');
}
});
}
} catch {
// console.log
}
@ -175,31 +410,142 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
setError(errorInfo.errorFields);
};
//保存数据 (新增 / 修改) 项目建档
const saveData = async (values: Record<string, any>) => {
if(values.organization === 'organization_2'){ //自主招标
values.status = 5;
} else if (values.organization === 'organization_1'){//委托代理
values.status = 1;
}
//是否是 版本升级
if(isUpgrade){
values.status = 1;
values.versionNo = Number(values.versionNo) + 1;
}
await onFinish(values);
}
//暂存数据
const tempStoreData = async (values: Record<string, any>) => {
values.status = 4;
await onFinish(values);
}
return (
<div className={styles.createProjectFile} style={{ backgroundColor: '#f8f8f8' }}>
<ProForm
layout="horizontal"
requiredMark
form={form}
formRef={formRef}
onValuesChange={(changedValues, allValues) => {
if (changedValues.projectManager !== undefined) {
form.setFieldsValue({ projectManagerPhone: map.get(changedValues.projectManager) });
}
if(changedValues.procurementMode === 'procurement_mode_2'){
form.setFieldsValue({suppQualify:'001'});
setSuppQualifyContentShow(false)
setSuppQualifyDisabled(true);
}else{
setSuppQualifyDisabled(false);
}
}}
submitter={{
searchConfig: {
submitText: '建档完成',
},
render: (props, dom) => {
if (readOnly) {
if (readOnly && !isAssign) {
return (
<FooterToolbar className={styles.footerToolbar}>
<Button key="cancel" onClick={() => {
history.replace('/ProjectFiles');
if(recordInfo.bidOrgDict === '002' || recordInfo.organization == 'organization_1'){
history.goBack();
}else{
history.replace('/ProjectFiles');
}
}}>
</Button>
</FooterToolbar>
);
}
if(isAssign){
return (
<FooterToolbar className={styles.footerToolbar}>
<Button type="primary" danger onClick={() => {
const values = props?.form?.getFieldsValue() || {};
values.currencyName = currencyCodeMap.get(values.currencyCode);
const sectionList = values?.bidSection;
for(const j in sectionList){
const section = sectionList[j];
section.currencyCode = values.currencyCode;
section.currencyName = values.currencyName;
const categories = section.bidSectionCategory;
const categoryList: any = [];
for(const i in categories){
const category = categories[i];
const categoryListItem = {
category: category.type[0],
subCategory: category.type[1],
percent: category.percent
}
categoryList.push(categoryListItem);
}
section.categoryList = categoryList;
}
delete values.bidSection;
delete values.regionDict;
values.projectEntrustExpand = {
sectionList: sectionList
}
const {id = '',projectManager = '',projectManagerName = '',projectManagerPhone = ''} = {...values};
const params = {
id: id,
projectManager: projectManager,
projectManagerName: projectManagerName,
projectManagerPhone: projectManagerPhone,
...values
}
Modal.confirm({
title: '确认分派该项目?',
onOk: async () => {
await dispatch(params).then((r: any) => {
if (r?.code == 200) {
message.success('操作成功').then(() => {
if(recordInfo.bidOrgDict === '002'|| recordInfo.organization == 'organization_1'){
history.goBack();
}else{
history.replace('/ProjectFiles');
}
});
} else {
message.error('操作失败');
}
})
},
});
}}>
</Button>
<Button key="cancel" onClick={() => {
if(recordInfo.bidOrgDict === '002' || recordInfo.organization =='organization_1'){
history.goBack();
}else{
history.replace('/ProjectFiles');
}
}}>
</Button>
</FooterToolbar>
);
}
const _dom = dom.filter((item: JSX.Element) => item.key !== 'rest').concat([
<Button key="stash" type="primary" onClick={() => {
console.log('暂存');
const values = props?.form?.getFieldsValue() || {};
tempStoreData(values).then(r => {})
}}>
</Button>
@ -224,25 +570,58 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
budgetAmount: 0,
currencyCode: 'CNY',
bidSection: [{
bidSectionIndex: 1,
bidSectionName: '',
bidSectionNo: '',
bidSectionBudget: 0,
bidSectCode: 1,
bidSectName: '',
sectionNumber: '',
bidSectContractPrice: 0,
bidMethod: '',
bidSectionCategory: [{
id: null,
type: [],
percent: 0,
}],
}],
purchasingManager: getUserMock().userId,
purchasingManagerName: getUserMock().fullName,
purchasingManagerPhone: getUserMock().mobilePhone,
entrustOrgName: getUserMock().organizationName,
entrustDepartmentName: getUserMock().deptName
}}
onFinish={onFinish}
onFinish={saveData}
onFinishFailed={onFinishFailed}
labelCol={{ span: 5 }}
wrapperCol={{ span: 19 }}
>
<PageContainer title="新建项目" style={{ paddingBottom: 50 }}>
{(isAssign || (isEntrustProject && isDrafts) || (isView && isEntrustProject)) && (<Card title="委托信息" className={styles.card} bordered={false}>
<Row gutter={16}>
<Col span={12}>
<ProFormSelect
label={"业务员"}
name="projectManager"
rules={[{ required: isAssign, message: '请选择业务员' }]}
options={agencyUserOption}
fieldProps={{
disabled: (readOnly || isEdit) && !isAssign,
}}
/>
</Col>
<Col span={12}>
<ProFormText
label={"联系方式"}
name="projectManagerPhone"
placeholder="请输入"
fieldProps = {
{disabled: true}
}
/>
</Col>
</Row>
</Card>)}
<Card title="招标项目概况" className={styles.card} bordered={false}>
<Row gutter={16}>
<Form.Item hidden={true} name={"id"}></Form.Item>
<Form.Item hidden={true} name={"versionNo"}></Form.Item>
<Col span={12}>
<ProFormText
label={fieldLabels.projectName}
@ -256,8 +635,8 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
</Col>
<Col span={12}>
<ProFormText
label={fieldLabels.ProjectBizNo}
name="ProjectBizNo"
label={fieldLabels.projectNumber}
name="projectNumber"
rules={[{ required: true, message: '请输入项目编号' }]}
placeholder="请输入"
fieldProps={{
@ -269,8 +648,8 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
<Row gutter={16}>
<Col span={12}>
<ProFormText
label={fieldLabels.tendereeOrgId}
name="tendereeOrgId"
label={fieldLabels.entrustOrgName}
name="entrustOrgName"
rules={[{ required: true, message: '请输入项目归属单位' }]}
fieldProps={{
disabled: true,
@ -280,8 +659,8 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
</Col>
<Col span={12}>
<ProFormText
label={fieldLabels.tendereeId}
name="tendereeId"
label={fieldLabels.entrustDepartmentName}
name="entrustDepartmentName"
rules={[{ required: true, message: '请输入项目归属部门' }]}
fieldProps={{
disabled: true,
@ -293,8 +672,8 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
<Row gutter={16}>
<Col span={12}>
<ProFormText
label={fieldLabels.appManagerId}
name="appManagerId"
label={fieldLabels.purchasingManagerName}
name="purchasingManagerName"
rules={[{ required: true, message: '请输入项目负责人' }]}
placeholder="请输入"
fieldProps={{
@ -304,8 +683,8 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
</Col>
<Col span={12}>
<ProFormText
label={fieldLabels.appManagerTel}
name="appManagerTel"
label={fieldLabels.purchasingManagerPhone}
name="purchasingManagerPhone"
rules={[{ required: true, message: '请输入联系电话' }]}
fieldProps={{
disabled: readOnly,
@ -316,10 +695,10 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
<Row gutter={16}>
<Col span={12}>
<ProFormSelect
label={fieldLabels.fundNature}
name="fundNature"
label={fieldLabels.fundsNature}
name="fundsNature"
rules={[{ required: true, message: '请选择资金性质' }]}
options={fundNatureOptions}
options={fundsNatureOptions}
fieldProps={{
disabled: readOnly,
}}
@ -327,8 +706,8 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
</Col>
<Col span={12}>
<ProFormSelect
label={fieldLabels.fundsProviderDict}
name="fundsProviderDict"
label={fieldLabels.sourcesFunds}
name="sourcesFunds"
rules={[{ required: true, message: '请选择资金来源' }]}
options={fundsProviderOptions}
fieldProps={{
@ -372,7 +751,7 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
{({ bidSection }) => {
// 计算所有标段预算之和
const total = Array.isArray(bidSection)
? bidSection.reduce((sum, item) => sum + (parseFloat(item?.bidSectionBudget) || 0), 0)
? bidSection.reduce((sum, item) => sum + (parseFloat(item?.bidSectContractPrice) || 0), 0)
: 0;
return (
<ProFormDigit
@ -470,49 +849,65 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
<Row gutter={16}>
<Col span={12}>
<ProFormSelect
label={fieldLabels.bidMethodDict}
name="bidMethodDict"
label={fieldLabels.procurementMode}
name="procurementMode"
rules={[{ required: true, message: '请选择采购方式' }]}
valueEnum={purchaseTypeEnum}
valueEnum={procurementMode}
fieldProps={{
disabled: readOnly,
}}
/>
</Col>
<Col span={12}>
<Col span={8}>
<ProFormSelect
label={fieldLabels.reviewMethod}
name="reviewMethod"
label={fieldLabels.suppQualify}
name="suppQualify"
rules={[{ required: true, message: '请选择资审方式' }]}
valueEnum={reviewMethodEnum}
valueEnum={suppQualifyEnum}
fieldProps={{
disabled: readOnly || suppQualifyDisabled,
onChange: (value) => {
setSuppQualifyContentShow(value === '002' ? true : false)
}
}}
/>
</Col>
<Col span={4}>
{suppQualifyContentShow && (<ProFormSelect
name="suppQualifyContent"
valueEnum={suppQualifyEnumContent}
rules={[{ required: true, message: '请选择资审方式具体形式' }]}
fieldProps={{
disabled: readOnly,
}}
/>
/>)}
</Col>
</Row>
<Row gutter={16}>
<Col span={12}>
<ProFormSelect
label={fieldLabels.bidOrgDict}
name="bidOrgDict"
label={fieldLabels.organization}
name="organization"
rules={[{ required: true, message: '请选择组织形式' }]}
valueEnum={organizationFormEnum}
fieldProps={{
disabled: readOnly,
onChange: (value) => {
setagencyCompanyShow(value === 'organization_1'? true: false);
}
}}
/>
</Col>
<Col span={12}>
<ProFormSelect
label={fieldLabels.tenderAgencyId}
name="tenderAgencyId"
{agencyCompanyShow && (<ProFormSelect
label={fieldLabels.agencyCompany}
name="agencyCompany"
rules={[{ required: true, message: '请选择招标代理机构' }]}
valueEnum={tenderAgencyEnum}
fieldProps={{
disabled: readOnly,
}}
/>
/>)}
</Col>
</Row>
</Card>
@ -524,9 +919,9 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
<>
<Row style={{ marginBottom: 16 }}>
<Col span={24}>
<Button type="primary" onClick={() => add({ bidSectionIndex: fields.length + 1, bidSectionCategory: [{ type: [], percent: 0 }] })} disabled={readOnly}>
{!readOnly && (<Button type="primary" onClick={() => add({ bidSectCode: fields.length + 1, bidSectionCategory: [{ id: null ,type: [], percent: 0 }] })}>
</Button>
</Button>)}
</Col>
</Row>
{fields.map(field => (
@ -534,10 +929,11 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
{field.key !== 0 && <Divider />}
<Row >
<Col span={8}>
<Form.Item name={"id"} hidden></Form.Item>
<ProFormText
{...field}
label="标段序号"
name={[field.name, 'bidSectionIndex']}
name={[field.name, 'bidSectCode']}
readonly
/>
</Col>
@ -545,7 +941,7 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
<ProFormText
{...field}
label="标段名称"
name={[field.name, 'bidSectionName']}
name={[field.name, 'bidSectName']}
rules={[{ required: true, message: '请输入标段名称' }]}
fieldProps={{
disabled: readOnly,
@ -554,16 +950,16 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
</Col>
<Col span={8}>
<Button danger onClick={() => remove(field.name)} style={{ marginLeft: 16 }} hidden={fields.length === 1} disabled={readOnly}>
{!readOnly && (<Button danger onClick={() => remove(field.name)} style={{ marginLeft: 16 }} hidden={fields.length === 1}>
</Button>
</Button>)}
</Col>
<Col span={8}>
<ProFormText
{...field}
label="标段编号"
name={[field.name, 'bidSectionNo']}
name={[field.name, 'sectionNumber']}
rules={[{ required: true, message: '请输入标段编号' }]}
fieldProps={{
disabled: readOnly,
@ -577,7 +973,7 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
<>
<ProFormDigit
label="标段预算"
name={[field.name, 'bidSectionBudget']}
name={[field.name, 'bidSectContractPrice']}
rules={[{ required: true, message: '请输入标段预算' }]}
fieldProps={{ precision: 2, style: { width: '80%' } }}
disabled={readOnly}
@ -594,9 +990,9 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
<Col span={8}>
<ProFormSelect
label="报价方式"
name={[field.name, 'bidMethod']}
name={[field.name, 'quotationMethodDict']}
rules={[{ required: true, message: '请选择报价方式' }]}
valueEnum={bidMethodEnum}
valueEnum={quotationMethodDictEnum}
fieldProps={{
disabled: readOnly,
}}
@ -605,9 +1001,9 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
<Col span={8}>
<ProFormSelect
label="评价方法"
name={[field.name, 'evaluationMethod']}
name={[field.name, 'evalMethodDict']}
rules={[{ required: true, message: '请选择评价方法' }]}
valueEnum={evaluationMethodEnum}
valueEnum={evalMethodDictEnum}
fieldProps={{
disabled: readOnly,
}}
@ -616,9 +1012,9 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
<Col span={8}>
<ProFormSelect
label="资格审查方法"
name={[field.name, 'reviewWay']}
name={[field.name, 'ptcpMode']}
rules={[{ required: true, message: '请选择资格审查方法' }]}
valueEnum={reviewWayEnum}
valueEnum={ptcpModeEnum}
fieldProps={{
disabled: readOnly,
}}
@ -627,9 +1023,9 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
<Col span={8}>
<ProFormSelect
label="流程类型"
name={[field.name, 'process']}
name={[field.name, 'chooseProcess']}
rules={[{ required: true, message: '请选择流程类型' }]}
valueEnum={processEnum}
valueEnum={chooseProcessEnum}
fieldProps={{
disabled: readOnly,
}}
@ -638,7 +1034,7 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
<Col span={8}>
<ProFormDigit
label="评标专家人数"
name={[field.name, 'reviewExpertCount']}
name={[field.name, 'juryNumber']}
rules={[{ required: true, message: '请输入评标专家人数' }]}
fieldProps={{ precision: 0, disabled: readOnly }}
min={0}
@ -654,6 +1050,7 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
<Fragment key={subField.key}>
<Row gutter={8}>
<Col span={8}>
<Form.Item hidden={true} name={"id"}></Form.Item>
<Form.Item label="主要标的类别" name={[subField.name, 'type']} rules={[
{
required: true,
@ -678,7 +1075,7 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
/>
<span style={{ position: 'absolute', right: '8%', top: 5 }}>%</span>
</Col>
<Col span={1} hidden={subFields.length === 1}>
<Col span={1} hidden={subFields.length === 1 || readOnly}>
<MinusCircleOutlined style={{ fontSize: 16, marginTop: 7, color: 'red' }} onClick={() => removeCategory(subField.name)} disabled={readOnly} />
</Col>
</Row>
@ -686,9 +1083,9 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
))}
<Row>
<Col span={16}>
<Button type="dashed" onClick={() => addCategory()} block icon={<PlusOutlined />} disabled={readOnly}>
{!readOnly && (<Button type="dashed" onClick={() => addCategory()} block icon={<PlusOutlined />} disabled={readOnly}>
</Button>
</Button>)}
</Col>
</Row>
</>
@ -706,7 +1103,7 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
</Card>
<Card title="备注" className={styles.card} bordered={false}>
<Form.Item name="remark" labelCol={{ span: 0 }} wrapperCol={{ span: 24 }}>
<Form.Item name="remarks" labelCol={{ span: 0 }} wrapperCol={{ span: 24 }}>
<Input.TextArea
autoSize={{ minRows: 3 }}
placeholder="请输入备注"
@ -757,4 +1154,4 @@ const ProjectFileCreate: FC<Record<string, any>> = () => {
);
};
export default ProjectFileCreate;
export default ProjectFileCreate;

View File

@ -1,15 +1,46 @@
import { Button } from 'antd';
import React, { useRef } from 'react';
import {Button, message, Modal, Table} from 'antd';
import React, {useEffect, useRef, useState} from 'react';
import { history } 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';
import { fetchProjectFileList } from './service';
import {agencyCompanyDispatch, fetchProjectEntrustFileList, getHistoryList} from './service';
import type { TableListItem, TableListPagination } from './data';
import { purchaseTypeEnum } from './dict';
import { procurementMode } from './dict';
import {ColumnsType} from "antd/es/table";
interface VersionData {
key: number;
index: number;
versionNo: string;
}
const ProjectFiles: React.FC = () => {
const actionRef = useRef<ActionType>();
const [versionData, setVersionData] = useState<VersionData[]>([]);
const [isModalOpen, setIsModalOpen] = useState(false);
const showModal = () => {
setIsModalOpen(true);
};
const handleOk = () => {
setIsModalOpen(false);
};
const handleCancel = () => {
setIsModalOpen(false);
};
useEffect(() => {
getHistoryList().then((res) => {
const records = res.data;
const newData = records.map((item: any, index: number) => ({
index: index + 1,
...item
}));
setVersionData(newData);
});
}, []);
const columns: ProColumns<TableListItem>[] = [
{
@ -26,7 +57,7 @@ const ProjectFiles: React.FC = () => {
},
{
title: '项目编号',
dataIndex: 'ebpProjectNumber',
dataIndex: 'projectNumber',
hideInSearch: true,
},
{
@ -36,42 +67,216 @@ const ProjectFiles: React.FC = () => {
},
{
title: '采购方式',
dataIndex: 'purchaseType',
dataIndex: 'procurementMode',
valueType: 'select',
valueEnum: purchaseTypeEnum,
valueEnum: procurementMode,
},
{
title: '采购类型',
dataIndex: 'purchaseType',
dataIndex: 'procurement_type',
hideInSearch: true,
render:(_, record) => {
const sectionList = record?.projectEntrustExpand?.sectionList;
const categoryArr: any[] = [];
for (const i in sectionList) {
const section = sectionList[i];
const categoryList = section?.categoryList;
categoryList.forEach((item: any) => {
categoryArr.push(item['category']);
})
}
return categoryArr.join(',');
}
},
{
/**
* 1 未分派 2 已分派/项目经理未同意 3 项目经理已同意
4 项目草稿 5 项目进行 9 拒绝
*/
title: '状态',
dataIndex: 'status',
valueType: 'select',
render: (_, record) => {
const status = Number(record.status);
if(status === 1){
return "未分派"
}else if(status === 2){
return "已分派";
}else if(status === 3){
return "项目经理已同意";
}else if(status === 4){
return "草稿"
}else if(status === 5){
return "进行中"
}else if(status === 9){
return "已拒绝"
}
return '-';
}
},
{
title: '版本号',
dataIndex: 'version',
dataIndex: 'versionNo',
hideInSearch: true,
render: (text: any, record: any) =>{
return record.versionNo ? record.versionNo : '-';
}
},
{
title: '操作',
dataIndex: 'option',
valueType: 'option',
render: (_, record) => [
<a
key="config"
onClick={() => {
history.push(`/ProjectFiles/file?action=view&id=${record.id}`);
}}
>
</a>,
],
render: (text: any, record: any) => (
<>
{(
<Button type="link" onClick={() =>
history.push({
pathname: '/ProjectFiles/file',
state: {
record: record,
opt: 'view'
}
})
}>
</Button>
)}
{(record.organization === 'organization_1')&&(
<Button type="link" onClick={() => {
showModal();
}}>
</Button>
)}
{(record.status === 4) &&(
<Button type="link" onClick={() =>
history.push({
pathname: '/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'
}
})
}
}>
</Button>
)}
{(record.status=== 1) && (
<Button type="link" onClick={() => {
history.push({
pathname: '/ProjectFiles/file',
state: {
record: record,
opt: 'assign',
myRoleCode: 'ebtp-agency-admin'
}
})
}
}>
</Button>
)}
{(record.status=== 1) && (
<Button type="link" onClick={() => {
const params = {
id: record.id,
remarks: '测试拒绝'
}
Modal.confirm({
title: '确认拒绝该项目?',
onOk: async () => {
await agencyCompanyDispatch(params).then((r: any) => {
if (r?.code == 200) {
message.success('操作成功');
} else {
message.error('操作失败');
}
})
.finally(() => actionRef.current?.reload());
},
});
}
}>
</Button>
)}
</>
)
},
];
const columns1: ColumnsType<VersionData> = [
{
title: '序号',
dataIndex: 'index',
key: 'index',
align: 'center',
},
{
title: '项目名称',
dataIndex: 'projectName',
key: 'projectName',
align: 'center',
},
{
title: '版本号',
dataIndex: 'versionNo',
key: 'versionNo',
align: 'center',
},
{
title: '操作',
dataIndex: 'option',
render: (text: any, record: any) => (
<>
{(
<Button type="link" onClick={() =>
history.push({
pathname: '/ProjectFiles/file',
state: {
record: record,
opt: 'view'
}
})
}>
</Button>
)}
</>
)
},
];
const request = async (params: any, sorter: any) => {
const requestParams = {
// ...params,
// ...searchParams,
purchasingManager: "xiaorui",
copyId: '-1',
// organization: 'organization_2',
basePageRequest: {
pageNo: params.current || 1,
pageSize: params.pageSize || 10
},
};
const result = await fetchProjectEntrustFileList(requestParams);
return {
data: result.data.records,
total: result.data.total,
success: true,
};
}
return (
<div className="project-file-container" style={{ backgroundColor: '#f8f8f8' }}>
<PageContainer title="我创建的项目">
@ -93,12 +298,33 @@ const ProjectFiles: React.FC = () => {
</Button>,
]}
options={{ density: false, reload: false, setting: false, fullScreen: false }}
request={fetchProjectFileList}
request={request}
columns={columns}
/>
</PageContainer>
<Modal
title="版本列表"
width={'461px'}
centered
visible={isModalOpen}
onOk={handleOk}
onCancel={handleCancel}
footer={[
<Button key="back" onClick={handleCancel}>
</Button>
]}
>
<Table
columns={columns1}
dataSource={versionData}
pagination={false}
bordered
size="small"
/>
</Modal>
</div>
);
};
export default ProjectFiles;
export default ProjectFiles;

View File

@ -1,36 +1,116 @@
// @ts-ignore
/* eslint-disable */
import { request } from 'umi';
import { TableListItem } from './data';
// import { TableListItem } from './data';
/** 获取规则列表 GET /api/rule */
export async function fetchProjectFileList(
params: {
// query
/** 当前的页码 */
current?: number;
/** 页面的容量 */
pageSize?: number;
},
) {
console.log(params);
return request<{
data: TableListItem[];
/** 列表的内容总数 */
total?: number;
success?: boolean;
}>('/api/projectFiles', {
method: 'GET',
params: {
...params,
},
});
}
const prefix = '/api/biz-service-ebtp-project/';
export async function submitForm(params: any) {
return request('/api/projectFile', {
// export async function fetchProjectFileList(params: any) {
// return request(prefix + 'v1/projectRecord/getPage', {
// data: params,
// method: 'POST'
// });
// }
export async function initProjectEntrustForCosco(params: any) {
return request(prefix + 'v1/projectEntrust/initProjectEntrustForCosco', {
method: 'POST',
data: params,
});
}
}
/** 获取我的进行中的项目 */
export async function getProjectInProgressPage(params: any) {
return request(prefix + 'v1/projectRecord/getProjectInProgressPage', {
method: 'POST',
data:params,
});
}
// /** 获取规则列表 GET /api/rule */
export async function fetchProjectFileList(params: any) {
return request(prefix + 'v1/projectRecord/getPage', {
method: 'POST',
data:params,
});
}
// /** 获取规则列表 GET /api/rule */
export async function getProjectOne(params: any) {
return request(prefix + 'v1/projectRecord/' + params, {
method: 'GET'
});
}
/** 获取代理项目列表 */
export async function fetchProjectEntrustFileList(params: any) {
return request(prefix + 'v1/projectEntrust/getPage', {
method: 'POST',
data:params,
});
}
/** 获取代理项目的 详情*/
export async function getProjectEntrustOne(params: any) {
return request(prefix + 'v1/projectEntrust/' + params, {
method: 'GET'
});
}
/**
* 分派项目经理
*
* @param id 委托单ID
* @param projectEntrust 分页信息
* @return 返回结果
*/
export async function dispatch(params: any) {
return request(prefix + 'v1/projectEntrust/dispatch/'+params.id, {
method: 'POST',
data: params,
});
}
/** 委托机构拒绝 */
export async function agencyCompanyDispatch(params: any) {
const {id = ''} = {...params};
return request(prefix + 'v1/projectEntrust/agencyCompanyDispatch/' + id, {
method: 'GET',
params: params
});
}
export async function getHistoryList() {
return request(prefix + 'v1/projectEntrust/getHistoryList', {
method: 'GET'
});
}
export async function saveProjectRecord(params: any) {
return request(prefix + 'v1/projectRecord', {
method: 'POST',
data: params,
});
}
export async function updateProjectEntrust(params: any) {
return request(prefix + 'v1/projectEntrust/update', {
method: 'POST',
data: params,
});
}
export async function saveSectionBatch(params: any) {
return request(prefix + 'v1/projectSection/insertBatch', {
method: 'POST',
data: params,
});
}
export async function updateSectionBatch(params: any) {
return request(prefix + 'v1/projectSection/updateBatch', {
method: 'POST',
data: params,
});
}

View File

@ -96,4 +96,15 @@ export async function fetchtClarify(params) { // 首页澄清列表
...params
}
});
}
}
/**
* 进行中的项目 首页
* @param params purchasingManager: 登陆人id , status 5
*/
export async function getProjectInProgress(params) {
return request('/api/biz-service-ebtp-project/v1/projectRecord/getProjectInProgress', {
method: 'GET',
params: params,
});
}