当前位置: 首页 > 工具软件 > URule > 使用案例 >

模仿urule

洪弘壮
2023-12-01

https://github.com/bigbigbo/rule-editor.git

demo

<template>
  <div>
    <UniteCondition class="ftms-condition" 
    :rootCondition="rootCondition"
    :variables="variables"
    @changeData="changeData"
    >
    </UniteCondition>
  </div>
</template>

<script>
import UniteCondition from './UniteCondition.vue'
// import Condition from './Condition.vue'/
export default {
  name: 'ConditionView',
  props: [],
  data:()=>{
    return{
      rootCondition: {
        id: 'ROOT',
        type: 'and',
        subConditions: [
          {
            id: '95fe42f0b1f395f9e20529b825e5599d',
            type: 'normal',
            expression: {
              left: {
                id: 'fb842a8d3730e7cd5a919fc8a0014214',
                type: 'variable',
                value: {
                  groupCode: ['kehu'],
                  groupLabel: '客户',
                  propCode: 'hunfou',
                  propLabel: '婚否'
                }
              },
              operator: {
                label: '等于',
                charator: '=='
              },
              right: {
                id: '769dfa8a8013d8987735d542df188021',
                type: 'input',
                value: '未婚'
              }
            }
          },
          {
            id: '638b12ff1d67d0e61a3aace0f1e6a11c',
            type: 'normal',
            expression: {
              left: {
                id: 'f0c01555924010e52f9cc918c5a55d7d',
                type: 'variable',
                value: {
                  groupCode: ['kehu'],
                  groupLabel: '客户',
                  propCode: 'nianling',
                  propLabel: '年龄'
                }
              },
              operator: {
                label: '等于',
                charator: '=='
              },
              right: {
                id: '5a30eaec8e0ed46f49dcb25ebd51bc7c',
                type: 'func',
                value: {
                  actionName: 'date.action',
                  methodName: 'format',
                  methodLabel: '格式化日期',
                  parameters: [
                    {
                      name: '目标日期',
                      type: 'Date',
                      value: {
                        id: 'dfc3cd60659f125bcd5766905260b20c',
                        type: 'func',
                        value: {
                          actionName: 'date.action',
                          methodName: 'getDate',
                          methodLabel: '当前日期',
                          parameters: []
                        }
                      }
                    },
                    {
                      name: '格式',
                      type: 'String',
                      value: {
                        id: '150fea2a440d4a251c8e62982d7ef054',
                        type: 'input',
                        value: 'YYYYMMDD'
                      }
                    }
                  ]
                }
              }
            }
          },
          {
            id: '9ee37340f10e30a944f23860f7b06afd',
            type: 'normal',
            expression: {
              left: {
                id: 'b83129403fcaaf3c70b330d4d53ae60b',
                type: 'variable',
                value: {
                  dicts: {
                    label: '性别',
                    value: 'sex',
                    children: [
                      {
                        label: '男',
                        value: '1'
                      },
                      {
                        label: '女',
                        value: '0'
                      }
                    ]
                  },
                  groupCode: ['kehu'],
                  groupLabel: '客户',
                  propCode: 'xingbie',
                  propLabel: '性别'
                }
              },
              operator: {
                label: '等于',
                charator: '=='
              },
              right: {
                id: 'e12a208596c5525130399c43d507a3aa',
                type: 'constant',
                value: {
                  dicts: {
                    label: '性别',
                    value: 'sex',
                    children: [
                      {
                        label: '男',
                        value: '1'
                      },
                      {
                        label: '女',
                        value: '0'
                      }
                    ]
                  },
                  dictType: 'sex',
                  dictTypeLabel: '性别',
                  code: '1',
                  label: '男'
                }
              }
            }
          },
          {
            id: '57d2401cb7b49f4643bd4ba775886fc5',
            type: 'normal',
            expression: {
              left: {
                id: 'a201a2e363defe1868233f469705437d',
                type: 'variable',
                value: {
                  dicts: {
                    label: '性别',
                    value: 'sex',
                    children: [
                      {
                        label: '男',
                        value: '1'
                      },
                      {
                        label: '女',
                        value: '0'
                      }
                    ]
                  },
                  groupCode: ['kehu'],
                  groupLabel: '客户',
                  propCode: 'xingbie',
                  propLabel: '性别'
                }
              },
              operator: {
                label: '在集合中',
                charator: 'in'
              },
              right: {
                id: '911fb641ab283eccc1a17fd78601c551',
                type: 'constant',
                value: {
                  dicts: {
                    label: '性别',
                    value: 'sex',
                    children: [
                      {
                        label: '男',
                        value: '1'
                      },
                      {
                        label: '女',
                        value: '0'
                      }
                    ]
                  },
                  dictType: 'sex',
                  dictTypeLabel: '性别',
                  code: '',
                  label: ''
                }
              }
            }
          },
          {
            id: '50757e83994e09379b35c4132e4415bb',
            type: 'or',
            subConditions: [
              {
                id: '0a2d8a7d952e124159226a69ed21fb15',
                type: 'normal',
                expression: {
                  left: {
                    id: '2956e9cc421afbb073f3fc537d2a7d49',
                    type: 'variable',
                    value: {
                      groupCode: ['kehu'],
                      groupLabel: '客户',
                      propCode: 'nianling',
                      propLabel: '年龄'
                    }
                  },
                  operator: {
                    label: '大于等于',
                    charator: '>='
                  },
                  right: {
                    id: 'aaee47dcbcd8b775ad98baf0be3171f8',
                    type: 'input',
                    value: '99'
                  }
                }
              },
              {
                id: '0a2d8a7d952e124159226a69ed21fb17',
                type: 'normal',
                expression: {
                  left: {
                    id: '2956e9cc421afbb073f3fc537d2a7d49',
                    type: 'variable',
                    value: {
                      groupCode: ['kehu'],
                      groupLabel: '客户',
                      propCode: 'nianling',
                      propLabel: '年龄'
                    }
                  },
                  operator: {
                    label: '大于等于',
                    charator: '>='
                  },
                  right: {
                    id: 'aaee47dcbcd8b775ad98baf0be3171f8',
                    type: 'input',
                    value: '99'
                  }
                }
              }
            ]
          },
          {
            id: 'bbc7b9132e24deff907386b6c511fec2',
            type: 'or',
            subConditions: [
              {
                id: '1d1c6a532ac8222b8f45e05e59983688',
                type: 'normal',
                expression: {
                  left: {
                    id: '3a0dd38fea59adc86ba3bc3a86cee3c2',
                    type: 'variable',
                    value: {
                      groupCode: ['dingdan'],
                      groupLabel: '订单',
                      propCode: 'shuliang',
                      propLabel: '数量'
                    }
                  },
                  operator: {
                    label: '大于等于',
                    charator: '>='
                  },
                  right: {
                    id: 'f3e8f1bd1baf90153cabf5a7c3d119a0',
                    type: 'input',
                    value: '1000000'
                  }
                }
              },
               {
                id: '1d1c6a532ac8222b8f45e05e59983678',
                type: 'normal',
                expression: {
                  left: {
                    id: '3a0dd38fea59adc86ba3bc3a86cee3c2',
                    type: 'variable',
                    value: {
                      groupCode: ['dingdan'],
                      groupLabel: '订单',
                      propCode: 'shuliang',
                      propLabel: '数量'
                    }
                  },
                  operator: {
                    label: '大于等于',
                    charator: '>='
                  },
                  right: {
                    id: 'f3e8f1bd1baf90153cabf5a7c3d119a0',
                    type: 'input',
                    value: '1000000'
                  }
                }
              },
               {
                id: '1d1c6a532ac8222b8f45e05e59983668',
                type: 'normal',
                expression: {
                  left: {
                    id: '3a0dd38fea59adc86ba3bc3a86cee3c2',
                    type: 'variable',
                    value: {
                      groupCode: ['dingdan'],
                      groupLabel: '订单',
                      propCode: 'shuliang',
                      propLabel: '数量'
                    }
                  },
                  operator: {
                    label: '大于等于',
                    charator: '>='
                  },
                  right: {
                    id: 'f3e8f1bd1baf90153cabf5a7c3d119a0',
                    type: 'input',
                    value: '1000000'
                  }
                }
              },
              {
            id: 'bbc7b9132e24deff907286b6c511fec2',
            type: 'or',
            subConditions: [
              {
                id: '1d1c6a532ac8222b8f45e05e49983688',
                type: 'normal',
                expression: {
                  left: {
                    id: '3a0dd38fea59adc86ba3bc3a86cee3c2',
                    type: 'variable',
                    value: {
                      groupCode: ['dingdan'],
                      groupLabel: '订单',
                      propCode: 'shuliang',
                      propLabel: '数量'
                    }
                  },
                  operator: {
                    label: '大于等于',
                    charator: '>='
                  },
                  right: {
                    id: 'f3e8f1bd1baf90153cabf5a7c3d119a0',
                    type: 'input',
                    value: '1000000'
                  }
                }
              },

               
            ]
          }
            ]
          },
           {
                id: '1d1c6a532ac8222b8f35e05e59983468',
                type: 'normal',
                expression: {
                  left: {
                    id: '3a0dd38fea59adc86ba3bc3a86cee3c2',
                    type: 'variable',
                    value: {
                      groupCode: ['dingdan'],
                      groupLabel: '订单',
                      propCode: 'shuliang',
                      propLabel: '数量'
                    }
                  },
                  operator: {
                    label: '大于等于',
                    charator: '>='
                  },
                  right: {
                    id: 'f3e8f1bd1baf90153cabf5a7c3d119a0',
                    type: 'input',
                    value: '1000000'
                  }
                }
              }
        ]
      },
      variables:[
  {
    label: '客户',
    value: 'kehu',
    desc: '描述客户的一些信息',
    children: [
      { label: '年龄', value: 'nianling', dictType: '' },
      { label: '性别', value: 'xingbie', dictType: 'sex' },
      { label: '婚否', value: 'hunfou', dictType: '' },
      {
        label: '订单',
        value: '_dingdan',
        children: [
          { label: '数量', value: '_shuliang' },
          { label: '名称', value: '_mingcheng' },
          { label: '价格', value: '_jiage' }
        ]
      }
    ]
  },
  {
    label: '订单',
    value: 'dingdan',
    desc: '描述订单的一些信息',
    children: [
      { label: '数量', value: 'shuliang' },
      { label: '名称', value: 'mingcheng' },
      { label: '价格', value: 'jiage' }
    ]
  }
],
    }
  },
  components:{
    UniteCondition,
    // Condition
  },
  methods:{
    changeData(){
      alert(1);
      console.log(this.rootCondition);
      // this.rootCondition.subConditions[5].type = 'And';
      this.getTreeName(this.rootCondition.subConditions,'1d1c6a532ac8222b8f45e05e59983688');
    },
    getTreeName(list,id){
       let _this=this
      for (let i = 0; i < list.length; i++) {
        let a=list[i];
         if(a.id === 'bbc7b9132e24deff907386b6c511fec2'){
              let temp =  {
                id: '1d1c6a532ac8222b8f45e05e59983689',
                type: 'normal',
                expression: {
                  left: {
                    id: '3a0dd38fea59adc86ba3bc3a86cee3c2',
                    type: 'variable',
                    value: {
                      groupCode: ['dingdan'],
                      groupLabel: '订单',
                      propCode: 'shuliang',
                      propLabel: '数量'
                    }
                  },
                  operator: {
                    label: '大于等于',
                    charator: '>='
                  },
                  right: {
                    id: 'f3e8f1bd1baf90153cabf5a7c3d119a0',
                    type: 'input',
                    value: '1000000'
                  }
                }
              };
              // a.subConditions.push(temp);
              this.$set(a.subConditions,a.subConditions.length,temp)
            }
        if(a.id===id){
          console.log(a);
            // a.type = 'Andnd'
            // a.expression.operator.label = 'Andnd'
            this.$set(a.expression.operator,'label','Andnd');
          // return a.type
          alert(123);
        }else{
          if(a.subConditions && a.subConditions.length>0){
            let res=_this.getTreeName(a.subConditions,id)
            if(res){
              // return res
            }
          }
        }
      }
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
  .ftms-condition:after{
    content: '';
    position: absolute;
    width: 16px;
    height: 1px;
    background-color: #fff;
    top: 20px;
    left: -16px;
  }
</style>

单项条件 condition

<template>
  <div class="condition-wrap condition-wrap-before">
     <el-cascader
     style="margin-right:20px;"
    :options="options"
    v-model="selectedOptions">
  </el-cascader>
   <el-select style="margin-right:20px;width:80px;" v-model="Svalue" placeholder="请选择">
    <el-option
      v-for="item in Selectoptions"
      :key="item.value"
      :label="item.label"
      :value="item.value">
    </el-option>
  </el-select>
  <el-input style="margin-right:20px;width: 120px;" v-model="input" placeholder="请输入内容"></el-input>

  </div>
</template>

<script>
export default {
  name: 'Condition',
  props: [
    'rootCondition'
  ],
  data:()=>{
    return {
      input:'',
      Svalue:'',
      Selectoptions:[
        {
          value: '选项1',
          label: '+'
        }, {
          value: '选项2',
          label: '-'
        }, {
          value: '选项3',
          label: '*'
        }, {
          value: '选项4',
          label: '/'
        }, {
          value: '选项5',
          label: '%'
        }
      ],
      selectedOptions:[],
      options:[{
          value: 'zhinan',
          label: '指南',
          children: [{
            value: 'shejiyuanze',
            label: '设计原则',
            children: [{
              value: 'yizhi',
              label: '一致'
            }]
          }, {
            value: 'daohang',
            label: '导航',
            children: [{
              value: 'cexiangdaohang',
              label: '侧向导航'
            }, {
              value: 'dingbudaohang',
              label: '顶部导航'
            }]
          }]
        }, {
          value: 'zujian',
          label: '组件',
          children: [{
            value: 'basic',
            label: 'Basic',
            children: [{
              value: 'layout',
              label: 'Layout 布局'
            }]
          }, {
            value: 'form',
            label: 'Form',
            children: [{
              value: 'radio',
              label: 'Radio 单选框'
            }, {
              value: 'checkbox',
              label: 'Checkbox 多选框'
            }]
          }, {
            value: 'data',
            label: 'Data',
            children: [{
              value: 'table',
              label: 'Table 表格'
            }]
          }, {
            value: 'notice',
            label: 'Notice',
            children: [{
              value: 'alert',
              label: 'Alert 警告'
            }]
          }, {
            value: 'navigation',
            label: 'Navigation',
            children: [{
              value: 'menu',
              label: 'NavMenu 导航菜单'
            }]
          }, {
            value: 'others',
            label: 'Others',
            children: [{
              value: 'dialog',
              label: 'Dialog 对话框'
            }]
          }]
        }, {
          value: 'ziyuan',
          label: '资源',
          children: [{
            value: 'axure',
            label: 'Axure Components'
          }]
        }]
    }
  },
  created(){
    // this.Svalue =  this.rootCondition.expression.operator.label
  },
  watch:{
     'rootCondition.expression':{
    handler(newValue,oldValue){
      console.log(newValue);
      console.log(oldValue);
      this.Svalue =  newValue.operator.label
    },
    immediate:true,
    deep:true
  },
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
  .condition-wrap{
    text-align: left;
    margin-bottom: 10px;
    position: relative;
  }
  .condition-wrap:before{
     content: '';
    position: absolute;
    width: 16px;
    height: 1px;
    background-color: #c9c9c9;
    top: 20px;
    left: -16px;
  }
  
</style>

联合条件 unitecondition

<template>
  <div class="unite-condition">
    <el-dropdown class="dropdown-wrap" split-button type="primary" @click="handleClick">
  {{rootCondition.type}}
  <el-dropdown-menu slot="dropdown">
    <el-dropdown-item>并且</el-dropdown-item>
    <el-dropdown-item>或者</el-dropdown-item>
    <el-dropdown-item divided>添加条件</el-dropdown-item>
    <el-dropdown-item>添加联合条件</el-dropdown-item>
    <el-dropdown-item divided v-if="rootCondition.id != 'ROOT'">删除</el-dropdown-item>
  </el-dropdown-menu>
</el-dropdown>
<div :class="rootCondition.subConditions.length > 1? 'sub-condition border-sub-condition':'sub-condition'" v-if="rootCondition.subConditions">
  <div v-for="item in rootCondition.subConditions" :key="item.id" class="sub-condition-wrap">
  <!-- <UniteCondition v-bind="$attrs" v-on="$listeners" v-if="item.type != 'normal'" :rootCondition="item"></UniteCondition> -->
  <UniteCondition  v-if="item.type != 'normal'" :rootCondition="item"></UniteCondition>
  <Condition v-bind="$attrs" v-on="$listeners" v-else :rootCondition="item"></Condition>
  </div>
</div>
<el-button @click="changeData">修改数据+{{rootCondition.type}}</el-button>
  </div>
</template>

<script>
import Condition from './Condition.vue'
export default {
  name: 'UniteCondition',
  props: [
   'rootCondition',
   'variables'
  ],
  components:{
    Condition
  },
  data:()=>{
    return{

    }
  },
  created(){

  },
  watch:{
    rootCondition:{
    handler(newValue,oldValue){
      console.log('unite***********8');
      console.log(newValue);
      console.log(oldValue);
    },
    deep:true
  },
  },
  methods:{
    handleClick(){

    },
    changeData(){
      this.$emit('changeData');
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped type="text/css" lang="less">
  .unite-condition{
    display: flex;
    position: relative;
    .dropdown-wrap{
      margin-right: 16px;
      height: 40px;
    }
    .dropdown-wrap:after{
      content: '';
    position: absolute;
    width: 16px;
    height: 1px;
    background-color: #c9c9c9;
    top: 20px;
    right: -16px;
    }
    .sub-condition{
      padding-left: 16px;
      position: relative;
    }
    .sub-condition:before{
       content: '';
    position: absolute;
    width: 1px;
    height: 20px;
    background-color: #fff;
    top: 0;
    left: -1px;
    }
     .sub-condition:after{
        content: '';
    position: absolute;
    width: 1px;
    height: 29px;
    background-color: #fff;
    bottom: 0;
    left: -1px;
    }
    .border-sub-condition{
      border-left: 1px solid #ddd;
    }
    .sub-condition-wrap{
      position: relative;
    }
  }
  .unite-condition:before{
     content: '';
    position: absolute;
    width: 16px;
    height: 1px;
    background-color: #c9c9c9;
    top: 20px;
    left: -16px;
  }
  .sub-condition-wrap:before{
     content: '';
    position: absolute;
    width: 1px;
    height: 50px;
    background-color: #fff;
    top: 20px;
    left: -132px;
  }
</style>

app中调用

<template>
  <div id="app">
    <ConditionView
                        disabled={disabled}
                        ruleId={id}
                        rootCondition={rootCondition}
                        dispatch={dispatch}
                        constants={constants}
                        variables={variables}
                        funcs={funcs}
                      />
  </div>
</template>

<script>
import ConditionView from './components/ConditionView.vue'

export default {
  name: 'App',
  components: {
    ConditionView
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

 类似资料: