CalculatorView.js 5.11 KB
import React, {Component} from 'react';
import {
    View,
    Text,
    TextInput,
    Image,
} from 'react-native';
import {Calculate, convertCurrency, isJSONString} from "../utils/utils";

const defaultHeight = (62);
const titleViewHeight = (24);
const HPading = (16);
const VPading = (6);

export default class CalculatorView extends Component {

    constructor(props) {
        super(props);
        this.state = {
            result: '',
        };
        this.attrData = this.props.attrData;
        this.inputType = this.props.inputType || 'default';// 输入类型

        this.extendData = (this.attrData.data && this.attrData.data.length > 0)?JSON.parse(this.attrData.data):{};
        this.expression = this.extendData.expression;
        this.moleculeDataList = [];// 计算公式分子数组
    }

    componentWillMount() {
        if (this.attrData.value && this.attrData.value.length > 0) {
            if (isJSONString(this.attrData.value)) {
                let data = JSON.parse(this.attrData.value);
                this.setState({
                    result: data.result
                })
            }
        }
    }

    calculateValue(count, key) {
        // 如果计算公式为空、或输入的数值不是表达式中的分子,不计算
        if (!!!this.expression || this.expression.length === 0 || this.expression.indexOf(key) === -1) {
            return;
        }
        // 计算表达式
        let moleculeData = {count: count, key: key};
        this.updateMoleculeDataList(moleculeData);
        let expression = this.replaceExpression();

        var calculate = new Calculate(expression);
        let _result = calculate.calculateResult();
        if (_result && _result.length > 0) {
            // 结果是整数,不做精度计算
            _result = Number.isInteger(_result)? _result:parseFloat(_result).toFixed(2);
        }
        this.setState({
            result: _result
        });
        // 计算结果
        let resultValue = {expression: this.expression, result: _result};
        this.attrData.value = JSON.stringify(resultValue)
    }

    /**
     * 更新公式分子
     * @param data
     */
    updateMoleculeDataList(data) {
        if (this.moleculeDataList && this.moleculeDataList.length > 0) {
            let length = this.moleculeDataList.length;
            for (let i=0; i< length; i++) {
                let _molecule = this.moleculeDataList[i];
                if (_molecule.key === data.key) {
                    // 刷新分子数值
                    if (data.count && data.count.length > 0) {
                        _molecule.count = data.count;
                    } else {
                        this.moleculeDataList.splice(i, 1);
                    }
                    return;
                }
            }
        }
        // 添加新分子
        this.moleculeDataList.push(data);
    }

    /**
     * 替换表达式
     */
    replaceExpression() {
        if (this.moleculeDataList && this.moleculeDataList.length > 0) {
            let wreckedExpression = this.expression;
            this.moleculeDataList.map(molecule => {
                wreckedExpression = wreckedExpression.replace(molecule.key, molecule.count);
            });
            return wreckedExpression;
        }
        return '';
    }

    render() {
        let {name, code, type, description, isRequired, isPreview} = this.attrData;
        let {placeholder, showChinese} = this.extendData;

        let calcHeight = defaultHeight;
        if(showChinese){
            calcHeight += 40
        }

        return(
            <View style={{width: '100%', backgroundColor: 'white', paddingTop: VPading,paddingLeft: 10, paddingRight: 15, height:calcHeight}}>
                <View style={{flexDirection: 'row',height:titleViewHeight,justifyContent:'flex-start',alignItems:'center'}}>
                    {isRequired&&<Text style={{ color: "#FF3030" }}>* </Text>}
                    {!isRequired&&<Text style={{ color: "#fff" }}>* </Text>}
                    <Text style={{fontSize: 16, color: 'rgba(0, 0, 0, 1)'}}>{name||""}</Text>
                </View>
                <View style={{width: "100%", height: 30, marginLeft:10,marginTop: 4, marginBottom:4,justifyContent: 'center',backgroundColor: 'white'}}>
                    <Text
                        style={{
                            fontSize: 14,
                            color: (!!this.state.result && this.state.result.length > 0)?'black':'#999',
                            textAlign: 'left',
                        }}>{this.state.result||placeholder||'自动计算数值'}
                    </Text>
                </View>
                {showChinese && <View style={{height:40,paddingBottom:VPading,flexDirection: 'row',alignItems:'center',backgroundColor:'#fff',
                    marginLeft:10, marginRight: 15}}>
                    <Text style={{fontSize: 16, color: 'rgba(0, 0, 0, 1)'}}>大写</Text>
                    <Text style={{fontSize: 14, color: 'rgba(0, 0, 0, 1)',marginLeft:4,marginRight:4}}>{!!this.state.result?convertCurrency(this.state.result):''}</Text>
                </View>
                }
            </View>
        )
    }
}