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

Merge branch 'dev-srm' of http://10.0.0.22:3000/lingxi/lingxi-business-paltform into dev-srm

parents feb7bf8f 9c115fd5
...@@ -26,12 +26,10 @@ const BidDetailLayout: React.FC<BidDetailLayoutProps> = (props: any) => { ...@@ -26,12 +26,10 @@ const BidDetailLayout: React.FC<BidDetailLayoutProps> = (props: any) => {
const { awardProcess = [], isOpenPurchase, isOpenRanking } = detail; const { awardProcess = [], isOpenPurchase, isOpenRanking } = detail;
const [showMore, setShowMore] = useState<boolean>(false); const [showMore, setShowMore] = useState<boolean>(false);
const [activeItem, setActiveItem] = useState<any>(awardProcess?.[0] || { detailss: [] }); const [activeItem, setActiveItem] = useState<any>(awardProcess?.[0] || { detailss: [] });
const [activeIndex, setActiveIndex] = useState<any>(awardProcess?.[0] || { detailss: [] });
const dataSource = showMore ? [...activeItem.detailss].splice(0, 4) : activeItem.detailss; const dataSource = showMore ? [...activeItem.detailss].splice(0, 4) : activeItem.detailss;
useEffect(() => { useEffect(() => {
awardProcess && setActiveItem(awardProcess?.[0] || { detailss: [] }) awardProcess && setActiveItem(awardProcess?.[0] || { detailss: [] });
awardProcess && setActiveIndex(awardProcess?.[0] ? 0 : '')
}, [detail]) }, [detail])
const columns: ColumnType<any>[] = [ const columns: ColumnType<any>[] = [
...@@ -46,9 +44,9 @@ const BidDetailLayout: React.FC<BidDetailLayoutProps> = (props: any) => { ...@@ -46,9 +44,9 @@ const BidDetailLayout: React.FC<BidDetailLayoutProps> = (props: any) => {
</Space> </Space>
) )
}, },
{ title: '规格型号',key: 'model', dataIndex: 'model', }, { title: '规格型号', key: 'model', dataIndex: 'model', },
{ title: '品类',key: 'category', dataIndex: 'category', }, { title: '品类', key: 'category', dataIndex: 'category', },
{ title: '品牌',key: 'brand', dataIndex: 'brand', }, { title: '品牌', key: 'brand', dataIndex: 'brand', },
{ {
title: '采购数量/单位', title: '采购数量/单位',
dataIndex: 'unit', dataIndex: 'unit',
...@@ -85,11 +83,10 @@ const BidDetailLayout: React.FC<BidDetailLayoutProps> = (props: any) => { ...@@ -85,11 +83,10 @@ const BidDetailLayout: React.FC<BidDetailLayoutProps> = (props: any) => {
}, },
] ]
const chooseItem = (item: any, index: number) => { const chooseItem = (item: any) => {
if (index !== activeIndex) { if (item.peportTime !== activeItem?.peportTime) {
setShowMore(false); setShowMore(false);
setActiveItem(item); setActiveItem(item);
setActiveIndex(index)
} }
} }
...@@ -103,13 +100,15 @@ const BidDetailLayout: React.FC<BidDetailLayoutProps> = (props: any) => { ...@@ -103,13 +100,15 @@ const BidDetailLayout: React.FC<BidDetailLayoutProps> = (props: any) => {
<Row gutter={[8, 8]} style={{ marginBottom: '10px' }}> <Row gutter={[8, 8]} style={{ marginBottom: '10px' }}>
{awardProcess?.map((item, index, arr) => { {awardProcess?.map((item, index, arr) => {
let _ratio = 0; let _ratio = 0;
let _arrLength = arr.length; const _arrLength = arr.length;
if (index != _arrLength - 1 && _arrLength > 2) { if (btnType === 2) {
_ratio = Number(((item.sumPice - arr[index + 1].sumPice) / arr[index + 1].sumPice * 100).toFixed(2)) if (index != _arrLength - 1 && _arrLength > 2) {
_ratio = Number(((item.sumPice - arr[index + 1].sumPice) / arr[index + 1].sumPice * 100).toFixed(2))
}
} }
return ( return (
<Col span={7} key={`${item.id}_${item.peportTime}`} onClick={() => { chooseItem(item, index) }}> <Col span={7} key={`${item.id}_${item.peportTime}`} onClick={() => { chooseItem(item) }}>
<BtnItem btnType={btnType} detail={{ ...item, isOpenPurchase, isOpenRanking, ratio: _ratio }} active={index === activeIndex} /> <BtnItem btnType={btnType} detail={{ ...item, isOpenPurchase, isOpenRanking, ratio: _ratio, selfRanking: index+1 }} active={item.peportTime === activeItem?.peportTime} />
</Col> </Col>
) )
})} })}
......
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState, useRef, useCallback } from 'react';
import { history } from 'umi'; import { history } from 'umi';
import { Row, Col } from 'antd'; import { Row, Col } from 'antd';
import { ArrowLeftOutlined } from '@ant-design/icons'; import { ArrowLeftOutlined } from '@ant-design/icons';
...@@ -6,6 +6,8 @@ import { ArrowLeftOutlined } from '@ant-design/icons'; ...@@ -6,6 +6,8 @@ import { ArrowLeftOutlined } from '@ant-design/icons';
import { PublicApi } from '@/services/api'; import { PublicApi } from '@/services/api';
import { priceFormat } from '@/utils/numberFomat'; import { priceFormat } from '@/utils/numberFomat';
import { formatTimeString } from '@/utils' import { formatTimeString } from '@/utils'
import { getAuth } from '@/utils/auth';
import { SOCKET_URL } from '@/constants';
import StatusBox from '../../../purchaseBid/readyBid/management/components/statusBox'; import StatusBox from '../../../purchaseBid/readyBid/management/components/statusBox';
import QuotationDeskLayout from '../../../components/detail/components/quotationDeskLayout'; import QuotationDeskLayout from '../../../components/detail/components/quotationDeskLayout';
...@@ -30,7 +32,45 @@ const Detail = () => { ...@@ -30,7 +32,45 @@ const Detail = () => {
const [dataSource, setDataSource] = useState<any>({}); const [dataSource, setDataSource] = useState<any>({});
const [chartsList, setChartsList] = useState<any>([]); const [chartsList, setChartsList] = useState<any>([]);
const fetchDataSource = async () => { const userInfo = getAuth();
const ws = useRef<WebSocket | null>(null);
const webSocketInit = useCallback(() => {
if (SOCKET_URL && (!ws.current || ws.current.readyState === 3) && userInfo) {
const url = `${SOCKET_URL}/message/websocket?memberId=${userInfo.memberId}&roleId=${userInfo.memberRoleId}&token=${userInfo.token}&source=${1}`;
console.log(url)
ws.current = new WebSocket(url);
// ws.current.onopen = (e) => {}
ws.current.onmessage = (e) => {
const data = JSON.parse(e.data);
console.log(data)
const _data = data.data;
if(data.action === 'purchase_bidding_message_supplier' && _data.id == onlineId){
const _obj = {
ranking: _data.ranking,
minLowPrice : _data.minPrice,
quotationDesks : _data.awardProcesss
}
fetchDataSource(_obj);
}
};
ws.current.onclose = (e) => {
console.log("关闭连接")
}
ws.current.onerror = (e) => {
console.log("socket 出错")
}
}
}, [ws]);
useEffect(() => {
webSocketInit();
return () => {
ws.current?.close();
};
}, [ws, webSocketInit]);
const fetchDataSource = async (socketObj?: any) => {
const params = { const params = {
id, id,
number, number,
...@@ -43,19 +83,28 @@ const Detail = () => { ...@@ -43,19 +83,28 @@ const Detail = () => {
return; return;
} }
const { data } = res; const { data } = res;
let _flag = false;
if(socketObj){
_flag = true;
data.ranking = socketObj.ranking;
data.minLowPrice = socketObj.minLowPrice;
}
data.onlineId = Number(onlineId); data.onlineId = Number(onlineId);
setDataSource(data); setDataSource(data);
let _list = []; let _list = [];
let _offerList = []; let _offerList = [];
let _minList = []; let _minList = [];
let _quotationDesks = data?.quotationDesks ? [...data.quotationDesks].reverse() : []; let _quotationDesks = data?.quotationDesks ? [...data.quotationDesks].reverse() : [];
if(_flag){
_quotationDesks = socketObj.quotationDesks.filter((item) => item.id == onlineId)
}
_quotationDesks.forEach((item) => { _quotationDesks.forEach((item) => {
_offerList.push({ type: 'offer', time: formatTimeString(item.offerTime, 'HH:mm:ss'), value: priceFormat(item.price,0) }); _offerList.push({ type: 'offer', time: formatTimeString(item.offerTime || item.peportTime, 'HH:mm:ss'), value: priceFormat(item.price || item.sumPice,0) });
}) })
_list.push({ title: '报价金额', type: 'offer', list: _offerList }); _list.push({ title: '报价金额', type: 'offer', list: _offerList });
if (data.isOpenPurchase) { if (data.isOpenPurchase) {
_quotationDesks.forEach((item) => { _quotationDesks.forEach((item) => {
_minList.push({ type: 'min', time: formatTimeString(item.offerTime, 'HH:mm:ss'), value: priceFormat(item.minPrice,0) }); _minList.push({ type: 'min', time: formatTimeString(item.offerTime || item.peportTime, 'HH:mm:ss'), value: priceFormat(item.minPrice,0) });
}) })
_list.push({ title: '最低价', type: 'min', list: _minList }); _list.push({ title: '最低价', type: 'min', list: _minList });
} }
......
...@@ -43,7 +43,7 @@ const RankRow: React.FC<RankRowProps> = (props: any) => { ...@@ -43,7 +43,7 @@ const RankRow: React.FC<RankRowProps> = (props: any) => {
<div className={styles.rankRowLeftTop}> <div className={styles.rankRowLeftTop}>
{_returnBadge(detail.ranking)} {_returnBadge(detail.ranking)}
{detail.memberName} {detail.memberName}
{detail.ranking === 1 && <TriangleTag text='最低价' wrapStyle={{ backgroundColor: '#EA8000', position: 'absolute', right: '0' }} bgcolor='#EA8000' direction='left' />} {detail.ranking === 1 && <TriangleTag text='最低价' wrapStyle={{ backgroundColor: '#EA8000', marginLeft: '8px' }} bgcolor='#EA8000' direction='left' />}
</div> </div>
<div className={styles.rankRowLeftBottom}> <div className={styles.rankRowLeftBottom}>
¥{priceFormat(detail.sumPrice)} ¥{priceFormat(detail.sumPrice)}
......
import React, { useState, useEffect, useMemo } from 'react'; import React, { useState, useEffect, useMemo } from 'react';
import { history } from 'umi';
import { Row, Col, Input, Drawer, Table, Space, Typography, message } from 'antd'; import { Row, Col, Input, Drawer, Table, Space, Typography, message } from 'antd';
import { ColumnType } from 'antd/lib/table/interface'; import { ColumnType } from 'antd/lib/table/interface';
...@@ -35,6 +34,7 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => { ...@@ -35,6 +34,7 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => {
{ {
title: '物料编号/名称', title: '物料编号/名称',
dataIndex: 'number', dataIndex: 'number',
key: 'number',
render: (text: any, record: any) => ( render: (text: any, record: any) => (
<Space direction='vertical'> <Space direction='vertical'>
<Text type='secondary' key={'number_1'} >{text}</Text> <Text type='secondary' key={'number_1'} >{text}</Text>
...@@ -42,12 +42,13 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => { ...@@ -42,12 +42,13 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => {
</Space> </Space>
) )
}, },
{ title: '规格型号', dataIndex: 'model', }, { title: '规格型号', key: 'model', dataIndex: 'model', },
{ title: '品类', dataIndex: 'category', }, { title: '品类', key: 'category', dataIndex: 'category', },
{ title: '品牌', dataIndex: 'brand', }, { title: '品牌', key: 'brand', dataIndex: 'brand', },
{ {
title: '采购数量/单位', title: '采购数量/单位',
dataIndex: 'unit', dataIndex: 'unit',
key: 'unit',
render: (text: any, record: any) => ( render: (text: any, record: any) => (
<Space direction='vertical'> <Space direction='vertical'>
<Text type='secondary' key={'unit_1'} >{record.purchaseCount}</Text> <Text type='secondary' key={'unit_1'} >{record.purchaseCount}</Text>
...@@ -58,16 +59,19 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => { ...@@ -58,16 +59,19 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => {
{ {
title: '含税/税率', title: '含税/税率',
dataIndex: 'isTax', dataIndex: 'isTax',
key: 'isTax',
render: (text: any, record: any) => <Input value={record.taxRate} onChange={(e) => { _changeTax(record, e.target.value) }} addonAfter="%" /> render: (text: any, record: any) => <Input value={record.taxRate} onChange={(e) => { _changeTax(record, e.target.value) }} addonAfter="%" />
}, },
{ {
title: '单价(含税)', title: '单价(含税)',
dataIndex: 'unitPrice', dataIndex: 'unitPrice',
key: 'unitPrice',
render: (text: any, record: any) => <Input value={record.unitPrice} onChange={(e) => { _changeUnitPrice(record, e.target.value) }} addonBefore="¥" /> render: (text: any, record: any) => <Input value={record.unitPrice} onChange={(e) => { _changeUnitPrice(record, e.target.value) }} addonBefore="¥" />
}, },
{ {
title: '金额(含税)', title: '金额(含税)',
dataIndex: 'price', dataIndex: 'price',
key: 'price',
render: (text: any, record: any) => <Text type='secondary'>{text && `¥${priceFormat(text)}`}</Text> render: (text: any, record: any) => <Text type='secondary'>{text && `¥${priceFormat(text)}`}</Text>
}, },
] ]
...@@ -135,7 +139,7 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => { ...@@ -135,7 +139,7 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => {
} }
PublicApi.postPurchaseOnlineBiddingSubmitReportPrice(_params).then(res => { PublicApi.postPurchaseOnlineBiddingSubmitReportPrice(_params).then(res => {
if (res.code === 1000) { if (res.code === 1000) {
history.goBack(); onClose && onClose();
} }
}) })
} }
...@@ -158,13 +162,13 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => { ...@@ -158,13 +162,13 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => {
</Col> </Col>
{awardProcess?.map((item, index, arr) => { {awardProcess?.map((item, index, arr) => {
let _ratio = 0; let _ratio = 0;
let _arrLength = arr.length; const _arrLength = arr.length;
if (index != _arrLength - 1 && _arrLength > 2) { if (index != _arrLength - 1 && _arrLength > 2) {
_ratio = Number(((item.sumPice - arr[index + 1].sumPice) / arr[index + 1].sumPice * 100).toFixed(2)) _ratio = Number(((item.sumPice - arr[index + 1].sumPice) / arr[index + 1].sumPice * 100).toFixed(2))
} }
return ( return (
<Col span={7} key={`${item.id}_${item.peportTime}`} onClick={() => { chooseItem(item, index) }}> <Col span={7} key={`${item.id}_${item.peportTime}`} onClick={() => { chooseItem(item, index) }}>
<BtnItem btnType={2} detail={{ ...item, isOpenPurchase, isOpenRanking, ratio: _ratio }} active={index === activeIndex} /> <BtnItem btnType={2} detail={{ ...item, isOpenPurchase, isOpenRanking, ratio: _ratio, selfRanking: index + 1 }} active={index === activeIndex} />
</Col> </Col>
) )
})} })}
......
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState, useRef, useCallback } from 'react';
import { history } from 'umi'; import { history } from 'umi';
import { Row, Col } from 'antd'; import { Row, Col } from 'antd';
import { ArrowLeftOutlined } from '@ant-design/icons'; import { ArrowLeftOutlined } from '@ant-design/icons';
...@@ -6,6 +6,8 @@ import { ArrowLeftOutlined } from '@ant-design/icons'; ...@@ -6,6 +6,8 @@ import { ArrowLeftOutlined } from '@ant-design/icons';
import { PublicApi } from '@/services/api'; import { PublicApi } from '@/services/api';
import { formatTimeString } from '@/utils' import { formatTimeString } from '@/utils'
import { priceFormat } from '@/utils/numberFomat'; import { priceFormat } from '@/utils/numberFomat';
import { getAuth } from '@/utils/auth';
import { SOCKET_URL } from '@/constants';
import QuotationDeskLayout from '../../../components/detail/components/quotationDeskLayout'; import QuotationDeskLayout from '../../../components/detail/components/quotationDeskLayout';
import BidDetailLayout from '../../../components/detail/components/bidDetailLayout'; import BidDetailLayout from '../../../components/detail/components/bidDetailLayout';
...@@ -32,6 +34,53 @@ const Management = () => { ...@@ -32,6 +34,53 @@ const Management = () => {
const [awardProcess, setAwardProcess] = useState<any>([]); const [awardProcess, setAwardProcess] = useState<any>([]);
const [lowestList, setLowestList] = useState<any>({}); const [lowestList, setLowestList] = useState<any>({});
const userInfo = getAuth();
const ws = useRef<WebSocket | null>(null);
const webSocketInit = useCallback(() => {
if (SOCKET_URL && (!ws.current || ws.current.readyState === 3) && userInfo) {
const url = `${SOCKET_URL}/message/websocket?memberId=${userInfo.memberId}&roleId=${userInfo.memberRoleId}&token=${userInfo.token}&source=${1}`;
console.log(url)
ws.current = new WebSocket(url);
// ws.current.onopen = (e) => {}
ws.current.onmessage = (e) => {
const data = JSON.parse(e.data);
console.log(data)
const _data = data.data;
if (data.action === 'purchase_bidding_message' && _data.id == id) {
let _dynamic = { ...dynamic };
_dynamic.count = _data.count;
_dynamic.id = _data.id;
_dynamic.memberName = _data.memberName;
_dynamic.minPrice = _data.minPrice;
setDynamic(_dynamic);
setQueryPriceDynamics(_data.queryPriceDynamics);
setSignupMembers(_data.sginUpInfos);
setAwardProcess(_data.awardProcesss);
setLowestList({
type: 'min',
title: '最低价',
list: _data.awardProcesss ? _data.awardProcesss.map((item) => { return { type: 'min', time: formatTimeString(item.peportTime, 'HH:mm:ss'), value: priceFormat(item.sumPice, 0) } }) : []
})
}
};
ws.current.onclose = (e) => {
console.log(e)
console.log("关闭连接")
}
ws.current.onerror = (e) => {
console.log("socket 出错")
}
}
}, [ws]);
useEffect(() => {
webSocketInit();
return () => {
ws.current?.close();
};
}, [ws, webSocketInit]);
const fetchDataSource = async () => { const fetchDataSource = async () => {
const params = { const params = {
id, id,
...@@ -89,7 +138,7 @@ const Management = () => { ...@@ -89,7 +138,7 @@ const Management = () => {
setLowestList({ setLowestList({
type: 'min', type: 'min',
title: '最低价', title: '最低价',
list: data ? data.map((item) => { return { type: 'min', time: formatTimeString(item.peportTime, 'HH:mm:ss'), value: priceFormat(item.sumPice,0) } }) : [] list: data ? data.map((item) => { return { type: 'min', time: formatTimeString(item.peportTime, 'HH:mm:ss'), value: priceFormat(item.sumPice, 0) } }) : []
}) })
}) })
} }
......
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