图形化设置数据库规则

 

dataFilters.vue
<template>
  <div class="filter">
    <div class="groupAdd" @click="addCondition">
      <a-icon type="plus-circle" theme="twoTone" two-tone-color="#52c41a" />
      <span>数据过滤</span>
    </div>
    <div class="list" :style="{ maxHeight: height + 'px' }">
      <data-filter-group
        :key="filter.key"
        :filter="filter"
        :deep="1"
        :columns="columns"
        @modifyed="filter.key = new Date().getTime()"
      />
    </div>
  </div>
</template>

<script>
import DataFilterGroup from './DataFilterGroup'
export default {
  name: 'dataFilters',
  components: {
    DataFilterGroup,
  },

  props: {
//下拉框中的数据 columns: { type: Array
| Object, default: () => {}, required: false, }, height: { type: Number, default: 200, }, filter: { type: Object | Array, default: () => { return { label: '且', operate: 'and', conditions: [], key: "key1", } }, required: false, }, }, data() { return { defaultFilter: { column: null, operate: null, value: null, function: null, key: null }, } }, watch: { filter(val) { if (typeof val === 'undefined' || Object.keys(val).length == 0) { this.filter={ label: '且', operate: 'and', conditions: [], key: 1, } }else{ this.filter=val } }, }, computed: {}, mounted() {}, methods: { addCondition() { let obj = JSON.parse(JSON.stringify(this.defaultFilter)) obj.key = new Date().getTime() this.filter.conditions.push(obj) this.filter.key = new Date().getTime() }, }, } </script> <style lang='less' scoped> .groupAdd { line-height: 20px; padding: 10px; cursor: pointer; display: inline-block; & i { font-size: 20px; vertical-align: middle; } & span { padding: 0px 10px; user-select: none; } } .list { overflow-y: auto; &::-webkit-scrollbar { 8px; height: 8px; background-color: #f5f5f5 !important; } &::-webkit-scrollbar-track { background: #f6f6f6 !important; border-radius: 2px; } &::-webkit-scrollbar-thumb { border-radius: 10px; -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); background-color: #6f6f6f !important; /*background: #cd4426;*/ /*border-radius:2px;*/ } &::-webkit-scrollbar-thumb:hover { background: #747474; } &::-webkit-scrollbar-corner { background: #f6f6f6; } } </style>
DataFilterGroup.vue
<template>
  <div class="filter-group">
    <div v-for="(item, index) in filter.conditions" :key="index">
      <data-filter-group
        v-if="item.conditions instanceof Array"
        :filter="item"
        :columns="columns"
        :deep="2"
        @upSub="upSubFilter"
        @modifyed="$emit('modifyed', filter)"
      ></data-filter-group>
      <a-row class="filter-component" :gutter="15" v-else>
        <a-col :span="7" v-if="columns instanceof Array">
          <a-select v-model="item.column">
            <a-select-option v-for="(option, index) in columns" :key="index" :value="option.id"
              >{{ option.columnCode }} / {{ option.columnName }}</a-select-option
            >
          </a-select>
        </a-col>
        <a-col :span="7" v-else>
          <a-tree-select
            tree-node-filter-prop="title"
            v-model="item.column"
            show-search
            style=" 100%"
            :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
            placeholder="请选择"
            allow-clear
            tree-default-expand-all
          >
            <a-tree-select-node
              v-for="(value, key) in columns"
              :key="key"
              :selectable="false"
              :value="key"
              :title="key"
            >
              <a-tree-select-node
                v-for="(option, index) in value"
                :key="index"
                :value="key.split('(')[1].replace(')', '') + '.' + option.id"
                :title="option.columnCode + '/' + option.columnName"
              />
            </a-tree-select-node>
          </a-tree-select>
        </a-col>

        <a-col :span="7">
          <a-select v-model="item.operate" placeholder="请选择过滤条件">
            <a-select-option v-for="(item, index) in filterTypes" :key="index" :value="item.value">{{
              item.text
            }}</a-select-option>
          </a-select>
        </a-col>
        <a-col :span="7">
          <a-input v-model="item.value" placeholder="请输入值" />
        </a-col>
        <a-col :span="3" class="filter-buttons">
          <a-space>
            <a-icon class="filter-option delete" type="minus-circle-o" @click="removeCondition(item, index)" />
            <a-icon class="filter-option add" type="plus-circle" @click="addCondition(item, index)" />
          </a-space>
        </a-col>
      </a-row>
    </div>
    <div
      class="relation line"
      v-if="filter.conditions && filter.conditions instanceof Array && filter.conditions.length > 1"
    ></div>
    <span
      class="relation button"
      @click="switchClick(filter)"
      v-if="filter.conditions && filter.conditions instanceof Array && filter.conditions.length > 1"
      >{{ filter.label }}</span
    >
  </div>
</template>

<script>
import { initDictOptions, filterDictText } from '@/components/dict/JDictSelectUtil'
export default {
  name: 'DataFilterGroup',

  components: {},

  props: {
    columns: {
      type: Array | Object,
      default: () => [],
      required: true,
    },
    deep: {
      type: Number,
      require: true,
      default: 1,
    },
    filter: {
      require: true,
      type: Array | Object,
    },
  },

  data () {
    return {
      filterGroup: {
        label: '且',
        key: null,
        operate: 'and',
        conditions: [{ column: null, operate: null, value: null, function: null, key: null }],
      },
      filterTypes: [],
      subFilter: { column: null, operate: null, value: null, function: null, key: null },
    }
  },

  computed: {},

  mounted () {
    this.initDictConfig()
  },

  methods: {
    generateKey () {
      return new Date().getTime()
    },
    addCondition (item, index) {
      // 一级的增加按钮,点击后将当前降级成子级,并添加一条新过滤条件
      if (this.deep == 1) {
        let group = Object.assign({ key: this.generateKey() }, this.filterGroup)
        group.conditions.splice(0, 0, JSON.parse(JSON.stringify(item)))
        this.filter.conditions[index] = group
      } else {
        let subfilter = JSON.parse(JSON.stringify(this.subFilter))
        subfilter.key = this.generateKey()
        this.filter.conditions.push(subfilter)
        this.filter.key = this.generateKey()
      }
      this.$emit('modifyed', this.filter)
    },
    removeCondition (item, index) {
      console.log('removeCondition', this.deep, this.filter)
      //   第一级时,直接减
      if (this.deep == 1) {
        this.filter.conditions.splice(index, 1)
      } else {
        // 第二级时,判断减完后是不是只剩一个,只剩一个时,将子级提升到一级,
        this.filter.conditions.splice(index, 1)

        if (this.filter.conditions.length == 1) {
          //由于组件自我递归调用,子级无法修改当前对象,需向上冒泡给父级,进行调整。
          this.$emit('upSub', this.filter, index)
        }
      }
      this.$emit('modifyed', this.filter)
    },

    //接收子级冒泡,将孙级变为子级
    upSubFilter (subFilter, index) {
      for (let i = 0; i < this.filter.conditions.length; i++) {
        if (this.filter.conditions[i].key == subFilter.key) {
          let obj = JSON.parse(JSON.stringify(subFilter.conditions[0]))
          this.filter.conditions[i] = obj
        }
      }
      console.log('upSubFilter', this.deep, this.filter)
    },
    switchClick (val) {
      if (val.label === '或') {
        val.label = '且'
        val.operate = 'and'
      } else {
        val.label = '或'
        val.operate = 'or'
      }
      this.$emit('modifyed', this.filter)
    },
  },
}
</script>
<style lang='less' scoped>
.filter-component {
   90%;
}
.filter-group {
   96%;
  position: relative;
  padding-left: 30px;
  margin-bottom: 20px;

  & .filter-option {
    font-size: 20px;
    cursor: pointer;
    display: inline-block;

    &.add {
      color: #1890ff;
    }
    &.delete {
      color: rgb(226, 189, 119);
      transition: all 0.3s;

      &:hover {
        color: rgb(243, 12, 12);
      }
    }
  }
  & .relation {
    position: absolute;
    left: 15px;
    user-select: none;
    &.button {
      cursor: pointer;
      top: 50%;
      top: 50%;
      margin-top: -13px;
      margin-left: -13px;
      position: absolute;
      background: #ddefff;
       27px;
      height: 27px;
      border-radius: 50%;
      font-size: 12px;
      color: #2491f7;
      text-align: center;
      line-height: 26px;
    }

    &.line {
      top: 0px;
      height: 100%;
       2px;
      background: #ddefff;
    }
  }
}
</style>
请用今天的努力,让明天没有遗憾。
原文地址:https://www.cnblogs.com/cupid10/p/15324174.html