js 根据条件生成公式

需求:
根据用户选择公式条件,最终生成公式;

后端所需json较大举例IF函数:

{
		"name": "技术质量管理",
		"remark": "", //备注
		"evaluateId": "1656117529237520387",
		"previousResult": -1,
		"type": "函数", //选择类型
		"functionType": "IF", //具体函数类型 MIN、MAX、IF
		"functionStr": "IF(H19=0,1,IF(H19<=2,0.9,(IF(H19<=5,0.7,IF(H19<=8,0.5,0.2)))))", //形成的函数表达式
		"conditionParams": [
			{ //IF条件
				"expression": { //表达式参数
					"variable": {
						"des": "变量", //H31/H30*100<=100    IF(H5/H4>=0.8
						"type": "指标值", //指标分值、指标值,带入结果
						"previousResult": -1, //具体带入的结果步数 0,-1表示不带入
						"indicatorInfo": { //type 为指标分值、指标值、指标内容分值等
							"evaluateId": "1656117529237520388",
							"name": "质量问题投诉(次)",
							"indicatorId": "1655750184467955712",
							"indicatorVersionId": "d2d160b1-67ad-4608-9759-d9f3dfea0f9f"
						}
					},
					"condition": {
						"des": "条件",
						"type": "小于等于" //条件:大于、大于等于、小于、小于等于
					},
					"constant": {
						"des": "常量",
						"type": "填值",
						"value:": 8 //具体填的值
					}
				},
				"resultParams": { //结果参数
					"params1": {
						"des": "结果一",
						"type": "填值", //填值、指标分值、指标值、带入结果
						"value": 0.5, //具体填的值
						"previousResult": -1 //具体带入的结果步数 0,-1表示不带入
					},
					"params2": {
						"des": "结果二",
						"type": "填值", //填值、指标分值、指标值、带入结果
						"value": 0.2,
						"previousResult": -1 //具体带入的结果步数 0,-1表示不带入
					}
				}
			},
			{
				"previousConditionResult": 2, //具体带入的条件步数 0,-1表示不带入
				"asResultOne": false, //是否作为结果一,否则作为结果二
				"expression": { //表达式参数
					"variable": {
						"des": "变量", //H31/H30*100<=100    IF(H5/H4>=0.8
						"type": "指标值", //指标分值、指标值,带入结果
						"previousResult": -1, //具体带入的结果步数 0,-1表示不带入
						"indicatorInfo": { //type 为指标分值、指标值、指标内容分值等
							"evaluateId": "1656117529237520388",
							"name": "质量问题投诉(次)",
							"indicatorId": "1655750184467955712",
							"indicatorVersionId": "d2d160b1-67ad-4608-9759-d9f3dfea0f9f"
						}
					},
					"condition": {
						"des": "条件",
						"type": "等于" //条件:大于、大于等于、小于、小于等于
					},
					"constant": {
						"des": "常量",
						"type": "填值",
						"value:": 0 //具体填的值
					}
				},
				"resultParams": { //结果参数
					"params1": {
						"des": "结果一",
						"type": "填值", //填值、指标分值、指标值、带入结果
						"value": 0, //具体填的值
						"previousResult": -1 //具体带入的结果步数 0,-1表示不带入
					},
					"params2": {
						"des": "结果二",
						"type": "填值", //填值、指标分值、指标值、带入结果
						"value": null,
						"previousResult": -1 //具体带入的结果步数 0,-1表示不带入
					}
				}
			}
		]
	},

前端页面样式:
在这里插入图片描述
思路1:html代码中取数据,如遇带入步骤/带入条件则进行递归处理
item19,item 两个变量由于在老项目上改动,所以继续用了。
html代码中递归会出现很多问题,不好改动,后改为js写法。无需递归很简单的操作。

<template>
    <span>
        <span @click="dayin(item19)">
            查看
        </span>
        IF<span v-if="item19.expression.variable.type == '指标值' || item19.expression.variable.type == '指标分值'">
            {{ item19.expression.variable.indicatorInfo.name }}
        </span>
        <span v-if="item19.expression.variable.type == '填值'">
            {{ item19.expression.variable.value }}
        </span>
        <span v-if="item19.expression.condition.type == '小于'"> &lt; </span>
        <span v-if="item19.expression.condition.type == '大于'"> &gt; </span>
        <span v-if="item19.expression.condition.type == '小于等于'"> &lt;= </span>
        <span v-if="item19.expression.condition.type == '大于等于'"> &gt;= </span>
        <span v-if="item19.expression.condition.type == '等于'"> = </span>
        <span v-if="item19.expression.constant.type == '填值'">
            {{ item19.expression.constant.value }}</span>
        <span v-if="item19.expression.constant.type == '指标值' || item19.expression.constant.type == '指标分值'">
            {{ item19.expression.constant.indicatorInfo.name }}</span>
        <span v-if="item19.resultParams.params1.type == '带入步骤结果'">
            <span v-if="item19.resultParams.params2.previousResult || item19.resultParams.params2.previousResult == 0">
                <span v-if="item[item19.resultParams.params1.previousResult]">
                   <formula :item19="item[item19.resultParams.params1.previousResult].ifFunctionList[0]" :item="item" />
                </span>
            </span>
        </span>
        <span v-if="item19.resultParams.params1.type == '填值'">
            {{ item19.resultParams.params1.value }}</span>
        <span v-if="item19.resultParams.params1.type == '带入条件结果'">
            <span
                v-if="item19.resultParams.params1.previousConditionResult || item19.resultParams.params1.previousConditionResult == 0">
              <formula
                    :item19="item[item19.resultParams.params1.previousResult].ifFunctionList[item19.resultParams.params1.previousConditionResult]"
                    :item="item" />
            </span>
        </span>

        <span v-if="item19.resultParams.params2.type == '带入步骤结果'">
            <span v-if="item19.resultParams.params2.previousResult || item19.resultParams.params2.previousResult == 0">
                <span v-if="item[item19.resultParams.params2.previousResult]">
                    <formula :item19="item[item19.resultParams.params2.previousResult].ifFunctionList[0]" :item="item" />
                </span>
            </span>
        </span>
        <span v-if="item19.resultParams.params2.type == '填值'">
            {{ item19.resultParams.params2.value }}
        </span>
        <span v-if="item19.resultParams.params2.type == '带入条件结果'">
            <span
                v-if="item19.resultParams.params2.previousConditionResult || item19.resultParams.params2.previousConditionResult == 0">
                <formula :item19="item.ifFunctionList[item19.resultParams.params2.previousConditionResult]" :item="item" />
            </span>
        </span></span>
</template>

<script>
import formula from './formula.vue';
export default {
    name: "formula",
    components: {
        formula
    },
    data: function () {
        return {
            isShow: false,
            tableInfo: [],
        };
    },
    created() {
    },
    watch: {},
    props: {
        item: {
            item: {
                type: [Array, Object],
                default: () => ({})
            }
        },
        item19: {
            type: Object
        }
    },
    computed: {

    },
    methods: {
        dayin(record) {
            console.log('record =', record);
        }
    },
};
</script>

<style></style>

js代码如下:

// 设置 条件结果预览
        conditionResultPreview(item19, item) {
            let expression = "条件结果预览:IF(";

            if(item19.expression.variable.type == '指标值' || item19.expression.variable.type == '指标分值'){
                expression += item19.expression.variable.indicatorInfo.name;
            }
            if(item19.expression.variable.type == '填值'){
                expression += item19.expression.variable.value;
            }
            if(item19.expression.condition.type == '小于')  expression += ' < ';
            if(item19.expression.condition.type == '大于')  expression += ' > ';
            if(item19.expression.condition.type == '小于等于')  expression += ' <= ';
            if(item19.expression.condition.type == '大于等于')  expression += ' >= ';
            if(item19.expression.condition.type == '等于')  expression += ' = ';

            if(item19.expression.constant.type == '填值'){
                expression += item19.expression.constant.value + ',';
            }
            if(item19.expression.constant.type == '指标值' || item19.expression.constant.type == '指标分值'){
                expression += item19.expression.constant.indicatorInfo.name
            }
            // 带入步骤结果
            try {
                if (item19.resultParams.params1.type == '带入步骤结果') {
                    if (item19.resultParams.params1.previousResult || item19.resultParams.params1.previousResult == 0) {
                        expression += this.tyPeList[item19.resultParams.params1.previousResult].ifFunctionList[this.tyPeList[item19.resultParams.params1.previousResult].ifFunctionList.length-1].formula + ','
                    }
                }
            } catch (error) {
                // 处理错误的代码
            }


            // 带入条件结果
            if(item19.resultParams.params1.type == '带入条件结果'){
                if(item19.resultParams.params1.previousConditionResult || item19.resultParams.params1.previousConditionResult == 0){
                    expression += item.ifFunctionList[item19.resultParams.params1.previousConditionResult].formula +','
                }
            }

            if(item19.resultParams.params1.type == '填值'){
                expression += item19.resultParams.params1.value + ','
            }

            // 带入步骤结果
            try {
                if (item19.resultParams.params2.type == '带入步骤结果') {
                    if (item19.resultParams.params2.previousResult || item19.resultParams.params2.previousResult == 0) {
                        expression += this.tyPeList[item19.resultParams.params2.previousResult].ifFunctionList[this.tyPeList[item19.resultParams.params2.previousResult].ifFunctionList.length-1].formula
                    }
                }
            } catch (error) {
                // 处理错误的代码
            }

            // 带入条件结果
            if(item19.resultParams.params2.type == '带入条件结果'){
                if(item19.resultParams.params2.previousConditionResult || item19.resultParams.params2.previousConditionResult == 0){
                    expression += item.ifFunctionList[item19.resultParams.params2.previousConditionResult].formula
                }
            }

            if(item19.resultParams.params2.type == '填值'){
                expression += item19.resultParams.params2.value
            }

            expression += ')'
            item19.formula = expression;
            return expression;

        }

这边用到了try catch 防止报错导致程序不能运行,我只添加了报错(报错是因为数据没拿到)的条件下,这样能完美解决问题。并且方便拿到每个条件的数据,我认为这个方法比较好。

**

重构后代码:

重构后的代码将逻辑拆分为几个小函数,并且在 conditionResultPreview 函数中调用这些小函数处理相应的任务,并且针对空值和未定义的情况进行了检查。
使代码更加模块化和易于维护,同时可以提高代码的可复用性。

		conditionResultPreview(item19, item) {
            let expression = "IF(";
            const { variable = {}, condition = {}, constant = {} } = item19.expression || {};

            expression += this.getIndicatorOrValue(variable);
            expression += this.getConditionSymbol(condition.type);
            expression += this.getIndicatorOrValue(constant);

            expression += this.addStepOrConditionResult(item19.resultParams.params1, this.tyPeList, item);
            expression += this.addStepOrConditionResult(item19.resultParams.params2, this.tyPeList, item);

            expression += ')';
            item19.formula = expression;
            return expression;
        },

        getIndicatorOrValue(obj) {
            if (obj.type === '指标值' || obj.type === '指标分值') {
                return obj.indicatorInfo?.name ?? '';
            } else if (obj.type === '填值') {
                return obj.value ?? '';
            }
            return '';
        },

        getConditionSymbol(type) {
            switch (type) {
                case '小于': return ' < ';
                case '大于': return ' > ';
                case '小于等于': return ' <= ';
                case '大于等于': return ' >= ';
                case '等于': return ' = ';
                default: return '';
            }
        },

        addStepOrConditionResult(params, tyPeList, item) {
            if (params.type === '带入步骤结果' && params.previousResult != null && tyPeList && tyPeList[params.previousResult]) {
                return `${tyPeList[params.previousResult].ifFunctionList[tyPeList[params.previousResult].ifFunctionList.length - 1].formula}`;
            } else if (params.type === '带入条件结果' && params.previousConditionResult != null && item && item.ifFunctionList) {
                return `${item.ifFunctionList[params.previousConditionResult].formula}`;
            } else if (params.type === '填值') {
                return `${params.value ?? ''}`;
            }
            return '';
        }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值