5.16 内拍改造

This commit is contained in:
jl-zhoujl2
2022-05-16 16:22:57 +08:00
parent 216d65fe55
commit a5d48fc999
8 changed files with 1106 additions and 18 deletions

View File

@ -0,0 +1,639 @@
/*
* @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 { 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, getSessionRoleData, 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 = 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 [countDownTime, setCountDownTime] = useState<any>(null);
//结束时间
const [endTime, setEndTime] = 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);
}
/**
* 倒计时结束
*/
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 = () => {
const roleID = getSessionRoleData().roleId;
getAuctionViewAuctions(tpId).then(res => {
if (res.code === 200) {
let data = res.data;
//判断项目是否结束
if (data.yczt) {
setOverFlag(data.yczt);
overFlagRef.current = data.yczt;
}
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>
{
data.cprdm !== null && roleID === '20003' && <span>{data.cprdm}</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);
setCountDownTime(data.jpjssjTime);
//围观+1
if (data.cprdm == null) {
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 = () => {
setIsModalVisible(true);
form.setFieldsValue({
"organizationName": userData.organizationName,
"biddersCpr": userData.fullName,
});
}
//参与竞拍
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("参与竞拍成功!");
setViewStatus('1');
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 ? 'stateBlock' : 'stateBlock stateRed'}>
{
overFlag ? (
<>
<span className="stateIco"></span>
<span className="staeTime">
&nbsp;{endTime}{delay}
</span>
</>
) : (
<>
<span className="stateIco"></span>
<span className="staeTime">
&nbsp;
<CountDownUtils countDown={countDownTime} countDownOver={() => countDownOver()} />{delay}
</span>
</>
)
}
<p>
{participateData}
</p>
</div>
<div className="priceBlock">
{overFlag ? '最终价:' : '当前价:'}<span>{digitalConversionAmount(String(currentPrice), 2)}</span>
</div>
{
(!overFlag && isParticipant()) && (
viewStatus === '1' ? (
<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 style={{ marginBottom: 12 }}>
<Button type='primary' key="participate" onClick={() => toParticipate()}></Button>
</div>
)
)
}
<div className="otherInform">
{startingPrice}
</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="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 }}>
</ExtendUpload>
</Form.Item>
</Form>
</Spin>
</Modal>
</div>
</Spin>
)
}
export default AuctionViewAuctions;