图形化设置数据库规则

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 {
    width: 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="width: 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 {
  width: 90%;
}
.filter-group {
  width: 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;
      width: 27px;
      height: 27px;
      border-radius: 50%;
      font-size: 12px;
      color: #2491f7;
      text-align: center;
      line-height: 26px;
    }

    &.line {
      top: 0px;
      height: 100%;
      width: 2px;
      background: #ddefff;
    }
  }
}
</style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值