Files
fe_service_ebtp_frontend/src/pages/Auction/AuctionParticipateDetail/components/AuctionViewAuctions.tsx
2022-07-07 09:51:25 +08:00

669 lines
27 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* @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">
&nbsp;{endTime}{delay}
</span>
</>
) : startFlag ? (
<>
<span className="stateIco"></span>
<span className="staeTime">
&nbsp;
<CountDownUtils countDown={countDownTime} countDownOver={() => countDownOver()} />{delay}
</span>
</>
) : (
<>
<span className="stateIco"></span>
<span className="staeTime">
&nbsp;{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;