SOURCE

console 命令行工具 X clear

                    
>
console
// 假设的规则配置数据源
const allConfigList = [
    {
        id: 1,
        code: '3',
        priority: 1,
        type: '111', xxx: '222',
        list: [
            { keyName: 'oValue', cond: '>=', keyValue: 9.2, joint: 'OR' },
            { keyName: 'cValue', cond: '>=', keyValue: 19.2, joint: 'OR' }
        ]
    },
    {
        id: 2,
        code: '2',
        priority: 3,
        type: 'xxx', xxx: '767',
        list: [
            { keyName: 'oValue', cond: '>=', keyValue: 9.2, joint: 'AND' },
            { keyName: 'cValue', cond: '!=', keyValue: 15.3, joint: 'OR' },
            { keyName: 'life', cond: '>=', keyValue: 15.3, joint: 'OR' }
        ]
    },
]


// 将配置规则里的AND 和 OR 转化为 js可识别的运算符
const RULE_MAP = {
    'AND': '&&',
    'OR': '||'
}

// 转化运算符 符合js语法,=要转化为 ===, != 转化为 !==
function transformOperator(key) {
    switch (key) {
        case '=':
            return '===';
        case '!=':
            return '!==';
        default:
            return key;
    }
}

/**
     * 将原始数据进行转化处理,得到新的数据
     *  [{
          id: 1,
          code: '1',
          priority: 3,
          type: '111', xxx: '222',
          list: [
            { keyName: 'oValue', cond: '=', keyValue: 9.2, joint: 'AND' },
          ]
        }]
        形如上面数据的转化为
      [ { id: 1,code: '1',priority: 3,type: '111',xxx: '222',operatorString: '(【oValue】 === 9.2)' }]形式
     */
function transformInitData() {
    const arr = []
    for (let i = 0; i < allConfigList.length; i++) {
        const item = allConfigList[i]
        const obj = Object.assign({}, item)
        delete obj.list

        const listLen = item.list.length - 1
        // 做了转化处理
        const cond = item.list.reduce((prev, next, index) => {
            prev += `(【${next.keyName}${transformOperator(next.cond)} ${next.keyValue})`
            // 非最后一项的OR或者AND才转化为|| && 这样的
            if (index !== listLen) {
                prev += ` ${RULE_MAP[next.joint]} `
            }
            return prev
        }, '')

        arr.push({
            ...obj,
            operatorString: cond
        })
    }
    return arr
}

/**
* '(【oValue】 === 9.2)'将形如这样的表达式,通过给定数据获取对应字段值、去除首尾的【】,得到最终形如 '9 === 9.2'的形式,
* 再通过eval(string),即相当于js 执行字符串, 获取对应结果
* 用list进行保存的原因是:若符合结果项的有多个,则获取优先级最高的返回,优先级都是从1234..这样设置的,1最高
* @param data json数据源,
*/
function getMatchedTWRuleData(data) {
    const arr = transformInitData()
    const list = []
    for (let i = 0; i < arr.length; i++) {
        const item = arr[i]
        const reg = /\【(.+?)\】/g // 匹配【】,里面存放的是字段名

        // 将形如 '(【oValue】 === 9.2)' 替换为  '9 === 9.2' 形式
        item.operatorString = item.operatorString.replace(reg, function (value) {
            // 这里去除了首尾的【】,获取其中的字段名
            const ss = value.replace(/\【/g, '').replace(/\】/g, '')
            // 遍历数据源里的数据,比对键名与字段名相同,则获取数据源对应的该值
            for (const key in data) {
                if (key === ss) {
                    return data[key]
                }
            }
        })

        // 这块eval(xxx),相当于执行代码 9 === 9.2,不过一般eval慎用!
        // 若符合条件,装入list里
        if (eval(item.operatorString)) {
            list.push(item)
        }
    }

    // console.log('结果数组是===\n',list)
    console.table(list)
    // 返回结果
    return list.length ? list.sort((a, b) => a.priority - b.priority < 0 ? -1 : 1)[0] : null
}


const testData = {
    id: 12,
    all: 212,
    oValue: 10,
    life: 7.9,
    ss: 6.3
}

$(".testData").text(JSON.stringify(testData));


function workCode() {
    const res = getMatchedTWRuleData(testData)
    console.log('匹配到的结果是=====', res)
    $(".strJson").text(JSON.stringify(res));
    $(".res").text('匹配到啦!!!')
}
<h4>规则匹配</h4>
<div id="testDiv">
	<p>测试数据是:</p>
    <div class="testData"></div>
	<div>
		<br></br>
<button onclick="workCode()">提交</button>

<p>结果是:</p>
 <div class="panel-body" style="height:580px;overflow:auto"> 
   <div class="strJson"></div> 
   <p class="res"></p>
  </div>
.res {
    color: green;
}

本项目引用的自定义外部资源