cefc-view-transactiondetails
Version:
CEFC-UI Component
186 lines (147 loc) • 5.68 kB
JavaScript
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 };