669 lines
27 KiB
TypeScript
669 lines
27 KiB
TypeScript
/*
|
||
* @Author: liqiang
|
||
* @Date: 2021-02-23 13:49:53
|
||
* @LastEditTime: 2021-03-25 16:46:14
|
||
* @LastEditors: Please set LastEditors
|
||
* @Description: In User Settings Edit
|
||
* @FilePath: \ebtp-cloud-frontend\src\pages\Auction\AuctionViewAuctions\components\A.tsx
|
||
*/
|
||
import { getURLInformation, isEmpty } from '@/utils/CommonUtils';
|
||
import { Button, Col, Divider, Form, Input, message, Modal, Row, Spin, Tabs } from 'antd';
|
||
import React, { useEffect, useRef, useState } from 'react';
|
||
import ProTable from '@ant-design/pro-table';
|
||
import ExtendUpload from '@/utils/ExtendUpload';
|
||
import '../../AuctionViewAuctions/auctionParts.less';
|
||
import { getProId, getSessionUserData } from '@/utils/session';
|
||
import { pictureDisplayPath } from '@/utils/DownloadUtils';
|
||
import { algebraicAddition, digitalConversionAmount } from '@/utils/NumberUtils';
|
||
import { getFilelist } from '@/services/download_';
|
||
import { getAuctionViewAuctions, getRedisBidData, putOrderBidPrice, updatetOnlookers } from '../../AuctionViewAuctions/service';
|
||
import AuctionImage from '../../AuctionViewAuctions/components/AuctionImage';
|
||
import CountDownUtils from '../../AuctionViewAuctions/components/CountDownUtils';
|
||
import { insertBidders } from '../../AuctionLookingForInnerShot/service';
|
||
const { TabPane } = Tabs;
|
||
|
||
const layout = {
|
||
labelCol: { span: 7 },
|
||
wrapperCol: { span: 13 },
|
||
};
|
||
|
||
//定时器间隔时间
|
||
const timingInterval = 5000;
|
||
//金额校验正则 保留两位小数
|
||
const amountMoney = /^\d{1,15}([.]\d{1,2})?$/;
|
||
const AuctionViewAuctions: React.FC = () => {
|
||
//项目id
|
||
const tpId = isEmpty(getProId()) ? getURLInformation('id') : getProId();
|
||
//状态 0围观 1 参拍
|
||
const [viewStatus, setViewStatus] = useState<string>('');
|
||
//出价数据
|
||
const [cjDataSource, setCjDataSource] = useState<any[]>([]);
|
||
//起拍价
|
||
const [startingPrice, setStartingPrice] = useState<any>();
|
||
//公告数据
|
||
const [noticeData, setNoticeData] = useState<any>();
|
||
//物资数据
|
||
const [auctionMaterialsList, setAuctionMaterialsList] = useState<any[]>([]);
|
||
//标的物所在地:右侧信息
|
||
const [locationOfTheSubjectMatter, setLocationOfTheSubjectMatter] = useState<any>();
|
||
const [subjectMatterIntroductionForm] = Form.useForm();
|
||
//标的物清单附件bid
|
||
const [subjectMatterIntroductionBid, setSubjectMatterIntroductionBid] = useState<string>('');
|
||
//项目名称
|
||
const [projectName, setProjectName] = useState<string>('');
|
||
//参拍信息
|
||
const [participateData, setParticipateData] = useState<any>();
|
||
//当前价
|
||
const [currentPrice, setCurrentPrice] = useState<number>(0);
|
||
//延时次数
|
||
const [delay, setDelay] = useState<any>();
|
||
//是否结束
|
||
const [overFlag, setOverFlag] = useState<boolean>(false);
|
||
//是否开始
|
||
const [startFlag, setStartFlag] = useState<boolean>(false);
|
||
//竞拍数据
|
||
const [auctionData, setAuctionData] = useState<any>();
|
||
//倒计时剩余时间
|
||
const [countDownTime, setCountDownTime] = useState<any>(null);
|
||
//结束时间
|
||
const [endTime, setEndTime] = useState<string>('');
|
||
//开始时间
|
||
const [startTime, setStartTime] = useState<string>('');
|
||
const ref = useRef<any>();
|
||
|
||
const overFlagRef = useRef<any>();
|
||
//图片
|
||
const [auctionImage, setAuctionImage] = useState<string[]>([]);
|
||
//显示图片
|
||
const [auctionImageFlag, setAuctionImageFlag] = useState<boolean>(false);
|
||
//控制模态框是否显示
|
||
const [isModalVisible, setIsModalVisible] = useState<boolean>(false);
|
||
//loading
|
||
const [loading, setLoading] = useState<boolean>(false);
|
||
//form
|
||
const [form] = Form.useForm();
|
||
//当前用户信息
|
||
const userData = getSessionUserData();
|
||
|
||
const cjColumns = [
|
||
{
|
||
title: '序号',
|
||
valueType: 'index'
|
||
},
|
||
{
|
||
title: '参拍人',
|
||
dataIndex: 'supplierId',
|
||
},
|
||
{
|
||
title: '出价(元)',
|
||
dataIndex: 'price',
|
||
},
|
||
{
|
||
title: '出价时间',
|
||
dataIndex: 'bidTime',
|
||
},
|
||
];
|
||
|
||
const wzColumns = [
|
||
{
|
||
title: '所属OU组织',
|
||
dataIndex: 'organization',
|
||
},
|
||
{
|
||
title: '物资名称',
|
||
dataIndex: 'materialName',
|
||
},
|
||
{
|
||
title: '物料编码',
|
||
dataIndex: 'materialCode',
|
||
},
|
||
{
|
||
title: '物资厂家',
|
||
dataIndex: 'manufacturer',
|
||
},
|
||
{
|
||
title: '规格型号',
|
||
dataIndex: 'specification',
|
||
key: 'specification',
|
||
},
|
||
{
|
||
title: '库龄',
|
||
dataIndex: 'reservoirAge',
|
||
},
|
||
{
|
||
title: '数量',
|
||
dataIndex: 'amount',
|
||
},
|
||
{
|
||
title: '计量单位',
|
||
dataIndex: 'materialUnit',
|
||
},
|
||
{
|
||
title: '单价',
|
||
dataIndex: 'unitPrice',
|
||
},
|
||
{
|
||
title: '统一目录名称',
|
||
dataIndex: 'directoryName',
|
||
},
|
||
{
|
||
title: '统一目录编码',
|
||
dataIndex: 'directoryCode',
|
||
},
|
||
];
|
||
|
||
useEffect(() => {
|
||
|
||
init();
|
||
|
||
setTimeout(() => {
|
||
//项目已结束
|
||
if (overFlagRef.current) {
|
||
return;
|
||
}
|
||
ref.current = setInterval(() => {
|
||
getRedisBidData(tpId).then(res => {
|
||
res = res !== null ? res : {};
|
||
if (res.code === 200) {
|
||
let data = res.data;
|
||
timedRefreshData(data);
|
||
if (Number(data.jssj) <= 0) {
|
||
setOverFlag(true);
|
||
clearInterval(ref.current);
|
||
}
|
||
} else {
|
||
// clearInterval(ref.current);
|
||
}
|
||
})
|
||
|
||
}, timingInterval);
|
||
|
||
}, timingInterval);
|
||
|
||
}, []);
|
||
|
||
|
||
const reloadData = () => {
|
||
getRedisBidData(tpId).then(res => {
|
||
if (res.code === 200) {
|
||
let data = res.data;
|
||
timedRefreshData(data);
|
||
if (Number(data.jssj) <= 0) {
|
||
setOverFlag(true);
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
const timedRefreshData = (data: any) => {
|
||
let participateData = [data.cpr, data.cjcs, data.wgr];
|
||
getParticipateData(participateData);
|
||
setCjDataSource(data.cjjl);
|
||
setCurrentPrice(data.zgjg);
|
||
setDelay(data.yscs);
|
||
setCountDownTime(data.jssj);
|
||
setStartFlag(data.bidOpeningStatus != "0");
|
||
}
|
||
/**
|
||
* 倒计时结束
|
||
*/
|
||
const countDownOver = () => {
|
||
setOverFlag(true);
|
||
}
|
||
|
||
const getParticipateData = (arr: any[]) => {
|
||
setParticipateData(
|
||
<>
|
||
<span>{arr[0]}人参拍</span>
|
||
<span>{arr[1]}次出价</span>
|
||
<span>{arr[2]}人围观</span>
|
||
</>
|
||
)
|
||
}
|
||
|
||
/**
|
||
* 初始化
|
||
*/
|
||
const [range, rangeSet] = useState<any>(0)//加价幅度
|
||
const init = () => {
|
||
getAuctionViewAuctions(tpId).then(res => {
|
||
if (res.code === 200) {
|
||
let data = res.data;
|
||
//判断项目是否结束
|
||
if (data.yczt) {
|
||
setOverFlag(data.yczt);
|
||
overFlagRef.current = data.yczt;
|
||
}
|
||
//项目是否开始
|
||
setStartFlag(data.bidOpeningStatus != "0");
|
||
findFile(data.gg.auctionBdwxcdfzp)
|
||
setProjectName(data.xm.auction.projectName);
|
||
setCurrentPrice(data.inner02_04);
|
||
let participateData = [data.inner02_03.cprsl, data.inner02_03.xmcjcs, data.inner02_03.wgrsl];
|
||
getParticipateData(participateData);
|
||
setDelay(data.inner02_02.yscs);
|
||
setCjDataSource(data.tab03_01);
|
||
//状态 0围观 1 参拍
|
||
setViewStatus(data.cprdm !== null ? '1' : '0');
|
||
setStartingPrice(
|
||
<>
|
||
<span>起拍价:¥{digitalConversionAmount(String(data.gg.auctionJpjg), 2)}</span>
|
||
<span>加价幅度:¥{digitalConversionAmount(String(data.gg.auctionJjfd), 2)}</span>
|
||
<span>延时周期:{data.gg.auctionYszq}分钟/次</span>
|
||
</>
|
||
);
|
||
rangeSet(Number(data.gg.auctionJjfd));//幅度
|
||
// offerAPriceSet(Number(data.inner02_04));//出价
|
||
//公告数据
|
||
setNoticeData(
|
||
<div style={{ paddingLeft: '25px' }}>
|
||
<span dangerouslySetInnerHTML={{ __html: data.gg.htmlContent }}></span>
|
||
<br />
|
||
<br />
|
||
<br />
|
||
<span>竞拍公告附件:
|
||
<ExtendUpload bid={data.gg.auctionGgfj} btnName="附件" uploadProps={{ disabled: true }} />
|
||
</span>
|
||
</div>
|
||
)
|
||
setAuctionMaterialsList(data.xm.auctionMaterialsList);
|
||
subjectMatterIntroductionForm.setFieldsValue(data.gg);
|
||
setSubjectMatterIntroductionBid(data.gg.auctionBdwqdfj);
|
||
setLocationOfTheSubjectMatter(
|
||
<>
|
||
<li>标的物所在地:<span className="col333">{data.gg.auctionBdwwz}</span></li>
|
||
<li>挂拍方:<span className="col333">{data.gg.auctionGpf}</span></li>
|
||
<li>联系人:<span className="col333">{data.gg.auctionLxr}</span></li>
|
||
<li>联系电话:<span className="col333">{data.gg.auctionLxdh}</span></li>
|
||
</>
|
||
)
|
||
setEndTime(data.gg.auctionJpjssj);
|
||
setStartTime(data.gg.auctionJpkssj);
|
||
setCountDownTime(data.jpjssjTime);
|
||
setAuctionData(data);
|
||
//围观+1
|
||
if (data.cprdm == null && data.bidOpeningStatus != "0") {//开始后未报名的才算围观
|
||
updatetOnlookers(tpId).then(res => {
|
||
|
||
});
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
const findFile = (id: string) => {
|
||
getFilelist([id]).then(res => {
|
||
let arr = []
|
||
if (res?.success && res?.data.length > 0) {
|
||
for (const item of res?.data) {
|
||
arr.push(pictureDisplayPath + '?filePath=' + item.filePath);
|
||
}
|
||
}
|
||
setAuctionImage(arr);
|
||
setAuctionImageFlag(true);
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 出价
|
||
*/
|
||
const [offerAPrice, offerAPriceSet] = useState<any>('');
|
||
const onSearch = () => {
|
||
let value: any = Number(offerAPrice);
|
||
if (isEmpty(value)) {
|
||
message.info('请出价!');
|
||
return;
|
||
}
|
||
|
||
if (!amountMoney.test(value)) {
|
||
message.info('请输入正确的格式(小数点前15位,小数点后2位)!');
|
||
return;
|
||
}
|
||
if (Number(value) <= Number(currentPrice)) {
|
||
message.info('请输入高于当前价的金额!');
|
||
return;
|
||
}
|
||
// let differ = (Number(value) - Number(currentPrice)) % range
|
||
// let differ = (value * 1000 - currentPrice * 1000) % (range * 1000)
|
||
// if (differ !== 0) {
|
||
// message.info('请增加加价幅度整数倍的金额!');
|
||
// return;
|
||
// }
|
||
//出价
|
||
confirmBidOrNot(tpId, value);
|
||
}
|
||
|
||
|
||
/**
|
||
* 确认出价
|
||
* @param tpId
|
||
* @param value
|
||
*/
|
||
const confirmBidOrNot = (tpId: any, value: any) => {
|
||
const orderBidPrice = (tpId: any, value: any) => {
|
||
//出价
|
||
putOrderBidPrice(tpId, value).then(res => {
|
||
if (res.code === 200) {
|
||
let data = res.data;
|
||
if (data) {
|
||
message.success('出价成功!');
|
||
}
|
||
reloadData();
|
||
}
|
||
})
|
||
}
|
||
Modal.confirm({
|
||
content: "请确认出价",
|
||
okText: '确认',
|
||
cancelText: '取消',
|
||
keyboard: false,
|
||
centered: true,
|
||
onCancel: () => { },
|
||
onOk: () => orderBidPrice(tpId, value)
|
||
});
|
||
}
|
||
/**
|
||
* 我要参拍
|
||
*/
|
||
const toParticipate = () => {
|
||
if (isParticipant()) {//有权限
|
||
setIsModalVisible(true);
|
||
form.setFieldsValue({
|
||
"organizationName": userData.organizationName,
|
||
"biddersCpr": userData.fullName,
|
||
});
|
||
} else {
|
||
message.info("您好,您不具有参拍人权限,无法参与竞拍出价,您可联系省分接口人配置参拍权限。");
|
||
}
|
||
}
|
||
//参与竞拍
|
||
const handleOk = () => {
|
||
form.validateFields().then(values => {
|
||
const fromData = {
|
||
"auctionId": tpId,
|
||
"biddersCpr": form.getFieldValue("biddersCpr"),
|
||
"biddersLxdh": form.getFieldValue("biddersLxdh"),
|
||
"biddersFj": form.getFieldValue("biddersFj"),
|
||
"biddersBs": 0
|
||
}
|
||
setLoading(true);
|
||
insertBidders(fromData).then(res => {
|
||
if (res != null && res.message == "success") {
|
||
message.success("参与竞拍成功!");
|
||
init();
|
||
setIsModalVisible(false);
|
||
}
|
||
}).finally(() => {
|
||
setLoading(false);
|
||
});
|
||
})
|
||
};
|
||
|
||
const handleCancel = () => {
|
||
setIsModalVisible(false);
|
||
};
|
||
//判断当前登录人是否有参拍人角色
|
||
const isParticipant = () => {
|
||
if (userData.authorityList?.length > 0) {
|
||
for (const ite of userData.authorityList) {
|
||
if (ite.roleCode == "ebtp-auction-participant") {//参拍人角色
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
return (
|
||
<Spin spinning={loading}>
|
||
<div className="htmlWrap">
|
||
{
|
||
auctionImageFlag && <AuctionImage image={auctionImage} />
|
||
}
|
||
<div className="contentParts">
|
||
{/* <!--核心区域--> */}
|
||
<div className="mainText">
|
||
<h4>{projectName}</h4>
|
||
{/* <!--stateRed是正在进行的状态样式,去掉stateRed是竞拍结束状态样式--> */}
|
||
<div className={overFlag || !startFlag ? 'stateBlock' : 'stateBlock stateRed'}>
|
||
|
||
{
|
||
overFlag ? (
|
||
<>
|
||
<span className="stateIco">竞拍结束</span>
|
||
<span className="staeTime">
|
||
结束时间:{endTime}(延时{delay}次)
|
||
</span>
|
||
</>
|
||
) : startFlag ? (
|
||
<>
|
||
<span className="stateIco">正在进行</span>
|
||
<span className="staeTime">
|
||
距离结束仅剩:
|
||
<CountDownUtils countDown={countDownTime} countDownOver={() => countDownOver()} />(延时{delay}次)
|
||
</span>
|
||
|
||
</>
|
||
) : (
|
||
<>
|
||
<span className="stateIco">未开始</span>
|
||
<span className="staeTime">
|
||
开始时间:{startTime}
|
||
</span>
|
||
</>
|
||
)
|
||
}
|
||
<p>
|
||
{participateData}
|
||
</p>
|
||
</div>
|
||
<div className="priceBlock">
|
||
{overFlag ? '最终价:' : '当前价:'}<span>¥{digitalConversionAmount(String(currentPrice), 2)}</span>
|
||
</div>
|
||
{
|
||
!overFlag && (
|
||
viewStatus === '1' ? (
|
||
startFlag ? (<div className="saleBlock">
|
||
<>
|
||
请出价:<span>¥</span>
|
||
<Input type="text" maxLength={15} value={offerAPrice} autoComplete='off'
|
||
onChange={(e) => offerAPriceSet(e.target.value)}
|
||
/>
|
||
<button type="button" onClick={onSearch} style={{ marginLeft: 8 }}>出价</button>
|
||
<button type="button" style={{ marginLeft: 8 }} onClick={() => {
|
||
let count: number = 0;
|
||
if (!Number(offerAPrice)) {
|
||
count = algebraicAddition(currentPrice, range);
|
||
offerAPriceSet(count);
|
||
} else {
|
||
count = algebraicAddition(offerAPrice, range);
|
||
offerAPriceSet(count);
|
||
}
|
||
message.success(`加价${range},当前价格为${count}`);
|
||
}}>+{range}</button>
|
||
|
||
</>
|
||
</div>) : (
|
||
<div className="auction-not-started">
|
||
<span>您已报名参拍,竞拍未开始!</span>
|
||
</div>
|
||
)
|
||
) : (
|
||
<div style={{ marginBottom: 12 }}>
|
||
<Button type='primary' key="participate" onClick={() => toParticipate()}>我要参拍</Button>
|
||
</div>
|
||
)
|
||
)
|
||
}
|
||
<div className="otherInform">
|
||
{startingPrice}
|
||
{
|
||
viewStatus === '1' && isParticipant() && startFlag && <span>竞拍代码:{auctionData?.cprdm}</span>
|
||
}
|
||
</div>
|
||
</div>
|
||
<div className="rightInform">
|
||
<ul>
|
||
{locationOfTheSubjectMatter}
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
<Divider />
|
||
<Row>
|
||
<Col span={24}>
|
||
<Tabs defaultActiveKey="1" size={'large'} centered>
|
||
<TabPane tab="竞拍公告" key="1">
|
||
<Divider>竞拍公告</Divider>
|
||
{noticeData}
|
||
</TabPane>
|
||
<TabPane tab="标的物介绍" key="2">
|
||
<Divider>标的物介绍</Divider>
|
||
<Form form={subjectMatterIntroductionForm} labelCol={{ span: 3 }}>
|
||
<Form.Item
|
||
label="标的物介绍"
|
||
name="auctionBdwjs">
|
||
<Input bordered={false} readOnly />
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label="标的物预估重量(kg)"
|
||
name="auctionBdwygzl">
|
||
<Input bordered={false} readOnly />
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label="标的物预估体积(m³)"
|
||
name="auctionBdwygtj">
|
||
<Input bordered={false} readOnly />
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label="标的物账面价值(元)"
|
||
name="auctionBdwzmjz">
|
||
<Input bordered={false} readOnly />
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label="标的物在库时间(天)"
|
||
name="auctionBdwzksj">
|
||
<Input bordered={false} readOnly />
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label="标的物位置"
|
||
name="auctionBdwwz">
|
||
<Input bordered={false} readOnly />
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label="详细地址"
|
||
name="auctionBy4">
|
||
<Input bordered={false} readOnly />
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
label="标的物清单附件"
|
||
name="auctionBdwqdfj">
|
||
<ExtendUpload bid={subjectMatterIntroductionBid} btnName="附件" uploadProps={{ disabled: true }} />
|
||
</Form.Item>
|
||
|
||
{/* <Form.Item
|
||
label="物资清单"
|
||
>
|
||
<ProTable
|
||
dataSource={auctionMaterialsList}
|
||
columns={wzColumns}
|
||
pagination={false}
|
||
search={false}
|
||
options={false}
|
||
rowKey="id"
|
||
/>
|
||
</Form.Item> */}
|
||
<ProTable
|
||
headerTitle="物资清单"
|
||
dataSource={auctionMaterialsList}
|
||
columns={wzColumns}
|
||
pagination={false}
|
||
search={false}
|
||
options={false}
|
||
rowKey="id"
|
||
/>
|
||
</Form>
|
||
</TabPane>
|
||
<TabPane tab="出价记录" key="3">
|
||
<Divider>出价记录</Divider>
|
||
<ProTable
|
||
dataSource={cjDataSource}
|
||
columns={cjColumns}
|
||
search={false}
|
||
options={false}
|
||
pagination={{ defaultPageSize: 10 }}
|
||
rowKey="id"
|
||
/>
|
||
</TabPane>
|
||
</Tabs>
|
||
</Col>
|
||
</Row>
|
||
<Modal
|
||
title="我要参拍"
|
||
destroyOnClose
|
||
centered
|
||
visible={isModalVisible}
|
||
onOk={handleOk}
|
||
onCancel={handleCancel}
|
||
okButtonProps={{
|
||
loading: loading,
|
||
}}
|
||
width={600}
|
||
>
|
||
<Spin spinning={loading}>
|
||
<Form
|
||
{...layout}
|
||
name="basic"
|
||
form={form}
|
||
>
|
||
<Form.Item
|
||
label="参拍方"
|
||
name="organizationName"
|
||
>
|
||
<Input disabled={true} />
|
||
</Form.Item>
|
||
<Form.Item
|
||
label="参拍人"
|
||
name="biddersCpr"
|
||
rules={[{ required: true, message: '请填写此项' }]}
|
||
>
|
||
<Input />
|
||
</Form.Item>
|
||
<Form.Item
|
||
label="联系电话"
|
||
name="biddersLxdh"
|
||
rules={[
|
||
{
|
||
pattern: /^[1][3,4,5,6,7,8,9][0-9]{9}$/,
|
||
message: '请输入正确的手机号'
|
||
}
|
||
]}
|
||
>
|
||
<Input />
|
||
</Form.Item>
|
||
<Form.Item
|
||
label="附件"
|
||
name="biddersFj"
|
||
extra="最多上传一个文件,每个最大30MB"
|
||
>
|
||
<ExtendUpload bid="" maxCount={1} maxSize={30} uploadProps={{ disabled: false, accept: ".png,.jpg,.jpeg,.rar,.zip,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt,.pdf" }}>
|
||
</ExtendUpload>
|
||
</Form.Item>
|
||
</Form>
|
||
</Spin>
|
||
</Modal>
|
||
</div>
|
||
|
||
|
||
</Spin>
|
||
)
|
||
}
|
||
export default AuctionViewAuctions; |