UNPKG

cefc-view-transactiondetails

Version:

CEFC-UI Component

186 lines (147 loc) 5.68 kB
import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { decimalFormat, switchUnit } from 'cefc-biz-utils/format'; import { isEmpty } from 'cefc-biz-utils/validator'; const DIRECTION = { 1: 'B', //买 2: 'S' //卖 }; const EMPTY_VALUE = '--'; const Decorator = (ComposedComponent = () => { return <div></div> }) => { const initTransactionDetails = (length) => { let initData = []; for (let i = 0; i < length; i++) { initData.push({ time: EMPTY_VALUE, price: EMPTY_VALUE, amount: EMPTY_VALUE, }) } return initData; } const getTransactionTime = (time) => { if (isEmpty(time)) { return EMPTY_VALUE; } const curTime = time.toString().slice(8, 12); //获取当前的小时和分钟 return `${curTime.slice(0, 2)}:${curTime.slice(2, 4)}`; } const getTransactionPrice = (price, precision) => { return isEmpty(price) ? EMPTY_VALUE : decimalFormat({ value: price, precision: precision }); } const getTransactionAmount = (amount, handCount) => { if (isEmpty(amount)) { return EMPTY_VALUE; } let amt = switchUnit(Math.floor(parseFloat(amount) / handCount)); //防止盘口数量带单位时折行, 若有中文单位,改变盘口数量列的宽度 if (amt.indexOf('万') !== -1) { //计算整数位的位数,为防止数量过长折行,整数位是2位或2位以上的,则略去小数点后的位数 const amtTemp = amt.split('.'); const integerLength = amtTemp[0].length; const decimalLength = amtTemp[1] && amtTemp[1].length; if (integerLength >= 2) { amt = `${amtTemp[0]}万`; } if ((integerLength === 1) && decimalLength && decimalLength >= 2) { amt = `${amtTemp[0]}.${amtTemp[1].split('')[0]}万` } } return amt; } const getTransactionDir = (dir, lastVol) => { //成交量为空时也显示买卖方向 return (isEmpty(dir) || isEmpty(lastVol)) ? '' : (`${DIRECTION[dir]}` || DIRECTION[1]); } return class extends Component { static propTypes = { //数据精度 precision: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), //数据一手的单位 handCount: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), //推送数据 socketData: PropTypes.object, //明细一次性请求的数据 tickData: PropTypes.array, } static defaultProps = { precision: 2, handCount: 100 } constructor(props, context) { super(props, context); this.state = { transactionDetails: [], transLength: 9 // 明细的条数 }; this.state.transactionDetails = initTransactionDetails(this.state.transLength); } componentWillMount() { if (!this.initCompleted && !isEmpty(this.props.tickData)) { this.initCompleted = true; this.state.transactionDetails = this.countTransactionDetails(this.props.tickData); } if (!isEmpty(this.props.socketData) && !isEmpty(this.props.tickData)) { this.countSocketData(this.props.socketData, this.props.tickData); } } componentWillReceiveProps(nextProps) { if (!this.initCompleted) { this.initCompleted = true; this.setState({ transactionDetails: this.countTransactionDetails(nextProps.tickData) }); } if (!isEmpty(nextProps.socketData) && !isEmpty(this.props.tickData)) { this.countSocketData(nextProps.socketData, nextProps.tickData, this.props.socketData); } } countTransactionDetails = (data) => { if (isEmpty(data)) { return this.state.transactionDetails; } const len = data.length; const { precision, handCount } = this.props; return this.state.transactionDetails.map((item, index) => { const dot = data[len - index - 1]; if (!isEmpty(dot)) { item.time = getTransactionTime(dot.time); item.price = getTransactionPrice(dot.price, precision); item.amount = getTransactionAmount(dot.volume, handCount); item.direction = getTransactionDir(dot.direction, dot.volume); } return item; }).reverse(); } countSocketData = (curSktdata, tickData, preSktData) => { const curTimestamp = curSktdata.timestamp; const curTradeVol = curSktdata.tradeVol; //总成交量 const lastDetailsDot = tickData[tickData.length - 1]; const { precision, handCount } = this.props; //推送的时间戳,与拉取的数据列表中的最新数据的时间戳相等时,不更新明细 if (lastDetailsDot.timestamp === curTimestamp) { return; } //若已经连续推送数据,则直接对比前后推送数据,若交易总量相同,不更新明细 if (!isEmpty(preSktData)) { const preTradeVol = preSktData.tradeVol; if (preTradeVol === curTradeVol) { return; } } this.state.transactionDetails.shift(); //删除明细中最早的数据 this.state.transactionDetails.push({ time: getTransactionTime(curTimestamp), price: getTransactionPrice(curSktdata.lastPrice, precision), amount: getTransactionAmount(curSktdata.lastVol, handCount), direction: getTransactionDir(curSktdata.direction, curSktdata.lastVol) }); this.setState({ transactionDetails: this.state.transactionDetails }); } render() { return <ComposedComponent {...this.props} transactionDetails={this.state.transactionDetails} />; } } } export default Decorator; export { DIRECTION };