Commit e5a855d9 authored by 前端-钟卫鹏's avatar 前端-钟卫鹏

feat: 添加投标查询

parent 91523d3b
...@@ -47,8 +47,8 @@ const routeList = [ ...@@ -47,8 +47,8 @@ const routeList = [
// commentRoutes, // commentRoutes,
// contentRoute, // contentRoute,
// balancedRoute, // balancedRoute,
demandRoute, // demandRoute,
procurementRoute, // procurementRoute,
// demandQuoteOrderRoute, // demandQuoteOrderRoute,
// capitalAccount, // capitalAccount,
// messageRoute, // messageRoute,
......
...@@ -42,7 +42,22 @@ const router = { ...@@ -42,7 +42,22 @@ const router = {
hideInMenu: true, hideInMenu: true,
noMargin: true, noMargin: true,
}, },
{
// 投标查询
path: '/procurement/tenderSearch',
name: '投标查询',
hidePageHeader: true,
component: '@/pages/procurement/tenderSearch',
},
{
// 投标 详情
path: '/procurement/tenderSearch/detail',
name: '投标详情',
component: '@/pages/procurement/tenderSearch/detail',
hidePageHeader: true,
hideInMenu: true,
noMargin: true,
},
] ]
} }
......
import React, { useRef } from 'react' import React from 'react'
import { useCallback, useState, useEffect } from 'react' import { useCallback, useState, useEffect } from 'react'
import { usePageStatus } from '@/hooks/usePageStatus' import { usePageStatus } from '@/hooks/usePageStatus'
import { PublicApi } from '@/services/api' import { PublicApi } from '@/services/api'
import { Link } from 'umi'
import { GlobalConfig } from '@/global/config'
import { formatTimeString } from '@/utils'
import { message } from 'antd' import { message } from 'antd'
import { history } from 'umi'
interface OrderDetailHookProps { interface OrderDetailHookProps {
/** 招标,投标 */ /** 招标-招标详情,投标-投标详情,招标-投标详情,投标-招标详情 */
type: 'callForBid' | 'tender' type: 'callForBid' | 'tender' | 'callForBidInTender' | 'tenderInCallForBid'
} }
// 招标详情, 支持(招标、投标)两种模式 // 招标详情, 支持(招标-招标、投标-投标、招标-投标、投标-招标)两种模式
export const useBidDetail = (options: OrderDetailHookProps) => { export const useBidDetail = (options: OrderDetailHookProps) => {
// 详情数据 // 详情数据
const [formData, setFormData] = useState<any>(null) const [formData, setFormData] = useState<any>(null)
// 流转记录数据(内/外) // 流转记录数据(内/外)
const [interiorProcurementOrderLogResponses, setInteriorProcurementOrderLogResponses] = useState<any>(null) const [interiorProcurementOrderLogResponses, setInteriorProcurementOrderLogResponses] = useState<any>(null)
const [externalProcurementOrderLogResponses, setExternalProcurementOrderLogResponses] = useState<any>(null) const [externalProcurementOrderLogResponses, setExternalProcurementOrderLogResponses] = useState<any>(null)
// 流程状态数据(内/外)
const [interiorWorkflowFlowRecordLogResponses, setInteriorWorkflowFlowRecordLogResponses] = useState<any>(null)
const [externalWorkflowFlowRecordLogResponses, setExternalWorkflowFlowRecordLogResponses] = useState<any>(null)
// 地址 // 地址
const [address, setAddress] = useState<string>(null) const [address, setAddress] = useState<string>('')
// 内容元素距顶部距离数组 // 内容元素距顶部距离数组
const [offsetTopList, setOffsetTopList] = useState<number[]>([]) const [offsetTopList, setOffsetTopList] = useState<number[]>([])
...@@ -34,20 +33,63 @@ export const useBidDetail = (options: OrderDetailHookProps) => { ...@@ -34,20 +33,63 @@ export const useBidDetail = (options: OrderDetailHookProps) => {
reloadFormData() reloadFormData()
}, []) }, [])
const reloadFormData = useCallback(() => { const switchApi = (type) => {
let _api: any = null;
switch (type) {
case 'callForBid':
_api = PublicApi.getPurchaseInviteTenderPlatformGetInviteTender;
break;
case 'tender':
_api = PublicApi.getPurchaseInviteTenderPlatformGetSubmitTender;
break;
// case 'callForBidInTender':
// _api = PublicApi.getPurchaseInviteTenderGetSubmitTender;
// break;
// case 'tenderInCallForBid':
// _api = PublicApi.getPurchaseSubmitTenderGetInviteTender;
// break;
default:
_api = null;
}
return _api
}
// const switchParamField = (type) => {
// let field: any = null;
// switch (type) {
// case 'callForBid':
// field = 'inviteTenderId'
// break;
// case 'tender':
// field = 'submitTenderId'
// break;
// // case 'callForBidInTender':
// // field = 'submitTenderId'
// // break;
// // case 'tenderInCallForBid':
// // field = 'inviteTenderId'
// // break;
// default:
// field = null;
// }
// return field
// }
const reloadFormData = useCallback(async () => {
if (id) { if (id) {
// 详情 const fn = switchApi(type);
// @todo 需补充投标详情api let params: any = {};
const fn = type === 'callForBid' ? PublicApi.getPurchaseInviteTenderGetInviteTender : PublicApi.getPurchaseSubmitTenderGetInviteTender // params[switchParamField(type)] = id
fn({ id }, { ctlType: "none" }).then(res => { params['id'] = id
const { code, data, message: msg } = res
const { code, data, message: msg } = await fn(params, { ctlType: "none" })
if (code === 1000) { if (code === 1000) {
setFormData(data) setFormData(data)
if(data?.deliverAddress) { if(data?.deliverAddress) {
PublicApi.getLogisticsReceiverAddressGet({id: data.deliverAddress}).then(_res => { PublicApi.getLogisticsReceiverAddressGet({id: data.deliverAddress}).then(_res => {
const { data: _data } = _res const { data: _data } = _res
const { provinceName, cityName, districtName, address } = _data const { provinceName, cityName, districtName, address } = _data
if(res.code === 1000) { if(code === 1000) {
setAddress(`${provinceName}/${cityName}/${districtName}/${address}`) setAddress(`${provinceName}/${cityName}/${districtName}/${address}`)
} }
}) })
...@@ -55,28 +97,36 @@ export const useBidDetail = (options: OrderDetailHookProps) => { ...@@ -55,28 +97,36 @@ export const useBidDetail = (options: OrderDetailHookProps) => {
} else { } else {
message.error(msg) message.error(msg)
} }
})
// 有投标模式的情况下提取招标id
const searchId = type.indexOf('ender') !== -1 ? data.inviteTender.id : id
// 流转记录(内/外) // 流转记录(内/外)
// @todo 需补充投标记录api // 招投标
const inCheckRecordFn = PublicApi.getPurchaseInviteTenderInCheckRecordGetInviteTenderInCheckRecord const inCheckRecordFn = !type.indexOf('c')
inCheckRecordFn({ inviteTenderId: id }, { ctlType: "none" }).then(res => { ?
const { code, data, message: msg } = res PublicApi.getPurchaseInviteTenderInCheckRecordGetInviteTenderInCheckRecord
if (code === 1000) { :
setInteriorProcurementOrderLogResponses(data) PublicApi.getPurchaseSubmitTenderInCheckRecordGetSubmitTenderInCheckRecord
} else {
message.error(msg) const inReocrdRes = await inCheckRecordFn({ inviteTenderId: searchId })
if (inReocrdRes.code === 1000) {
setInteriorProcurementOrderLogResponses(inReocrdRes.data)
} }
})
const outCheckRecordFn = PublicApi.getPurchaseTenderOutCheckRecordGetTenderOutCheckRecord const outCheckRecordFn = PublicApi.getPurchaseTenderOutCheckRecordGetTenderOutCheckRecord
outCheckRecordFn({ inviteTenderId: id }, { ctlType: "none" }).then(res => { const outRecordRes = await outCheckRecordFn({ inviteTenderId: searchId })
const { code, data, message: msg } = res if (outRecordRes.code === 1000) {
if (code === 1000) { setExternalProcurementOrderLogResponses(outRecordRes.data)
setExternalProcurementOrderLogResponses(data) }
} else {
message.error(msg) // 流程状态(内/外)
// 招投标
const processRes = await PublicApi.getPurchaseInviteTenderGetInviteTenderProcess({ inviteTenderId: searchId })
if(processRes.code === 1000 && processRes.data) {
setInteriorWorkflowFlowRecordLogResponses(processRes.data.subProcess.userTaskList)
setExternalWorkflowFlowRecordLogResponses(processRes.data.userTaskList)
} }
})
} }
}, [id]) }, [id])
...@@ -85,13 +135,16 @@ export const useBidDetail = (options: OrderDetailHookProps) => { ...@@ -85,13 +135,16 @@ export const useBidDetail = (options: OrderDetailHookProps) => {
data: formData, data: formData,
interiorProcurementOrderLogResponses, interiorProcurementOrderLogResponses,
externalProcurementOrderLogResponses, externalProcurementOrderLogResponses,
interiorWorkflowFlowRecordLogResponses,
externalWorkflowFlowRecordLogResponses,
address, address,
offsetTopList, offsetTopList,
ctl: { ctl: {
setData: setFormData, setData: setFormData,
setOffsetTopList, setOffsetTopList,
}, },
reloadFormData reloadFormData,
apiType: type,
} }
return { return {
......
...@@ -24,7 +24,6 @@ const callForBidsSearch: React.FC<{}> = () => { ...@@ -24,7 +24,6 @@ const callForBidsSearch: React.FC<{}> = () => {
return ( return (
<PageHeaderWrapper>
<Card> <Card>
<StandardTable <StandardTable
fetchTableData={params => fetchTableData(params)} fetchTableData={params => fetchTableData(params)}
...@@ -54,7 +53,6 @@ const callForBidsSearch: React.FC<{}> = () => { ...@@ -54,7 +53,6 @@ const callForBidsSearch: React.FC<{}> = () => {
}} }}
/> />
</Card> </Card>
</PageHeaderWrapper>
) )
} }
......
...@@ -24,6 +24,13 @@ const mapColor = [ ...@@ -24,6 +24,13 @@ const mapColor = [
"rgb(101, 84, 192)", // 紫 "rgb(101, 84, 192)", // 紫
"rgb(230, 63, 59)", // 红 "rgb(230, 63, 59)", // 红
"rgb(0, 179, 122)", // 绿 "rgb(0, 179, 122)", // 绿
"rgb(96, 98, 102)", // 灰
"rgb(255, 153, 31)", // 黄
"rgb(63, 126, 210)", // 蓝
"rgb(101, 84, 192)", // 紫
"rgb(230, 63, 59)", // 红
"rgb(0, 179, 122)", // 绿
] ]
// 订单内部状态显示 // 订单内部状态显示
......
...@@ -53,8 +53,7 @@ const FirstCheckedBid:React.FC<FirstCheckedBidProps> = (props) => { ...@@ -53,8 +53,7 @@ const FirstCheckedBid:React.FC<FirstCheckedBidProps> = (props) => {
message.error('只能批量提交外部状态为待平台审核招标的招标') message.error('只能批量提交外部状态为待平台审核招标的招标')
} }
} }
return <PageHeaderWrapper> return <Card>
<Card>
<StandardTable <StandardTable
fetchTableData={params => fetchTableData(params)} fetchTableData={params => fetchTableData(params)}
rowSelection={rowSelection} rowSelection={rowSelection}
...@@ -96,7 +95,6 @@ const FirstCheckedBid:React.FC<FirstCheckedBidProps> = (props) => { ...@@ -96,7 +95,6 @@ const FirstCheckedBid:React.FC<FirstCheckedBidProps> = (props) => {
}} }}
/> />
</Card> </Card>
</PageHeaderWrapper>
} }
FirstCheckedBid.defaultProps = {} FirstCheckedBid.defaultProps = {}
......
.anchorGap {
div {
&:target {
padding-top: 190px;
margin-top: -190px;
}
}
}
import React, { useState, useCallback, useRef } from 'react';
import { Button } from 'antd';
import PreLoading from '@/components/PreLoading';
import { BidDetailContext } from '@/pages/procurement/_public/bid/context';
import { useBidDetail } from '@/pages/procurement/_public/bid/effects/useBidDetail';
import BidDetailHeader from '@/pages/procurement/components/bidDetailHeader';
import BidDetailSection from '@/pages/procurement/components/bidDetailSection';
import OrderDetailWrapper from '@/pages/orderSystem/components/OrderDetailWrapper';
const TenderSearchDetail: React.FC = () => {
const { formContext, id } = useBidDetail({type: 'tender'})
const {data} = formContext
const anchorTitleList = [
{ title: '流转进度', id: 'transferProcess', componentName: "TransferProcess" },
{ title: '中标结果', id: 'bidResult', type: "bidResult" },
{ title: '中标明细', id: 'bidParticulars', componentName: "BidParticulars" },
{ title: '基本信息', id: 'baseicInfo', type: "basicInfo" },
{ title: '投标要求', id: 'tenderNeed', type: "bidNeed" },
{ title: '投标其他要求', id: 'tenderOtherNeed', type: "bidNeed" },
{ title: '投标商品', id: 'tenderParticulars', componentName: "BidParticulars" },
{ title: '流转记录', id: 'transferRecord', componentName: "BidTransformRecord" },
]
return (
<div>
<BidDetailContext.Provider value={formContext}>
<BidDetailHeader
formContext={formContext}
anchorList={anchorTitleList}
/>
<OrderDetailWrapper>
<PreLoading loading={!formContext.data} active paragraph={{rows: 6}}>
<BidDetailSection formContext={formContext} anchorList={anchorTitleList} type="tender" />
</PreLoading>
</OrderDetailWrapper>
</BidDetailContext.Provider>
</div>
);
};
export default TenderSearchDetail;
import React from 'react'
import { Card} from 'antd'
import { StandardTable } from 'god'
import { useStateFilterSearchLinkageEffect } from '@/formSchema/effects/useFilterSearch'
import { FORM_FILTER_PATH } from '@/formSchema/const'
import { useSelfTable } from './model/useSelfTable'
import { tableListSchema } from './schema'
import Submit from '@/components/NiceForm/components/Submit'
import DateRangePickerUnix from '@/components/NiceForm/components/DateRangePickerUnix'
import { PublicApi } from '@/services/api'
import { BidOuterWorkState } from '@/constants'
const TenderSearch: React.FC<{}> = () => {
const {
ref,
columns
} = useSelfTable()
const fetchTableData = async (params) => {
const { data } = await PublicApi.postPurchaseInviteTenderPlatformGetSubmitTenderList(params, { ctlType: "none" })
return data
}
return (
<Card>
<StandardTable
fetchTableData={params => fetchTableData(params)}
currentRef={ref}
columns={columns}
rowKey={'id'}
formilyLayouts={{
justify: 'space-between'
}}
formilyProps={{
ctx: {
inline: false,
schema: tableListSchema,
effects: ($, actions) => {
useStateFilterSearchLinkageEffect(
$,
actions,
'code',
FORM_FILTER_PATH,
);
},
components: {
DateRangePickerUnix,
Submit
}
}
}}
/>
</Card>
)
}
export default TenderSearch
import React, { useRef } from 'react'
import EyePreview from '@/components/EyePreview'
import { formatTimeString } from '@/utils'
import CustomTag from '@/pages/procurement/components/CustomTag'
// 投标查询
export const useSelfTable = () => {
const ref = useRef<any>({})
const callForBidColumns: any[] = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
render: (text, record, index) => index + 1
},
{
title: '招标编号/项目',
align: 'center',
dataIndex: 'memberId',
key: 'memberId',
render: (text, record) => <>
<EyePreview url={`/procurement/callForBidsSearch/detail?id=${record.inviteTender.id}`}>
{record.inviteTender.code}
</EyePreview>
<div>{record.inviteTender.projectName}</div>
</>
},
{
title: '投标编号/会员',
align: 'center',
dataIndex: 'code',
key: 'code',
render: (text, record) => <>
{text ? <EyePreview url={`/procurement/tenderSearch/detail?id=${record.id}`}>
{text}
</EyePreview> : null}
<div>{record.memberName}</div>
</>
},
{
title: '投标时间',
align: 'center',
dataIndex: 'inviteTender',
key: 'inviteTender',
render: (text, record) => formatTimeString(record.inviteTender.inviteTenderStartTime),
width: 200
},
{
title: '开标时间',
align: 'center',
dataIndex: 'inviteTender',
key: 'inviteTender',
render: (text, record) => formatTimeString(record.inviteTender.openTenderTime),
width: 200
},
{
title: '是否中标',
align: 'center',
dataIndex: 'isWin',
key: 'isWin',
render: (text) => text ? '是' : '否'
},
{
title: '外部状态',
align: 'center',
dataIndex: 'inviteTender',
key: 'inviteTender',
render: (text, record) => <CustomTag status={record.inviteTender.tenderOutStatus} type='out' />
},
// {
// title: '内部状态',
// align: 'center',
// dataIndex: 'interiorState',
// key: 'interiorState',
// render: (text) => <CustomBadge status={text} type='inside' />
// },
]
return {
ref,
columns: callForBidColumns
}
}
import { ISchema } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { BidOutStateTexts } from '@/constants';
/**
* 招标查询列表高级筛选
*/
export const tableListSchema: ISchema = {
type: 'object',
properties: {
code: {
type: 'string',
"x-component": 'SearchFilter',
'x-component-props': {
placeholder: '请输入招标编号',
align: 'flex-start',
},
},
[FORM_FILTER_PATH]: {
type: 'object',
'x-component': 'flex-layout',
'x-component-props': {
inline: true,
rowStyle: {
justifyContent: 'start',
},
colStyle: {
marginRight: 20
}
},
properties: {
projectName: {
type: 'string',
'x-component-props': {
placeholder: '请输入投标项目',
}
},
tenderCode: {
type: 'string',
'x-component-props': {
placeholder: '请输入投标编号',
}
},
openTenderTime: {
type: 'string',
"x-component": 'data',
'x-component-props': {
placeholder: '开标开始时间',
showTime: true,
},
},
memberName: {
type: 'string',
'x-component-props': {
placeholder: '请输入投标会员',
}
},
tenderOutStatusList: {
type: 'string',
"x-component-props": {
placeholder: '请选择外部状态'
},
enum: Object.keys(BidOutStateTexts).map(item => ({
label: BidOutStateTexts[item],
value: item,
}))
},
// "interiorState": {
// type: 'string',
// "x-component-props": {
// placeholder: '请选择内部状态'
// },
// enum: Object.keys(PurchaseOrderInsideWorkStateTexts).map(item => ({
// label: PurchaseOrderInsideWorkStateTexts[item],
// value: item,
// }))
// },
submit: {
'x-component': 'Submit',
'x-component-props': {
children: '查询',
},
},
},
},
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment