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

feat: 新增招标查询、详情页面

parent 4621e9f3
......@@ -42,6 +42,36 @@ const memberCenterRoute = {
// // component: '@/pages/index',
// component: '@/pages/home',
// },
// srm开发临时使用...
{
path:"/memberCenter/procurementAbility",
routes: [
// 招标
{
path:'/memberCenter/procurementAbility/callForBids',
name:'招标',
routes:[
{
path: '/memberCenter/procurementAbility/callForBids/callForBidsSearch',
name: '招标查询',
component: '@/pages/procurement/callForBids/callForBidsSearch'
},
// 招标-详情
{
path: '/memberCenter/procurementAbility/callForBids/callForBidsSearch/preview',
name: '招标详情',
component: '@/pages/procurement/callForBids/callForBidsSearch/detail',
hideInMenu: true,
noMargin: true,
},
]
},
],
name:"采购能力",
icon:"commodity",
},
//...
...asyncRoutes,
{
path: '/memberCenter/noAuth',
......
/**
* @description: 采购能力 招标
* @param {type}
* @return {type}
*/
export default [
{
path:'/memberCenter/procurementAbility/callForBids',
name:'callForBids',
routes:[
// 招标查询
{
path: '/memberCenter/procurementAbility/callForBids/callForBidsSearch',
name: 'callForBidsSearch',
component: '@/pages/procurement/callForBids/callForBidsSearch'
},
// // 招标查询-详情
// {
// path: '/memberCenter/procurementAbility/callForBids/callForBidsSearch/preview',
// name: 'callForBidsSearchPreview',
// hideInMenu: true,
// component: '@/pages/procurement/callForBids/callForBidsSearch/details'
// },
]
}
]
import callForBids from './callForBids';
/**
* 采购能力路由
*/
const ProcurementRoute = {
path: '/memberCenter/procurementAbility',
name: 'procurementAbility',
icon: 'procurement',
routes: [
// 招标
...callForBids,
]
}
export default ProcurementRoute
......@@ -358,3 +358,15 @@ a {
}
}
}
// 固定头部
// .ant-layout-header {
// position: fixed;
// top: 0;
// }
// .ant-pro-page-header-wrap-page-header-warp {
// position: fixed;
// top: 0;
// width: 100%;
// z-index: 8;
// }
......@@ -632,5 +632,10 @@ export default {
'menu.balance.accountsReceivable.logisticsDetail': '物流通知单结算明细',
'menu.balance.accountsReceivable.productNoticeSettlementDetail': '生产通知单结算明细',
'menu.balance.accountsReceivable.invoice': '开票管理',
'menu.balance.settleRules.memberSettleDetailEdit': '编辑会员结算策略'
'menu.balance.settleRules.memberSettleDetailEdit': '编辑会员结算策略',
// 采购能力
'menu.procurementAbility': '采购能力',
'menu.procurementAbility.callForBids': '招标',
};
import { createContext } from 'react';
export const BidDetailContext = createContext<any>({})
import React, { useRef } from 'react'
import { useCallback, useState, useEffect } from 'react'
import { usePageStatus } from '@/hooks/usePageStatus'
import { PublicApi } from '@/services/api'
import { Link } from 'umi'
import { GlobalConfig } from '@/global/config'
import { formatTimeString } from '@/utils'
import { message } from 'antd'
import { history } from 'umi'
interface OrderDetailHookProps {
// 采购、销售
type: 'purchaseOrder' | 'saleOrder'
}
// 订单详情, 支持两种订单模式
export const useBidDetail = (options: OrderDetailHookProps) => {
// 订单详情内容
const [formData, setFormData] = useState<any>(null)
// 当前的支付信息id 默认第一个
const [currentPayInfoId, setCurrentPayInfoId] = useState<any>(null)
// 支付信息列表
const [payList, setPaylist] = useState<any[]>([])
const { id } = usePageStatus()
const { orderNo } = history.location.query
const { type } = options
const dataRef = useRef<any>([
{ label: '对应报价单号', name: 'quotationNo', span: 8, render: text => <Link to={'/'}>{text}</Link> },
{ label: '订单摘要', name: 'orderThe', span: 8 },
{ label: type === 'saleOrder' ? '采购会员' : '供应会员', name: type === 'saleOrder' ? 'createMemberName' : 'supplyMembersName', span: 8 },
{ label: '下单模式', name: 'orderModel', span: 8, render: text => GlobalConfig.web.orderMode.find(v => v.value === text)?.label || '' },
{ label: '订单类型', name: 'type', span: 8 },
{ label: '下单时间', name: 'createTime', span: 8, render: text => formatTimeString(text) },
{ label: '外部状态', name: 'externalState', span: 8 },
{ label: '内部状态', name: type === 'saleOrder' ? 'purchaseOrderInteriorState' : 'interiorState', span: 8 },
])
useEffect(() => {
reloadFormData()
}, [])
const reloadFormData = useCallback(() => {
if (id || orderNo) {
const fn = type === 'purchaseOrder' ? PublicApi.getOrderProcurementOrderDetails : PublicApi.getOrderPurchaseOrderDetails
fn( id ? { id } : { orderNo }, { ctlType: "none" }).then(res => {
const { code, data, message: msg } = res
if (code === 1000) {
setFormData(data)
// if(data.paymentInformationResponses.length > 0){
// setCurrentPayInfoId(data.paymentInformationResponses[0].id)
// }
reloadPayList(data.supplyMembersId, data.supplyMembersRoleId)
} else {
message.error(msg)
}
})
}
}, [id])
const reloadPayList = (memberId, memberRoleId) => {
PublicApi.getPayPayWayList({memberId, memberRoleId}).then(res => {
const { code, data } = res
if (code === 1000) {
setPaylist(data)
}
})
}
// 需共享的状态
const formContext = {
data: formData,
currentPayInfoId,
payList,
ctl: {
setData: setFormData,
setPayId: setCurrentPayInfoId,
},
reloadFormData
}
return {
formContext,
id,
detailList: dataRef.current
}
}
.anchorGap {
div {
&:target {
padding-top: 190px;
margin-top: -190px;
}
}
}
import React, { useState, useCallback, useRef, useContext, useEffect, createRef } from 'react';
import { history } from 'umi'
import { Button } from 'antd';
import OrderDetailWrapper from '@/pages/transaction/components/OrderDetailWrapper';
import PreLoading from '@/components/PreLoading';
// import { useOrderDetail } from '../../../_public/order/effects/useOrderDetail';
// import OrderDetailSection from '../../../components/orderDetailSection';
import OrderPayModal from '@/pages/transaction/components/orderPayModal';
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 OrderDetailSection from '@/pages/transaction/components/orderDetailSection';
import style from './index.less'
import BidDetailSection from '@/pages/procurement/components/bidDetailSection';
const CallForBidsSearchDetail: React.FC = () => {
const { formContext, id, detailList } = useBidDetail({type: 'purchaseOrder'})
const {data, currentPayInfoId} = formContext
const payRef = useRef<any>({})
/** 约定好 对应的锚点title和元素id映射 */
const anchorTitleMapId = [
{ title: '流转进度', id: 'transferProcess' },
{ title: '基本信息', id: 'baseicInfo' },
{ title: '招标物料', id: 'bidMaterial' },
{ title: '招标要求', id: 'bidNeed' },
{ title: '报名要求', id: 'registerNeed' },
{ title: '资格预审要求', id: 'checkNeed' },
{ title: '评标要求', id: 'remarkNeed' },
{ title: '其他要求', id: 'otherNeed' },
{ title: '招标方式', id: 'bidWay' },
{ title: '流转记录', id: 'transferRecord' },
]
return (
<div>
<BidDetailContext.Provider value={formContext}>
<BidDetailHeader
detailList={detailList}
detailData={formContext.data}
anchorList={anchorTitleMapId}
extraRight={
<>
<Button type='primary'>
去支付
</Button>
<div style={{ textAlign: 'right' }}>
<p style={{ marginTop: 12, fontSize: 12, color: '#6B778C' }}>本次需支付</p>
{ formContext.data && <p>¥666</p> }
</div>
</>
}
/>
<OrderDetailWrapper>
<PreLoading loading={!formContext.data} active paragraph={{rows: 6}}>
<BidDetailSection formContext={formContext} anchorList={anchorTitleMapId} />
</PreLoading>
</OrderDetailWrapper>
<OrderPayModal
currentRef={payRef}
/>
</BidDetailContext.Provider>
</div>
);
};
export default CallForBidsSearchDetail;
import React, { useRef } from 'react'
import { Button, Popconfirm, Card, Space} from 'antd'
import { PageHeaderWrapper } from '@ant-design/pro-layout'
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'
const callForBidsSearch: React.FC<{}> = () => {
const {
ref,
columns
} = useSelfTable()
const fetchTableData = async (params) => {
const { data } = await PublicApi.getOrderPendingOrderList(params)
return data
}
return (
<PageHeaderWrapper>
<Card>
<StandardTable
fetchTableData={params => fetchTableData(params)}
currentRef={ref}
columns={columns}
rowKey={'orderNo'}
formilyLayouts={{
justify: 'space-between'
}}
formilyProps={{
ctx: {
inline: false,
schema: tableListSchema,
effects: ($, actions) => {
useStateFilterSearchLinkageEffect(
$,
actions,
'orderNo',
FORM_FILTER_PATH,
);
},
components: {
DateRangePickerUnix,
Submit
}
}
}}
/>
</Card>
</PageHeaderWrapper>
)
}
export default callForBidsSearch
import React, { useRef } from 'react'
import { history, Link } from 'umi'
import { Button, Row, Col, Progress, Popconfirm } from 'antd'
import { PublicApi } from '@/services/api'
import EyePreview from '@/components/EyePreview'
import { formatTimeString } from '@/utils'
import { ORDER_TYPE, PurchaseOrderInsideWorkState, PurchaseOrderOutWorkState } from '@/constants'
import { PlayCircleOutlined, PoweroffOutlined } from '@ant-design/icons'
import CustomTag from '@/pages/procurement/components/CustomTag'
import CustomBadge from '@/pages/procurement/components/customBadge'
// 业务hooks, 待支付订单
export const useSelfTable = () => {
const ref = useRef<any>({})
const handleCancel = (param) => {
PublicApi.postOrderPurchaseOrderCancel({id: param}).then(res => {
if(res.code === 1000) {
ref.current.reload()
}
})
}
const payOrderColumns: any[] = [
{
title: '序号',
align: 'center',
dataIndex: 'id',
key: 'id',
render: (text, record, index) => index + 1
},
{
title: '招标编号/项目',
align: 'center',
dataIndex: 'orderNo',
key: 'orderNo',
render: (text, record) => <>
<EyePreview url={`/memberCenter/procurementAbility/callForBids/callForBidsSearch/preview?id=${record.id}`}>
{text}
</EyePreview>
<div>{text}</div>
</>
},
{
title: '采购类型',
align: 'center',
dataIndex: 'type',
key: 'type',
render: (text) => ORDER_TYPE[text]
},
{
title: '招标方式',
align: 'left',
dataIndex: 'supplyMembersName',
key: 'supplyMembersName',
},
{
title: '发布时间',
align: 'center',
dataIndex: 'createTime',
key: 'createTime',
render: (text, record) => formatTimeString(record.createTime),
width: 200
},
{
title: '报名开始/截止时间',
align: 'center',
dataIndex: 'createTime',
key: 'createTime',
render: (text, record) => <>
<div><PlayCircleOutlined />{formatTimeString(record.createTime)}</div>
<div><PoweroffOutlined />{formatTimeString(record.createTime)}</div>
</>,
width: 200
},
{
title: '资格预审开始/截止时间',
align: 'center',
dataIndex: 'createTime',
key: 'createTime',
render: (text, record) => <>
<div><PlayCircleOutlined />{formatTimeString(record.createTime)}</div>
<div><PoweroffOutlined />{formatTimeString(record.createTime)}</div>
</>,
width: 200
},
{
title: '投标开始/截止时间',
align: 'center',
dataIndex: 'createTime',
key: 'createTime',
render: (text, record) => <>
<div><PlayCircleOutlined />{formatTimeString(record.createTime)}</div>
<div><PoweroffOutlined />{formatTimeString(record.createTime)}</div>
</>,
width: 200
},
{
title: '外部状态',
align: 'center',
dataIndex: 'externalState',
key: 'externalState',
render: text => <CustomTag status={text} type='out' />
},
{
title: '内部状态',
align: 'center',
dataIndex: 'interiorState',
key: 'interiorState',
render: (text) => <CustomBadge status={text} type='inside' />
},
{
title: '操作',
align: 'center',
dataIndex: 'ctl',
key: 'ctl',
render: (text, record) => <>
<Button type='link'>复制</Button>
<Popconfirm
title="是否要取消该订单?"
onConfirm={() => handleCancel(record.id)}
okText="是"
cancelText="否"
>
<Button type='link'>废标</Button>
</Popconfirm>
</>
}
]
return {
ref,
columns: payOrderColumns
}
}
import { ISchema } from '@formily/antd';
import { FORM_FILTER_PATH } from '@/formSchema/const';
import { OrderTypeMap, PurchaseOrderInsideWorkStateTexts, PurchaseOrderOutWorkStateTexts } from '@/constants';
/**
* 招标查询列表高级筛选
*/
export const tableListSchema: ISchema = {
type: 'object',
properties: {
orderNo: {
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: {
orderThe: {
type: 'string',
'x-component-props': {
placeholder: '请输入招标项目',
}
},
"[startCreateTime,endCreateTime]": {
type: 'array',
"x-component": 'DateRangePickerUnix',
'x-component-props': {
placeholder: ['发布开始时间','发布结束时间'],
},
},
"[startEnterTime,endEnterTime]": {
type: 'array',
"x-component": 'DateRangePickerUnix',
'x-component-props': {
placeholder: ['报名开始时间','报名结束时间'],
},
},
"externalState": {
type: 'string',
"x-component-props": {
placeholder: '请选择外部状态'
},
enum: Object.keys(PurchaseOrderOutWorkStateTexts).map(item => ({
label: PurchaseOrderOutWorkStateTexts[item],
value: item,
}))
},
"interiorState": {
type: 'string',
"x-component-props": {
placeholder: '请选择内部状态'
},
enum: Object.keys(PurchaseOrderInsideWorkStateTexts).map(item => ({
label: PurchaseOrderInsideWorkStateTexts[item],
value: item,
}))
},
"[startApplyTime,endApplyTime]": {
type: 'array',
"x-component": 'DateRangePickerUnix',
'x-component-props': {
placeholder: ['预审开始时间','预审结束时间'],
},
},
"[startBidTime,endBidTime]": {
type: 'array',
"x-component": 'DateRangePickerUnix',
'x-component-props': {
placeholder: ['投标开始时间','投标结束时间'],
},
},
submit: {
'x-component': 'Submit',
'x-component-props': {
children: '查询',
},
},
},
},
}
}
.card-list {
font-size: 12px;
line-height: 20px;
margin-top: 24px;
}
.card-list_title {
font-size: 12px;
color: #909399;
}
import React, { useContext, useState } from 'react'
import { Row, Col, Tag, Modal } from 'antd'
import MellowCard from '@/components/MellowCard'
import { BidDetailContext } from '@/pages/procurement/_public/bid/context';
import { formatTimeString } from '@/utils'
import style from './index.less'
import { CaretDownOutlined, CaretUpOutlined } from '@ant-design/icons';
export interface BasicInfoProps {
cardTitle?: string;
}
const BasicInfo: React.FC<BasicInfoProps> = ({cardTitle}) => {
const bidDetailContext = useContext(BidDetailContext)
const { data, ctl } = bidDetailContext
const [showMore, setShowMore] = useState<boolean>(false)
console.log(data, 'basicInfo')
const toogleMore = () => {
setShowMore(!showMore)
}
const columnList = [
{
span: 8,
fieldList: [
{ title: '招标编号', name: 'orderNo' },
{ title: '外部状态', name: 'orderModel' },
{ title: '内部状态', name: 'orderModel' },
{ title: '发布时间', name: 'createTime', render: (text) => formatTimeString(text) },
]
},
{
span: 8,
fieldList: [
{ title: '招标项目', name: 'createMemberName' },
{ title: '项目预算', name: 'createMemberName' },
{ title: '采购类型', name: 'createMemberName' },
{ title: '招标会员', name: 'createMemberName' },
{ title: '招标摘要', name: 'createMemberName' },
]
},
{
span: 8,
fieldList: [
{
title: '适用地址',
name: 'paymentInformationResponses',
render: (t, r) => {
const showDataSource = showMore ? data['paymentInformationResponses'] : [...data['paymentInformationResponses']].splice(0, 3)
return <>
<p>
{
showDataSource.map((_item, _i) => <p key={_i}>{_item.payNode+'/'+(_item.payNode||'')}</p>)
}
</p>
{
data.length > 3 &&
<p onClick={toogleMore} style={{ cursor: 'pointer' }} className="commonPickColor">
展开{showMore ? <CaretDownOutlined /> : <CaretUpOutlined />}
</p>
}
</>
}
},
]
}
]
const RenderBasicInfoColumns = ({ infoList = [], dataSource }) => <Row>
{
infoList.map(({span, fieldList = []}, index) => (<Col key={index} span={span}>
{
// item.fieldList.map((_v, _i) => dataSource[_v.name] ? <Row key={_v.name} className={style['card-list']}>
// <Col span={6} className={style['card-list_title']}>{_v.title}</Col>
// {/* <Col flex={1} {..._v.resetCol}>{_v.render ? _v.render(dataSource[_v.name], dataSource) : dataSource[_v.name]}</Col> */}
// </Row> : null)
fieldList.length ? fieldList.map((_v, _i) => <Row key={_v.name} className={style['card-list']}>
<Col span={6} className={style['card-list_title']}>{_v.title}</Col>
<Col>{_v.render ? _v.render(dataSource[_v.name], dataSource) : dataSource[_v.name]}</Col>
</Row>) : null
}
</Col>))
}
</Row>
return (
<MellowCard
title={cardTitle}
style={{marginTop: 24}}
bordered={false}
fullHeight
>
<RenderBasicInfoColumns infoList={columnList} dataSource={data} />
</MellowCard>)
}
BasicInfo.defaultProps = {}
export default BasicInfo
.titleAvator {
width:48px;
height:48px;
background:rgba(135,119,217,1);
border-radius:4px;
border:1px solid rgba(223,225,230,1);
line-height: 48px;
text-align: center;
color: #fff;
margin: 0 24px;
}
.titleAvatorText {
font-size: 16px;
font-weight: 500;
color: #303133;
margin-left: 8px;
}
.detailHeader {
background: #fff;
padding: 24px 24px 0;
}
.detailCol {
display: flex;
margin-top: 20px;
color: #303133;
}
.colLabel {
color: #909399;
margin-right: 16px;
}
// tabs标签锚点
.anchorTitle {
height: 48px;
ul {
padding-left: 0;
display: flex;
li {
height: 48px;
line-height: 48px;
text-align: center;
list-style: none;
a {
display: inline-block;
height: 48px;
font-size: 14px;
color: #909399;
line-height: 48px;
margin: 0 16px;
}
.current {
font-weight: 500;
color: #303133;
border-bottom: 2px solid #00B37A;
}
}
}
}
.anchorTitleFixed {
position: fixed;
top: 0;
width: 100%;
z-index: 10;
}
import React, { ReactNode, useEffect, useRef, useState } from 'react'
import { Row, Col, Skeleton } from 'antd'
import { history } from 'umi'
import { ArrowLeftOutlined, BugTwoTone } from '@ant-design/icons'
import style from './index.less'
export interface BidDetailHeaderProps {
extraRight?: ReactNode,
detailList?: { label: string, name: string, render?(text, record?), [key: string]: any }[],
detailData?: any,
anchorList?: any,
}
/**
* 招标详情头部
*/
const BidDetailHeader:React.FC<BidDetailHeaderProps> = ({ extraRight, detailList = [], detailData, anchorList = []}) => {
const isLoading = !!detailData
const flagRef = useRef({
flag: false,
distanceTop: 0
})
const [current, setCurrent] = useState<number>(0)
// const itemList = ['#components1', '#components2', '#components3', '#components31A', '#components32A', '#components4']
const [isFixed, setIsFixed] = useState<boolean>(false)
useEffect(() => {
window.addEventListener("scroll", onScroll);
return (()=>{
window.removeEventListener('scroll', onScroll)
})
}, [])
const onScroll = () => {
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
let floors = document.querySelectorAll(".anchorContent>div")
floors.forEach((floor: any, index: any) => {
if(floor.offsetTop - 100 <= scrollTop) {
setCurrent(index)
}
})
// 锚点导航距离顶端距离
let navDom: any = document.getElementById("anchorTitle")
let distance = navDom.offsetTop - document.documentElement.scrollTop
if(!flagRef.current.flag) {
flagRef.current.distanceTop = navDom.offsetTop
flagRef.current.flag = true
}
if(distance <= 0) {
setIsFixed(true)
}
if(document.documentElement.scrollTop <= flagRef.current.distanceTop) {
setIsFixed(false)
}
}
const clickItem = (index: any) => {
setCurrent(index)
}
return (
<div className={isFixed ? [style.detailHeader, style.anchorTitleFixed].join(' '): style.detailHeader} id="detailHeader">
{
isLoading ?
<Row>
{
<Col>
<Row align='middle'>
<Col>
<ArrowLeftOutlined onClick={() => history.goBack()}/>
</Col>
<Col>
<div className={style.titleAvatorText}>订单号: {detailData.orderNo}</div>
</Col>
</Row>
<Row>
<Col>
{/* <div className={isFixed ? [style.anchorTitle, style.anchorTitleFixed].join(' '): style.anchorTitle} id="anchorTitle"> */}
<div className={style.anchorTitle} id="anchorTitle">
<ul className={style.anchorUl}>
{
anchorList.map((item, index) => (
<li key={index} onClick={()=>clickItem(index)}>
<a href={`#${item.id}`} className={current === index ? style.current : null}>{item.title}</a>
</li>
))
}
</ul>
</div>
</Col>
</Row>
</Col>
}
</Row>
: <Skeleton avatar={{shape: 'square'}} active paragraph={{ rows: 3 }} />
}
</div>
)
}
BidDetailHeader.defaultProps = {}
export default BidDetailHeader
.anchorContentWrap {
div {
&:target {
padding-top: 160px;
margin-top: -160px;
}
}
}
import React from 'react'
import { Card, Radio } from 'antd'
import AuditProcess from '@/components/AuditProcess'
import { findLastIndexFlowState } from '@/utils'
// import OrderProductTable from '../../components/orderProductTable'
// import SaleOrderProductTable from '../../components/saleOrderProductTable'
// import OrderPayTabs from '../../components/orderPayTabs'
// import OrderMergeInfo from '../../components/orderMergeInfo'
// import OrderDeleveRecord from '../../components/orderDeleveRecord'
// import OrderTransformRecord from '../../components/orderTransformRecord'
// import OrderSaleRecord from '../orderSaleRecord'
import style from './index.less'
import MellowCard from '@/components/MellowCard'
import TransferProcess from '../transferProcess'
import BasicInfo from '../basicInfo'
export interface BidDetailSectionProps {
formContext: any,
type?: 'purchaseOrder' | 'saleOrder',
anchorList?: any,
}
const BidDetailSection:React.FC<BidDetailSectionProps> = ({formContext, type = 'purchaseOrder', anchorList = []}) => {
return (
// formContext.data && <div className='gray-wrap'>
// <AuditProcess
// customTitleKey='operationalProcess'
// customKey='state'
// outerVerifyCurrent={findLastIndexFlowState(formContext.data.externalWorkflowFlowRecordLogResponses)}
// innerVerifyCurrent={findLastIndexFlowState(formContext.data.interiorWorkflowFlowRecordLogResponses)}
// outerVerifySteps={
// formContext.data.externalWorkflowFlowRecordLogResponses ?
// formContext.data.externalWorkflowFlowRecordLogResponses.map(item => ({
// ...item,
// status: item.isExecute ? 'finish' : 'wait',
// })) :
// []
// }
// innerVerifySteps={
// formContext.data.interiorWorkflowFlowRecordLogResponses ?
// formContext.data.interiorWorkflowFlowRecordLogResponses.map(item => ({
// ...item,
// status: item.isExecute ? 'finish' : 'wait',
// })) :
// []
// }
// ></AuditProcess>
// { type === 'saleOrder' ? <SaleOrderProductTable/> : <OrderProductTable editable /> }
// <OrderPayTabs />
// <OrderMergeInfo />
// { type === 'saleOrder' ? <OrderSaleRecord /> : <OrderDeleveRecord /> }
// <OrderTransformRecord type={type}/>
// </div>
// const anchorTitleMapId = [
// { title: '流转进度', id: 'transferProcess' },
// { title: '基本信息', id: 'baseicInfo' },
// { title: '招标物料', id: 'bidMaterial' },
// { title: '招标要求', id: 'bidNeed' },
// { title: '报名要求', id: 'registerNeed' },
// { title: '资格预审要求', id: 'checkNeed' },
// { title: '评标要求', id: 'remarkNeed' },
// { title: '其他要求', id: 'otherNeed' },
// { title: '招标方式', id: 'bidWay' },
// { title: '流转记录', id: 'transferRecord' },
// ]
formContext.data &&
<div className={[style.anchorContentWrap, "anchorContent"].join(' ')}>
<div id={anchorList[0]['id']}>
<TransferProcess
cardTitle={anchorList[0]['title']}
customTitleKey='operationalProcess'
customKey='state'
outerVerifyCurrent={findLastIndexFlowState(formContext.data.externalWorkflowFlowRecordLogResponses)}
innerVerifyCurrent={findLastIndexFlowState(formContext.data.interiorWorkflowFlowRecordLogResponses)}
outerVerifySteps={
formContext.data.externalWorkflowFlowRecordLogResponses ?
formContext.data.externalWorkflowFlowRecordLogResponses.map(item => ({
...item,
status: item.isExecute ? 'finish' : 'wait',
})) :
[]
}
innerVerifySteps={
formContext.data.interiorWorkflowFlowRecordLogResponses ?
formContext.data.interiorWorkflowFlowRecordLogResponses.map(item => ({
...item,
status: item.isExecute ? 'finish' : 'wait',
})) :
[]
}
></TransferProcess>
</div>
<div id={anchorList[1]['id']}>
<BasicInfo cardTitle={anchorList[1]['title']}/>
</div>
<div id={anchorList[2]['id']}>
<MellowCard title={anchorList[2]['title']} style={{marginTop: 24}} bordered={false}>
<p>1234564654</p>
<br/>
<p>1234564654</p>
<br/>
<p>1234564654</p>
<br/>
<p>1234564654</p>
<br/>
<p>1234564654</p>
<br/>
<p>1234564654</p>
<p>1234564654</p>
<br/>
<p>1234564654</p>
<br/>
<p>1234564654</p>
<br/>
<p>1234564654</p>
<br/>
<p>1234564654</p>
</MellowCard>
</div>
<div id={anchorList[3]['id']}>
<MellowCard title={anchorList[3]['title']} style={{marginTop: 24}} bordered={false}>
<p>1234564654</p>
<br/>
<p>1234564654</p>
<br/>
<p>1234564654</p>
<br/>
<p>1234564654</p>
<br/>
<p>1234564654</p>
<br/>
<p>1234564654</p>
<p>1234564654</p>
<br/>
<p>1234564654</p>
<br/>
<p>1234564654</p>
<br/>
<p>1234564654</p>
<br/>
<p>1234564654</p>
</MellowCard>
</div>
</div>
)
}
BidDetailSection.defaultProps = {}
export default BidDetailSection
import React from 'react'
import { Tag } from 'antd'
import { insideStatusText, outStatusText } from '../constants'
// 用于标签状态控制
export interface StatusColorsProps {
status: number,
type: 'out' | 'inside'
}
// 颜色映射
const mapColor = [
"#606266", // 灰
"#FF991F", // 黄
"#3F7ED2", // 蓝
"#6554C0", // 紫
"#E63F3B", // 红
"#00B37A", // 绿
]
// className映射
const classNameMap = [
"commonStatusStop", // 灰色
"commonStatusInvalid", // 黄色
"commonStatusModify", // 蓝色
"commonStatusValid", // 绿色
"commonStatusStop", // 灰色
"commonStatusInvalid", // 黄色
"commonStatusModify", // 蓝色
"commonStatusValid", // 绿色
"commonStatusStop", // 灰色
"commonStatusInvalid", // 黄色
"commonStatusModify", // 蓝色
"commonStatusValid", // 绿色
]
const typeMaps = {
'out': outStatusText,
'inside': insideStatusText,
}
// 订单内部状态显示
const CustomBadge: React.FC<StatusColorsProps> = (props) => {
const { status, type } = props
const statusText = typeMaps[type]
// const statusShowColor = matchStatusColor(status)
return (<><span className={classNameMap[status]}></span>{statusText[status]}</>)
}
CustomBadge.defaultProps = {}
export default CustomBadge
import React from 'react'
import { Tag } from 'antd'
import { insideStatusText, outStatusText } from '../constants'
// 用于标签状态控制
export interface StatusColorsProps {
status: number,
type: 'out' | 'inside'
}
// 颜色映射
const mapColor = [
"rgb(96, 98, 102)", // 灰
"rgb(255, 153, 31)", // 黄
"rgb(63, 126, 210)", // 蓝
"rgb(101, 84, 192)", // 紫
"rgb(230, 63, 59)", // 红
"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)", // 绿
]
const typeMaps = {
'out': outStatusText,
'inside': insideStatusText,
}
// 订单内部状态显示
const CustomTag: React.FC<StatusColorsProps> = (props) => {
const { status, type } = props
const statusText = typeMaps[type]
// const statusShowColor = matchStatusColor(status)
return (
<span style={{
color: mapColor[status],
padding: '2px 4px',
backgroundColor: `rgba(${mapColor[status].slice(4, mapColor[status].length-1)}, 0.1)`,
borderRadius: '4px',
}}>{statusText[status]}</span>
)
}
CustomTag.defaultProps = {}
export default CustomTag
.cardWrap {
:global {
.ant-radio-button-wrapper:hover {
color: #606266;
}
.ant-radio-group-solid .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled) {
color: #fff;
background: #6B778C;
border-color: #6B778C;
}
.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled)::before {
background-color: #6B778C;
}
}
}
/**
* 带按钮式Radio切换的流转进度
*/
import React, { useState } from 'react';
import {
Steps,
Tabs,
Radio
} from 'antd';
import MellowCard from '@/components/MellowCard';
import style from './index.less'
interface TransferProcessProp {
outerVerifyCurrent?: number;
innerVerifyCurrent?: number;
outerVerifySteps?: {
step: number,
stepName: string,
roleName: string,
status?: 'wait' | 'process' | 'finish' | 'error',
}[];
innerVerifySteps?: {
step: number,
stepName: string,
roleName: string,
status?: 'wait' | 'process' | 'finish' | 'error',
}[];
customTitleKey?: string;
customKey?: string;
cardTitle?: string;
};
export enum TransferEnum {
/** 外部流转 */
Outer = 1,
/** 内部流转 */
Interior = 2,
}
const TransferProcess: React.FC<TransferProcessProp> = ({
outerVerifyCurrent = 0,
innerVerifyCurrent = 0,
outerVerifySteps = [],
innerVerifySteps = [],
customTitleKey,
customKey,
cardTitle = ''
}) => {
const [transferRadio, setTransferRadio] = useState<TransferEnum>(TransferEnum.Outer)
const handleChangeType = (e) => {
setTransferRadio(e.target.value)
}
return (
<MellowCard
title={cardTitle}
bordered={false}
extra={
<Radio.Group value={transferRadio} buttonStyle="solid" size="small" onChange={handleChangeType}>
{outerVerifySteps?.length ? <Radio.Button value={TransferEnum.Outer}>外部流转</Radio.Button> : null}
{innerVerifySteps?.length ? <Radio.Button value={TransferEnum.Interior}>内部流转</Radio.Button> : null}
</Radio.Group>
}
className={style.cardWrap}
>
{
(outerVerifySteps?.length && transferRadio === TransferEnum.Outer) ?
<Steps style={{ marginTop: 30, overflow: "auto", paddingTop: 5, paddingBottom: 5, }} progressDot current={outerVerifyCurrent}>
{outerVerifySteps.map(item => (
<Steps.Step
key={customKey ? item[customKey] : item.step}
title={customTitleKey ? item[customTitleKey] : item.stepName}
description={item.roleName}
status={item.status}
/>
))}
</Steps>
: null
}
{
(innerVerifySteps?.length && transferRadio === TransferEnum.Interior) ?
<Steps style={{ marginTop: 30, overflow: "auto", paddingTop: 5, paddingBottom: 5, }} progressDot current={innerVerifyCurrent}>
{innerVerifySteps.map(item => (
<Steps.Step
key={customKey ? item[customKey] : item.step}
title={customTitleKey ? item[customTitleKey] : item.stepName}
description={item.roleName}
status={item.status}
/>
))}
</Steps>
: null
}
</MellowCard>
)
};
export default TransferProcess;
// 招投标内部状态
export const insideStatusText = [
"待提交审核",
"审核通过",
"报名审核通过",
"资格预审审核通过",
"待开标",
"待评标",
"待提交审核定标",
"定标审核通过(二级)",
"完成招标",
"已废标"
]
// 招投标外部状态
export const outStatusText = [
"待提交招标",
"待平台审核招标",
"待招标报名",
"待资格预审",
"待开标",
"待评标",
"待定标",
"待中标公示",
"完成招标",
"已废标"
]
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