Commit 3d2db24c authored by XieZhiXiong's avatar XieZhiXiong

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

parents 5e1adeb7 ee3581ab
......@@ -47,16 +47,18 @@ const readySubmitReportDetail: React.FC = () => {
console.log(submitData)
const {fileList, recommandList, childTableData} = submitData
let params: any = { id }
if(recommandList && recommandList.length) {
params.evaluationTenderRecommendList = recommandList.filter(item => !item?.id)
}
params.evaluationTenderFile = fileList
params.evaluationTenderReportMemberList = childTableData[0].map(item => ({ memberId: item.memberId, correctScore: item.total }))
PublicApi.postPurchaseExpertExtractReportSubmitEvaluationTenderReport(params).then(res => {
setLoading(true)
if(res.code === 1000) {
history.goBack()
} else {
setLoading(false)
}
}).finally(() => {
setLoading(false)
})
}
......
......@@ -12,7 +12,6 @@ import {
View,
} from 'bizcharts';
import Interval from 'bizcharts/lib/geometry/Interval'
import DataSet from "@antv/data-set";
import { BidInStateTexts, BidOuterWorkState, BidOutStateTexts, PURCHASE_TYPE, TenderInStateTexts, TenderOutStateTexts } from '@/constants';
import { PublicApi } from '@/services/api';
import moment from 'moment';
......@@ -312,7 +311,7 @@ const DescriptionsInfo: React.FC<BasicInfoProps> = ({cardTitle, type}) => {
span: 8,
fieldList: [
{ title: '是否在线评标:', name: 'isOnlineEvaluation', render: (text) => text ? '是' : '否' },
{ title: '评标项模板:', name: 'templateId' },
{ title: '评标项模板:', name: 'templateName' },
]
},
]
......@@ -346,6 +345,9 @@ const DescriptionsInfo: React.FC<BasicInfoProps> = ({cardTitle, type}) => {
/** 投标区块 **/
// @todo 中标结果 根据后端数据控制
const result = _data.isWin
const sumPrice = _data?.submitTender ? _data.submitTender.submitTenderMateriel.reduce((a, b) => a + b.price * b.inviteTenderMateriel.count, 0) : 0
const alreadyPay = _data?.submitTender ? _data.submitTender.submitTenderMateriel.reduce((a, b) => a + b.price * b.inviteTenderMateriel.count * b.awardTenderRatio/100, 0) : 0
console.log(sumPrice, alreadyPay, 'aaa')
const bidResultList = [
{
span: 8,
......@@ -356,11 +358,11 @@ const DescriptionsInfo: React.FC<BasicInfoProps> = ({cardTitle, type}) => {
name: 'createTime',
render: (text, record) => <Row justify='space-between'>
<Col style={{margin: "0 16px"}}>
<CircleChart sumPrice={record.sumPrice} alreadyPay={record.alreadyPay} />
<CircleChart sumPrice={sumPrice} alreadyPay={alreadyPay} />
</Col>
<Col>
<div><span className={style['card-list_title']}>中标金额(含税):</span></div>
<div><span>{record.alreadyPay || 0}</span></div>
<div><span>{alreadyPay}</span></div>
</Col>
</Row>,
},
......@@ -456,24 +458,17 @@ const DescriptionsInfo: React.FC<BasicInfoProps> = ({cardTitle, type}) => {
// 圆形环状金额显示
const CircleChart = props => {
const { sumPrice = 100, alreadyPay = 10 } = props
const { DataView } = DataSet;
const userData = [
{ type: '总金额', value: (sumPrice - alreadyPay) || 100 },
{ type: '已支付', value: alreadyPay }
{ type: '总金额', value: sumPrice-alreadyPay, percent: Math.round((sumPrice-alreadyPay) / sumPrice)/ 100.00 },
{ type: '已支付', value: alreadyPay, percent: Math.round(alreadyPay / sumPrice)/ 100.00 }
];
const userDv = new DataView();
userDv.source(userData).transform({
type: 'percent',
field: 'value',
dimension: 'type',
as: 'percent',
});
console.log(userData, 'ggg')
return <Chart placeholder={false} height={64} width={64} style={{position: "relative"}} autoFit>
<Legend visible={false} />
{/* 绘制图形 */}
<View data={userDv.rows}>
<View data={userData}>
<Coordinate type="theta" innerRadius={0.75} />
<Interval
position="percent"
......@@ -481,7 +476,11 @@ const DescriptionsInfo: React.FC<BasicInfoProps> = ({cardTitle, type}) => {
color={['type', ['#ffc400', '#6c9ceb']]}
tooltip={false}
/>
<p style={{position: "absolute", top: "50%", left: "50%", transform: "translate(-50%, -50%)"}}>80%</p>
<p style={{position: "absolute", top: "50%", left: "50%", transform: "translate(-50%, -50%)"}}>
{
sumPrice <= 0 ? "0%" : (Math.round(alreadyPay / sumPrice * 10000) / 100.00)+"%"
}
</p>
</View>
</Chart>
}
......
......@@ -26,12 +26,10 @@ const BidDetailLayout: React.FC<BidDetailLayoutProps> = (props: any) => {
const { awardProcess = [], isOpenPurchase, isOpenRanking } = detail;
const [showMore, setShowMore] = useState<boolean>(false);
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;
useEffect(() => {
awardProcess && setActiveItem(awardProcess?.[0] || { detailss: [] })
awardProcess && setActiveIndex(awardProcess?.[0] ? 0 : '')
awardProcess && setActiveItem(awardProcess?.[0] || { detailss: [] });
}, [detail])
const columns: ColumnType<any>[] = [
......@@ -46,9 +44,9 @@ const BidDetailLayout: React.FC<BidDetailLayoutProps> = (props: any) => {
</Space>
)
},
{ title: '规格型号',key: 'model', dataIndex: 'model', },
{ title: '品类',key: 'category', dataIndex: 'category', },
{ title: '品牌',key: 'brand', dataIndex: 'brand', },
{ title: '规格型号', key: 'model', dataIndex: 'model', },
{ title: '品类', key: 'category', dataIndex: 'category', },
{ title: '品牌', key: 'brand', dataIndex: 'brand', },
{
title: '采购数量/单位',
dataIndex: 'unit',
......@@ -85,11 +83,10 @@ const BidDetailLayout: React.FC<BidDetailLayoutProps> = (props: any) => {
},
]
const chooseItem = (item: any, index: number) => {
if (index !== activeIndex) {
const chooseItem = (item: any) => {
if (item.peportTime !== activeItem?.peportTime) {
setShowMore(false);
setActiveItem(item);
setActiveIndex(index)
}
}
......@@ -103,13 +100,15 @@ const BidDetailLayout: React.FC<BidDetailLayoutProps> = (props: any) => {
<Row gutter={[8, 8]} style={{ marginBottom: '10px' }}>
{awardProcess?.map((item, index, arr) => {
let _ratio = 0;
let _arrLength = arr.length;
const _arrLength = arr.length;
if (btnType === 2) {
if (index != _arrLength - 1 && _arrLength > 2) {
_ratio = Number(((item.sumPice - arr[index + 1].sumPice) / arr[index + 1].sumPice * 100).toFixed(2))
}
}
return (
<Col span={7} key={`${item.id}_${item.peportTime}`} onClick={() => { chooseItem(item, index) }}>
<BtnItem btnType={btnType} detail={{ ...item, isOpenPurchase, isOpenRanking, ratio: _ratio }} active={index === activeIndex} />
<Col span={7} key={`${item.id}_${item.peportTime}`} onClick={() => { chooseItem(item) }}>
<BtnItem btnType={btnType} detail={{ ...item, isOpenPurchase, isOpenRanking, ratio: _ratio, selfRanking: index+1 }} active={item.peportTime === activeItem?.peportTime} />
</Col>
)
})}
......
import React, { useEffect, useState } from 'react';
import React, { useEffect, useState, useRef, useCallback } from 'react';
import { history } from 'umi';
import { Row, Col } from 'antd';
import { ArrowLeftOutlined } from '@ant-design/icons';
......@@ -6,6 +6,8 @@ import { ArrowLeftOutlined } from '@ant-design/icons';
import { PublicApi } from '@/services/api';
import { priceFormat } from '@/utils/numberFomat';
import { formatTimeString } from '@/utils'
import { getAuth } from '@/utils/auth';
import { SOCKET_URL } from '@/constants';
import StatusBox from '../../../purchaseBid/readyBid/management/components/statusBox';
import QuotationDeskLayout from '../../../components/detail/components/quotationDeskLayout';
......@@ -30,7 +32,45 @@ const Detail = () => {
const [dataSource, setDataSource] = 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 = {
id,
number,
......@@ -43,19 +83,28 @@ const Detail = () => {
return;
}
const { data } = res;
let _flag = false;
if(socketObj){
_flag = true;
data.ranking = socketObj.ranking;
data.minLowPrice = socketObj.minLowPrice;
}
data.onlineId = Number(onlineId);
setDataSource(data);
let _list = [];
let _offerList = [];
let _minList = [];
let _quotationDesks = data?.quotationDesks ? [...data.quotationDesks].reverse() : [];
if(_flag){
_quotationDesks = socketObj.quotationDesks.filter((item) => item.id == onlineId)
}
_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 });
if (data.isOpenPurchase) {
_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 });
}
......
......@@ -43,7 +43,7 @@ const RankRow: React.FC<RankRowProps> = (props: any) => {
<div className={styles.rankRowLeftTop}>
{_returnBadge(detail.ranking)}
{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 className={styles.rankRowLeftBottom}>
¥{priceFormat(detail.sumPrice)}
......
import React, { useState, useEffect, useMemo } from 'react';
import { history } from 'umi';
import { Row, Col, Input, Drawer, Table, Space, Typography, message } from 'antd';
import { ColumnType } from 'antd/lib/table/interface';
......@@ -35,6 +34,7 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => {
{
title: '物料编号/名称',
dataIndex: 'number',
key: 'number',
render: (text: any, record: any) => (
<Space direction='vertical'>
<Text type='secondary' key={'number_1'} >{text}</Text>
......@@ -42,12 +42,13 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => {
</Space>
)
},
{ title: '规格型号', dataIndex: 'model', },
{ title: '品类', dataIndex: 'category', },
{ title: '品牌', dataIndex: 'brand', },
{ title: '规格型号', key: 'model', dataIndex: 'model', },
{ title: '品类', key: 'category', dataIndex: 'category', },
{ title: '品牌', key: 'brand', dataIndex: 'brand', },
{
title: '采购数量/单位',
dataIndex: 'unit',
key: 'unit',
render: (text: any, record: any) => (
<Space direction='vertical'>
<Text type='secondary' key={'unit_1'} >{record.purchaseCount}</Text>
......@@ -58,16 +59,19 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => {
{
title: '含税/税率',
dataIndex: 'isTax',
key: 'isTax',
render: (text: any, record: any) => <Input value={record.taxRate} onChange={(e) => { _changeTax(record, e.target.value) }} addonAfter="%" />
},
{
title: '单价(含税)',
dataIndex: 'unitPrice',
key: 'unitPrice',
render: (text: any, record: any) => <Input value={record.unitPrice} onChange={(e) => { _changeUnitPrice(record, e.target.value) }} addonBefore="¥" />
},
{
title: '金额(含税)',
dataIndex: 'price',
key: 'price',
render: (text: any, record: any) => <Text type='secondary'>{text && `¥${priceFormat(text)}`}</Text>
},
]
......@@ -135,7 +139,7 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => {
}
PublicApi.postPurchaseOnlineBiddingSubmitReportPrice(_params).then(res => {
if (res.code === 1000) {
history.goBack();
onClose && onClose();
}
})
}
......@@ -158,13 +162,13 @@ const DetailBottomDrawer: React.FC<DetailBottomDrawerProps> = (props: any) => {
</Col>
{awardProcess?.map((item, index, arr) => {
let _ratio = 0;
let _arrLength = arr.length;
const _arrLength = arr.length;
if (index != _arrLength - 1 && _arrLength > 2) {
_ratio = Number(((item.sumPice - arr[index + 1].sumPice) / arr[index + 1].sumPice * 100).toFixed(2))
}
return (
<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>
)
})}
......
import React, { useEffect, useState } from 'react';
import React, { useEffect, useState, useRef, useCallback } from 'react';
import { history } from 'umi';
import { Row, Col } from 'antd';
import { ArrowLeftOutlined } from '@ant-design/icons';
......@@ -6,6 +6,8 @@ import { ArrowLeftOutlined } from '@ant-design/icons';
import { PublicApi } from '@/services/api';
import { formatTimeString } from '@/utils'
import { priceFormat } from '@/utils/numberFomat';
import { getAuth } from '@/utils/auth';
import { SOCKET_URL } from '@/constants';
import QuotationDeskLayout from '../../../components/detail/components/quotationDeskLayout';
import BidDetailLayout from '../../../components/detail/components/bidDetailLayout';
......@@ -32,6 +34,53 @@ const Management = () => {
const [awardProcess, setAwardProcess] = 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 params = {
id,
......@@ -89,7 +138,7 @@ const Management = () => {
setLowestList({
type: 'min',
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