|
@@ -0,0 +1,690 @@
|
|
|
|
+<template>
|
|
|
|
+ <div class="filter-setting-box">
|
|
|
|
+ <div class="group">
|
|
|
|
+ <div class="name">过滤器</div>
|
|
|
|
+ <div class="middle" @click="onEditRelation">编辑结构</div>
|
|
|
|
+ <div :class="{ btn: 1, active }" >
|
|
|
|
+ <el-popover placement="bottom-start" trigger="click">
|
|
|
|
+ <div style="display: flex">
|
|
|
|
+ <div style="margin-right: 10px;max-height: 300px;overflow-y: auto">
|
|
|
|
+ <p>引用字段</p>
|
|
|
|
+ <template v-for="field of tobeChooseWeidu">
|
|
|
|
+ <div :key="field.columnTitle" :title="field.columnName" class="weidu" @click="setJarValueFun(field)">
|
|
|
|
+ {{ field.columnTitle + '【' + field.columnName + '】' }}
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+ <template v-for="field of tobeChooseZhibiao">
|
|
|
|
+ <div :key="field.columnTitle" :title="field.columnName" class="zhibiao" @click="setJarValueFun(field)">
|
|
|
|
+ {{ field.columnTitle + '【' + field.columnName + '】' }}
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <el-button slot="reference" type="text" size="mini">选择字段<i class="el-icon-d-arrow-right"></i></el-button>
|
|
|
|
+ </el-popover>
|
|
|
|
+
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <draggable v-model="config.filter" :animation="150" :class="{ 'selected-box': 1, 'item-box': 1, active }">
|
|
|
|
+ <div :class="['item', 'selected', field.dimensionType]" v-for="(field, i) of config.filter" :key="i">
|
|
|
|
+ <div class="name" :title="field.columnTitle + ' ' + field.columnName">
|
|
|
|
+ {{ field.columnTitle + " " + field.columnName }}
|
|
|
|
+ </div>
|
|
|
|
+ <i class="el-icon-setting" style="margin-right: 5px; cursor: pointer" @click="onEditFilter(field, 1)"></i>
|
|
|
|
+ <i class="el-icon-close" @click="onFieldDel(i)"></i>
|
|
|
|
+ </div>
|
|
|
|
+ </draggable>
|
|
|
|
+ <!-- 过滤器编辑框 -->
|
|
|
|
+ <el-dialog append-to-body :visible.sync="showEditFilter" title="编辑过滤器" custom-class="bigdata-filter"
|
|
|
|
+ width="560px">
|
|
|
|
+ <div v-if="nowFilter">
|
|
|
|
+ <el-form size="mini" label-width="80px">
|
|
|
|
+ <el-form-item label="当前字段">
|
|
|
|
+ <div :class="['now-filter', nowFilter.dimensionType]">
|
|
|
|
+ <div class="name"> {{ nowFilter.columnTitle + " " + nowFilter.columnName }}</div>
|
|
|
|
+ <div style="color: #999"> {{ datatypeMap[nowFilter.viewDataType] }}</div>
|
|
|
|
+ </div>
|
|
|
|
+ </el-form-item>
|
|
|
|
+<!-- <el-form-item label="作为筛选">-->
|
|
|
|
+<!-- <el-switch v-model="nowFilter.asFilter"></el-switch>-->
|
|
|
|
+<!-- </el-form-item>-->
|
|
|
|
+ <el-form-item label="过滤时机" v-show="toggleType === 1">
|
|
|
|
+ <el-radio-group v-model="nowFilter.connectTime" @change="onConnectTimeChange">
|
|
|
|
+ <el-radio label="where">where</el-radio>
|
|
|
|
+<!-- <el-radio label="having" :disabled="countFilterTime()"> 聚合后(having)</el-radio>-->
|
|
|
|
+ </el-radio-group>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item label="聚合方式" v-if="countCanAggregation(nowFilter)">
|
|
|
|
+ <el-select v-model="nowFilter.aggregationType">
|
|
|
|
+ <el-option
|
|
|
|
+ v-for="item of fieldAggregates" :key="item.label" :label="item.label" :value="item.value"
|
|
|
|
+ ></el-option>
|
|
|
|
+ </el-select>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <el-form-item label="连接方式">
|
|
|
|
+ <el-radio-group v-model="nowFilter.connectType">
|
|
|
|
+ <el-radio label="and">且</el-radio>
|
|
|
|
+ <el-radio label="or">或</el-radio>
|
|
|
|
+ </el-radio-group>
|
|
|
|
+ </el-form-item>
|
|
|
|
+<!-- <el-form-item label="枚举来源" v-show="countEnumShow()">-->
|
|
|
|
+<!-- <el-radio-group v-model="nowFilter.enumSource" @change="nowFilter.enumId=''">-->
|
|
|
|
+<!-- <el-radio label="1">原始数据聚合</el-radio>-->
|
|
|
|
+<!-- <el-radio label="2">api</el-radio>-->
|
|
|
|
+<!-- <el-radio label="3">自定义字典</el-radio>-->
|
|
|
|
+<!-- </el-radio-group>-->
|
|
|
|
+<!-- <el-button-->
|
|
|
|
+<!-- size="mini" icon="el-icon-share" plain type="success" @click="onGetEnumData" style="margin-left: 20px"-->
|
|
|
|
+<!-- >-->
|
|
|
|
+<!-- 获取-->
|
|
|
|
+<!-- </el-button>-->
|
|
|
|
+<!-- </el-form-item>-->
|
|
|
|
+<!-- <el-form-item label="选择api" v-if="countEnumShow() && nowFilter.enumSource === '2'">-->
|
|
|
|
+<!-- <el-cascader-->
|
|
|
|
+<!-- v-model="nowFilter.enumId" :options="apiList" filterable popper-class="bigdata-data-selector"-->
|
|
|
|
+<!-- :props="{ expandTrigger: 'hover', emitPath: false }" :show-all-levels="true" style="width: 400px"-->
|
|
|
|
+<!-- ></el-cascader>-->
|
|
|
|
+<!-- </el-form-item>-->
|
|
|
|
+<!-- <el-form-item label="选择字典" v-if="countEnumShow() && nowFilter.enumSource === '3'">-->
|
|
|
|
+<!-- <el-select v-model="nowFilter.enumId" filterable>-->
|
|
|
|
+<!-- <el-option v-for="(item, i) of dictList" :key="i" :value="item.id" :label="item.keyCode"></el-option>-->
|
|
|
|
+<!-- </el-select>-->
|
|
|
|
+<!-- </el-form-item>-->
|
|
|
|
+ <el-form-item label="过滤条件">
|
|
|
|
+ <div class="filter-item" v-for="(condition, i) of nowFilter.conditions" :key="i">
|
|
|
|
+ <el-select
|
|
|
|
+ size="mini" v-model="condition.function" style="width: 100px; margin-right: 10px"
|
|
|
|
+ placeholder="选择条件" @change="onFunctionChange"
|
|
|
|
+ >
|
|
|
|
+ <el-option
|
|
|
|
+ v-for="func of functions[nowFilter.viewDataType]" :key="func.function" :value="func.function"
|
|
|
|
+ :label="func.label"
|
|
|
|
+ ></el-option>
|
|
|
|
+ </el-select>
|
|
|
|
+ <!-- 日期类型 -->
|
|
|
|
+ <template v-if="nowFilter.viewDataType === 'DATETIME'">
|
|
|
|
+ <el-select
|
|
|
|
+ v-model="condition.timeType" style="width: 95px; margin-right: 5px"
|
|
|
|
+ @change="onTimeTypeChange(condition)"
|
|
|
|
+ >
|
|
|
|
+ <el-option label="绝对时间" value="absolute"></el-option>
|
|
|
|
+ <el-option label="相对时间" value="relative"></el-option>
|
|
|
|
+ </el-select>
|
|
|
|
+ <template v-if="condition.timeType === 'relative'">
|
|
|
|
+ <el-input style="width: 120px; margin-right: 5px" v-model="condition.values[0]">
|
|
|
|
+ <template slot="append"> {{ timeTypeMap[nowFilter.timeDataFormat] }}</template>
|
|
|
|
+ </el-input>
|
|
|
|
+ <el-select v-model="condition.countType" style="width: 60px">
|
|
|
|
+ <el-option label="前" value="left"></el-option>
|
|
|
|
+ <el-option label="后" value="right"></el-option>
|
|
|
|
+ </el-select>
|
|
|
|
+ </template>
|
|
|
|
+ <template v-else>
|
|
|
|
+ <template v-if="nowFilter.dateType === 'time'">
|
|
|
|
+ <el-date-picker
|
|
|
|
+ style="width: 200px" v-model="condition.values[0]" type="datetime"
|
|
|
|
+ placeholder="选择日期时间" :value-format="nowFilter.dateFormat"
|
|
|
|
+ ></el-date-picker>
|
|
|
|
+ <el-date-picker
|
|
|
|
+ v-if="condition.function === 'between'" style="width: 200px" v-model="condition.values[1]"
|
|
|
|
+ type="datetime" placeholder="选择日期时间" :value-format="nowFilter.dateFormat"
|
|
|
|
+ ></el-date-picker>
|
|
|
|
+ </template>
|
|
|
|
+ <template v-else-if="['year', 'month', 'date'].includes(nowFilter.dateType)">
|
|
|
|
+ <el-date-picker
|
|
|
|
+ style="width: 200px" v-model="condition.values[0]" :type="nowFilter.dateType"
|
|
|
|
+ placeholder="选择日期" :value-format="nowFilter.dateFormat"
|
|
|
|
+ ></el-date-picker>
|
|
|
|
+ <el-date-picker
|
|
|
|
+ v-if="condition.function === 'between'" style="width: 200px" v-model="condition.values[1]"
|
|
|
|
+ :type="nowFilter.dateType" placeholder="选择日期" :value-format="nowFilter.dateFormat"
|
|
|
|
+ ></el-date-picker>
|
|
|
|
+ </template>
|
|
|
|
+ <template v-else>
|
|
|
|
+ <el-time-select
|
|
|
|
+ style="width: 200px" v-model="condition.values[0]" placeholder="选择时间"
|
|
|
|
+ :value-format="nowFilter.dateFormat"
|
|
|
|
+ ></el-time-select>
|
|
|
|
+ <el-time-select
|
|
|
|
+ v-if="condition.function === 'between'" style="width: 200px" v-model="condition.values[1]"
|
|
|
|
+ placeholder="选择时间" :value-format="nowFilter.dateFormat"
|
|
|
|
+ ></el-time-select>
|
|
|
|
+ </template>
|
|
|
|
+ </template>
|
|
|
|
+ </template>
|
|
|
|
+ <template v-else>
|
|
|
|
+ <template v-if="['in', 'notIn'].includes(condition.function)">
|
|
|
|
+ <el-cascader
|
|
|
|
+ v-model="condition.values" :options="nowFilter.options"
|
|
|
|
+ :props="{expandTrigger: 'hover',emitPath: false,multiple: true,label: 'VALUE',value: 'KEY',}"
|
|
|
|
+ filterable :show-all-levels="false" collapse-tags clearable
|
|
|
|
+ ></el-cascader>
|
|
|
|
+ <el-button size="mini" @click="onEnumSelectAll(nowFilter)" type="primary"> 全选</el-button>
|
|
|
|
+ </template>
|
|
|
|
+ <template v-else-if="['indexIn'].includes(condition.function)">
|
|
|
|
+ <el-input style="width: 200px" size="mini" v-model="condition.values[0]" placeholder="默认使用第几条">
|
|
|
|
+ </el-input>
|
|
|
|
+ </template>
|
|
|
|
+ <span v-else-if="['isnull', 'notnull'].includes(condition.function)"></span>
|
|
|
|
+ <el-input v-else style="width: 200px" size="mini" v-model="condition.values[0]" placeholder="输入值">
|
|
|
|
+ </el-input>
|
|
|
|
+ </template>
|
|
|
|
+ <i class="el-icon-delete" v-show="nowFilter.conditions.length > 1" @click="onConditionDel(i)"></i>
|
|
|
|
+ </div>
|
|
|
|
+ <el-button size="mini" type="success" plain @click="onConditionAdd" v-show="canAddCondition">
|
|
|
|
+ 添加条件
|
|
|
|
+ </el-button>
|
|
|
|
+ </el-form-item>
|
|
|
|
+ <div class="btns" style="
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: space-evenly;
|
|
|
|
+ margin-top: 30px;
|
|
|
|
+ ">
|
|
|
|
+ <el-button size="small" @click="showEditFilter = false" style="width: 100px"> 取消</el-button>
|
|
|
|
+ <el-button type="primary" size="small" @click="onConditionUpdate" style="width: 100px"> 确定
|
|
|
|
+ </el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </el-form>
|
|
|
|
+ </div>
|
|
|
|
+ </el-dialog>
|
|
|
|
+ <el-dialog
|
|
|
|
+ :visible.sync="showRelationEdit" title="过滤器结构编辑" width="600px" custom-class="filter-relation-dialog"
|
|
|
|
+ append-to-body
|
|
|
|
+ >
|
|
|
|
+ <filter-node :node="relationNode" :level="1" type="where"></filter-node>
|
|
|
|
+ </el-dialog>
|
|
|
|
+ </div>
|
|
|
|
+</template>
|
|
|
|
+<script>
|
|
|
|
+import {getEnumData, onEnumSelectAll} from "./util";
|
|
|
|
+import draggable from "vuedraggable";
|
|
|
|
+import {dictList} from "@/api/newbi/dict";
|
|
|
|
+import {dateTypeMap,functions, timeTypeMap, fieldAggregates,fieldDateFormats} from "./dict";
|
|
|
|
+import filterNode from "./filterNode.vue";
|
|
|
|
+import {cubeFieldList} from "@/api/newbi/dataset";
|
|
|
|
+import util from '@/utils/wey';
|
|
|
|
+
|
|
|
|
+export default {
|
|
|
|
+ components: {draggable, filterNode},
|
|
|
|
+ props: ["config", "active", "selectedFields", "apiList", "chartId", 'maxLevel','dbLinkId'],
|
|
|
|
+ data() {
|
|
|
|
+ return {
|
|
|
|
+ nowFilter: null,
|
|
|
|
+ showEditFilter: false,
|
|
|
|
+ functions,
|
|
|
|
+ timeTypeMap,
|
|
|
|
+ fieldAggregates,dateTypeMap,fieldDateFormats,
|
|
|
|
+ datatypeMap: {NUMBER: "数字", STRING: "字符串", DATETIME: "时间"},
|
|
|
|
+ showRelationEdit: false,
|
|
|
|
+ relationNode: {conditions: [], filters: [], relation: "AND"},
|
|
|
|
+ havingNode: {conditions: [], filters: [], relation: "AND"},
|
|
|
|
+ draggingNode: null,
|
|
|
|
+ draggingIndex: 0,
|
|
|
|
+ draggingType: "where",
|
|
|
|
+ dictList: [],
|
|
|
|
+ toggleType: 1,
|
|
|
|
+ tobeChooseWeidu:[],
|
|
|
|
+ tobeChooseZhibiao:[],
|
|
|
|
+ defaultRelation:
|
|
|
|
+ '{"where":{"conditions":[],"filters":[],"relation":"AND"},"having":{"conditions":[],"filters":[],"relation":"AND"}}',
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+ computed: {
|
|
|
|
+ // 能否添加过滤条件
|
|
|
|
+ canAddCondition() {
|
|
|
|
+ if (!this.nowFilter) return false;
|
|
|
|
+ let func = this.nowFilter.conditions[0].function;
|
|
|
|
+ return !(func === "in" || func === "notIn" || func === "indexIn");
|
|
|
|
+ },
|
|
|
|
+ visualId() {
|
|
|
|
+ let {query, params, fullPath} = this.$route;
|
|
|
|
+ return fullPath.includes("/preview/") ? params.id : query.id;
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ watch: {
|
|
|
|
+ showRelationEdit(val) {
|
|
|
|
+ // 结构编辑框关闭时
|
|
|
|
+ if (!val) {
|
|
|
|
+ let filterRelation = {where: this.relationNode, having: this.havingNode,};
|
|
|
|
+ this.config.filterRelation = JSON.stringify(this.relationNode);
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ provide() {
|
|
|
|
+ return {
|
|
|
|
+ editFilterByUniqId: this.editFilterByUniqId,
|
|
|
|
+ onNodeDrag: this.onNodeDrag,
|
|
|
|
+ onNodeDrop: this.onNodeDrop,
|
|
|
|
+ onDelFilter: this.onDelFilter,
|
|
|
|
+ maxLevel: this.maxLevel,
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+ created() {
|
|
|
|
+ dictList({current: 1, size: 10000}).then((res) => this.dictList = res.data.data.records);
|
|
|
|
+ //获取数据集
|
|
|
|
+ cubeFieldList({ cubeDataId: this.dbLinkId }).then((res) => {
|
|
|
|
+ let tableFieldsWeidu = res.data.data.filter((i) => i.dimensionType === 'WEIDU').sort((a, b) => a.sortNum - b.sortNum)
|
|
|
|
+ let tableFieldsZhibiao = res.data.data.filter((i) => i.dimensionType === 'ZHIBIAO').sort((a, b) => a.sortNum - b.sortNum)
|
|
|
|
+ this.tobeChooseWeidu = tableFieldsWeidu.filter((i) => i.columnAttr == 'NORMAL')
|
|
|
|
+ this.tobeChooseZhibiao = tableFieldsZhibiao.filter((i) => i.columnAttr == 'NORMAL')
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ setJarValueFun(field){
|
|
|
|
+ field.connectTime = 'where'; // 过滤时机 where having
|
|
|
|
+ this.$set( field, 'connectType', 'and')
|
|
|
|
+ field.uniqId = util.getRandomStr(7)
|
|
|
|
+ if (field.viewDataType === 'DATETIME') {
|
|
|
|
+ this.$set( field, 'dateType', this.dateTypeMap[field.timeDataFormat])
|
|
|
|
+ this.$set( field, 'dateFormat', this.fieldDateFormats.find(i => i.value === field.timeDataFormat).label)
|
|
|
|
+ }
|
|
|
|
+ this.$set( field, 'conditions', [{function: "eq", values: ["", ""], timeType: "absolute", countType: "left",connectType:"and",asFilter:true,uniqId: util.getRandomStr(7)}])
|
|
|
|
+ this.config.filter.push(field);
|
|
|
|
+ document.body.click()
|
|
|
|
+ field.conditions.forEach((item,i)=>{
|
|
|
|
+ this.relationNode.conditions.push({uniqId: item.uniqId, columnTitle: field.columnTitle,})
|
|
|
|
+ this.config.filterRelation = JSON.stringify(this.relationNode)
|
|
|
|
+ })
|
|
|
|
+ // if (this.config.filterRelation){
|
|
|
|
+ // let filterRelation = JSON.parse(this.config.filterRelation)
|
|
|
|
+ // filterRelation.conditions.push({uniqId: field.uniqId, columnTitle: field.columnTitle,})
|
|
|
|
+ // this.config.filterRelation = JSON.stringify(filterRelation)
|
|
|
|
+ // }
|
|
|
|
+ },
|
|
|
|
+ countCanAggregation(filter) {
|
|
|
|
+ if (filter.connectTime == 'where') return false;
|
|
|
|
+ if (filter.dimensionType == 'WEIDU') return false;
|
|
|
|
+ if (filter.columnAttr == 'NORMAL') return true;
|
|
|
|
+ return !filter.virtualAggregationStatus;
|
|
|
|
+ },
|
|
|
|
+ onDelFilter(item, node, i) {
|
|
|
|
+ let index = this.config.filter.findIndex(i => i.uniqId == item.uniqId);
|
|
|
|
+ if (index >= 0) {
|
|
|
|
+ this.onFieldDel(index);
|
|
|
|
+ } else {
|
|
|
|
+ node.conditions.splice(i, 1);
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ onGetEnumData() {
|
|
|
|
+ getEnumData(this.nowFilter, this.config.dataId, this.visualId, this.chartId, true);
|
|
|
|
+ },
|
|
|
|
+ // 过滤时机改变时
|
|
|
|
+ onConnectTimeChange() {
|
|
|
|
+ this.config.filterRelation = "";
|
|
|
|
+ },
|
|
|
|
+ // 清除空节点
|
|
|
|
+ clearNullNode(parent, item, index) {
|
|
|
|
+ if (item.conditions && item.conditions.length){
|
|
|
|
+ item.conditions.forEach((node, i) => this.clearNullNode(item, node, i));
|
|
|
|
+ }
|
|
|
|
+ if (item.conditions && !item.conditions.length) {
|
|
|
|
+ parent.conditions.splice(index, 1);
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 节点拖拽完成时
|
|
|
|
+ onNodeDrop(node, type) {
|
|
|
|
+ if (type != this.draggingType) return;
|
|
|
|
+ let item = this.draggingNode.conditions.splice(this.draggingIndex, 1)[0];
|
|
|
|
+ node.conditions.push(item);
|
|
|
|
+ if (type === "where") {
|
|
|
|
+ this.relationNode?.conditions?.forEach((node, index) => this.clearNullNode(this.relationNode, node, index));
|
|
|
|
+ } else {
|
|
|
|
+ this.havingNode.forEach((node, index) => this.clearNullNode(this.havingNode, node, index));
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 开始拖拽某节点
|
|
|
|
+ onNodeDrag(node, index, type) {
|
|
|
|
+ this.draggingNode = node;
|
|
|
|
+ this.draggingIndex = index;
|
|
|
|
+ this.draggingType = type;
|
|
|
|
+ },
|
|
|
|
+ // 结构编辑面板点击编辑过滤器时
|
|
|
|
+ editFilterByUniqId(uniqId) {
|
|
|
|
+ // 遍历 filter 中的每个对象
|
|
|
|
+ this.config.filter.forEach(item => {
|
|
|
|
+ // 检查 conditions 是否存在且不为空
|
|
|
|
+ if (item.conditions && item.conditions.length > 0) {
|
|
|
|
+ // 遍历 conditions 数组中的每个对象
|
|
|
|
+ item.conditions.forEach(condition => {
|
|
|
|
+ // 将 uniqId 添加到 uniqIds 数组中
|
|
|
|
+ if (condition.uniqId === uniqId){
|
|
|
|
+ this.onEditFilter(item, 2);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ // 编辑结构时
|
|
|
|
+ onEditRelation() {
|
|
|
|
+ let relation = this.config.filterRelation;
|
|
|
|
+ if (relation) {
|
|
|
|
+ let where = JSON.parse(relation);
|
|
|
|
+ if (where.conditions && where.conditions.length) {
|
|
|
|
+ this.relationNode = where;
|
|
|
|
+ } else {
|
|
|
|
+ this.initRelation();
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ this.initRelation();
|
|
|
|
+ }
|
|
|
|
+ this.showRelationEdit = true;
|
|
|
|
+ },
|
|
|
|
+ // 初始化过滤器结构
|
|
|
|
+ initRelation() {
|
|
|
|
+ let filterRelation = this.config.filter.filter((i) => i.connectTime === "where");
|
|
|
|
+ // 遍历 filterRelation 定义filterRelation下每个对象为item,如果item下conditions 存在且有长度的 遍历item的 conditions map出来 {uniqId: i.uniqId, columnTitle: item.columnTitle}
|
|
|
|
+ let conditionsList = []
|
|
|
|
+ filterRelation.forEach((item) => {
|
|
|
|
+ let filterItem = item.conditions.map((i) => ({uniqId: i.uniqId, columnTitle: item.columnTitle,}));
|
|
|
|
+ conditionsList = [...conditionsList,...filterItem]
|
|
|
|
+ });
|
|
|
|
+ this.relationNode = {
|
|
|
|
+ conditions: conditionsList,
|
|
|
|
+ relation: "AND",
|
|
|
|
+ };
|
|
|
|
+ },
|
|
|
|
+ onEnumSelectAll(filter) {
|
|
|
|
+ onEnumSelectAll(filter);
|
|
|
|
+ },
|
|
|
|
+ onTimeTypeChange(condition) {
|
|
|
|
+ if (condition.timeType === "relative") {
|
|
|
|
+ condition.values = [1];
|
|
|
|
+ } else {
|
|
|
|
+ condition.values = [""];
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 去掉为空的children
|
|
|
|
+ clearChildren(node) {
|
|
|
|
+ if (!node.children) return;
|
|
|
|
+ if (!node.children.length) {
|
|
|
|
+ delete node.children;
|
|
|
|
+ } else {
|
|
|
|
+ node.children.forEach(this.clearChildren);
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 判断是否展示枚举选项
|
|
|
|
+ countEnumShow() {
|
|
|
|
+ let func = this.nowFilter.conditions[0].function;
|
|
|
|
+ return func === "in" || func === "notIn" || func === "indexIn";
|
|
|
|
+ },
|
|
|
|
+ // 计算函数变化时
|
|
|
|
+ async onFunctionChange(func) {
|
|
|
|
+ if (["in", "notIn", "indexIn"].includes(func)) {
|
|
|
|
+ this.nowFilter.conditions = [{function: func, values: [], timeType: "absolute", countType: "left",},];
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 判断过滤项是否可选择having方式
|
|
|
|
+ countFilterTime() {
|
|
|
|
+ let id = this.nowFilter.cubeColumnId;
|
|
|
|
+ return !this.selectedFields.find((i) => i.cubeColumnId === id);
|
|
|
|
+ },
|
|
|
|
+ // 过滤器添加条件
|
|
|
|
+ onConditionAdd() {
|
|
|
|
+ let addItem = {function: "eq", values: ["", ""], timeType: "absolute", countType: "left",uniqId: util.getRandomStr(7)}
|
|
|
|
+ this.nowFilter.conditions.push(addItem);
|
|
|
|
+ if (this.config.filterRelation){
|
|
|
|
+ this.relationNode.conditions.push({uniqId: addItem.uniqId, columnTitle: this.nowFilter.columnTitle,})
|
|
|
|
+ this.config.filterRelation = JSON.stringify(this.relationNode)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ onConditionUpdate() {
|
|
|
|
+ this.showEditFilter = false
|
|
|
|
+ let itemUniqId = [];
|
|
|
|
+ // 遍历 filter 中的每个对象
|
|
|
|
+ this.config.filter.forEach(item => {
|
|
|
|
+ // 检查 conditions 是否存在且不为空
|
|
|
|
+ if (item.conditions && item.conditions.length > 0) {
|
|
|
|
+ // 遍历 conditions 数组中的每个对象
|
|
|
|
+ item.conditions.forEach(condition => {
|
|
|
|
+ // 将 uniqId 添加到 uniqIds 数组中
|
|
|
|
+ itemUniqId.push(condition.uniqId);
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ this.relationNode?.conditions?.forEach((node, index) => {
|
|
|
|
+ this.updateNullNode(this.relationNode, node,itemUniqId, index);
|
|
|
|
+ });
|
|
|
|
+ if (this.config.filterRelation){
|
|
|
|
+ this.config.filterRelation = JSON.stringify(this.relationNode)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 清除空节点
|
|
|
|
+ updateNullNode(parent, item,itemUniqId, index) {
|
|
|
|
+ if (item?.conditions && item.conditions.length){
|
|
|
|
+ item.conditions.forEach((node, i) => this.updateNullNode(item, node, itemUniqId, i));
|
|
|
|
+ }
|
|
|
|
+ if (!item.conditions && !itemUniqId.includes(item.uniqId)) {
|
|
|
|
+ parent.conditions.splice(index, 1);
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 清除空节点
|
|
|
|
+ // clearNullNode(parent, item, index) {
|
|
|
|
+ // if (item.conditions && item.conditions.length){
|
|
|
|
+ // item.conditions.forEach((node, i) => this.clearNullNode(item, node, i));
|
|
|
|
+ // }
|
|
|
|
+ // if (item.conditions && !item.conditions.length) {
|
|
|
|
+ // parent.conditions.splice(index, 1);
|
|
|
|
+ // }
|
|
|
|
+ // },
|
|
|
|
+ // 过滤器删除条件
|
|
|
|
+ onConditionDel(i) {
|
|
|
|
+ this.nowFilter.conditions.splice(i, 1);
|
|
|
|
+ },
|
|
|
|
+ // 编辑某过滤器时
|
|
|
|
+ onEditFilter(field, toggleType) {
|
|
|
|
+ this.showEditFilter = true;
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
+ this.nowFilter = field;
|
|
|
|
+ this.toggleType = toggleType;
|
|
|
|
+ let relation = this.config.filterRelation;
|
|
|
|
+ if (relation) {
|
|
|
|
+ let where = JSON.parse(relation);
|
|
|
|
+ if (where.conditions && where.conditions.length) {
|
|
|
|
+ this.relationNode = where;
|
|
|
|
+ } else {
|
|
|
|
+ this.initRelation();
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ this.initRelation();
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ // let func = this.nowFilter.conditions[0].function;
|
|
|
|
+ // if (func === "in" || func === "notIn" || func === "indexIn") {
|
|
|
|
+ // if (!this.nowFilter.options.length) {
|
|
|
|
+ // getEnumData(this.nowFilter, this.config.dataId, this.visualId, this.chartId, true);
|
|
|
|
+ // }
|
|
|
|
+ // }
|
|
|
|
+ },
|
|
|
|
+ onFieldDel(index) {
|
|
|
|
+ let item = this.config.filter.splice(index, 1)[0];
|
|
|
|
+ item.conditions.forEach((item1) => {
|
|
|
|
+ let uniqId = item1.uniqId;
|
|
|
|
+ if (this.config.filterRelation){
|
|
|
|
+ let where = JSON.parse(this.config.filterRelation);
|
|
|
|
+ let node = this.getIncludeNode(where, uniqId);
|
|
|
|
+ let index2 = node.conditions.findIndex((i) => i.uniqId === uniqId);
|
|
|
|
+ node.conditions.splice(index2, 1);
|
|
|
|
+ where.conditions.forEach((node, index) => {
|
|
|
|
+ this.clearNullNode(where, node, index);
|
|
|
|
+ });
|
|
|
|
+ this.config.filterRelation = JSON.stringify(where);
|
|
|
|
+ this.relationNode = where;
|
|
|
|
+ this.$forceUpdate();
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ getIncludeNode(node, uniqId) {
|
|
|
|
+ if (node.conditions && node.conditions.length){
|
|
|
|
+ if (node.conditions.find((i) => i.uniqId === uniqId)) {
|
|
|
|
+ return node;
|
|
|
|
+ } else {
|
|
|
|
+ for (let i = 0; i < node.conditions.length; i++) {
|
|
|
|
+ if (node.conditions[i].conditions && node?.conditions[i].conditions.length){
|
|
|
|
+ if (this.getIncludeNode(node?.conditions[i], uniqId)) {
|
|
|
|
+ return node.conditions[i];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+};
|
|
|
|
+</script>
|
|
|
|
+<style lang="scss">
|
|
|
|
+.filter-setting-box {
|
|
|
|
+ .group {
|
|
|
|
+ padding-right: 10px;
|
|
|
|
+ display: -webkit-box;
|
|
|
|
+ display: -ms-flexbox;
|
|
|
|
+ display: flex;
|
|
|
|
+ -webkit-box-align: center;
|
|
|
|
+ -ms-flex-align: center;
|
|
|
|
+ align-items: center;
|
|
|
|
+ height: 40px;
|
|
|
|
+ margin-top: 10px;
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ .name{
|
|
|
|
+ -webkit-box-flex: 1;
|
|
|
|
+ -ms-flex: 1;
|
|
|
|
+ flex: 1;
|
|
|
|
+ font-weight: 600;
|
|
|
|
+ text-indent: 20px;
|
|
|
|
+ }
|
|
|
|
+ .midele{
|
|
|
|
+ margin-right: 10px;
|
|
|
|
+ color: #999;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ }
|
|
|
|
+ .btn {
|
|
|
|
+ color: #999;
|
|
|
|
+ padding: 5px;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ }
|
|
|
|
+ .btn.active {
|
|
|
|
+ color: #409eff;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ .item-box {
|
|
|
|
+ min-height: 30px;
|
|
|
|
+ -webkit-box-sizing: border-box;
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
+ border: 1px dashed #ccc;
|
|
|
|
+ margin-right: 10px;
|
|
|
|
+ padding-right: 0;
|
|
|
|
+ position: relative;
|
|
|
|
+ z-index: 1;
|
|
|
|
+ }
|
|
|
|
+ .item-box.active {
|
|
|
|
+ margin-right: 0;
|
|
|
|
+ padding-right: 10px;
|
|
|
|
+ border: 1px solid #ccc;
|
|
|
|
+ border-right-color: #fff;
|
|
|
|
+ }
|
|
|
|
+ .item {
|
|
|
|
+ display: -webkit-box;
|
|
|
|
+ display: -ms-flexbox;
|
|
|
|
+ display: flex;
|
|
|
|
+ -webkit-box-align: center;
|
|
|
|
+ -ms-flex-align: center;
|
|
|
|
+ align-items: center;
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ margin: 8px;
|
|
|
|
+ padding: 0 5px 0 10px;
|
|
|
|
+ line-height: 26px;
|
|
|
|
+ height: 26px;
|
|
|
|
+ .name {
|
|
|
|
+ -webkit-box-flex: 1;
|
|
|
|
+ -ms-flex: 1;
|
|
|
|
+ flex: 1;
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ white-space: nowrap;
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
+ margin-right: 5px;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .item.WEIDU {
|
|
|
|
+ border: 1px solid #1d54d5;
|
|
|
|
+ }
|
|
|
|
+ .item.ZHIBIAO {
|
|
|
|
+ border: 1px solid #00b375;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.bigdata-filter {
|
|
|
|
+ width: 660px;
|
|
|
|
+ .el-form-item {
|
|
|
|
+ margin-bottom: 10px;
|
|
|
|
+ }
|
|
|
|
+ .now-filter {
|
|
|
|
+ display: inline-flex;
|
|
|
|
+ font-size: 12px;
|
|
|
|
+ padding: 0 10px;
|
|
|
|
+ line-height: 28px;
|
|
|
|
+ width: 260px;
|
|
|
|
+ .name {
|
|
|
|
+ margin-right: 5px;
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ white-space: nowrap;
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
+ flex: 1;
|
|
|
|
+ }
|
|
|
|
+ &.WEIDU {
|
|
|
|
+ border: 1px solid #1d54d5;
|
|
|
|
+ }
|
|
|
|
+ &.ZHIBIAO {
|
|
|
|
+ border: 1px solid #00b375;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .filter-item {
|
|
|
|
+ padding-bottom: 10px;
|
|
|
|
+ .el-icon-delete {
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ margin-left: 5px;
|
|
|
|
+ color: #f56c6c;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.bigdata-data-setting {
|
|
|
|
+ .right-center-panel {
|
|
|
|
+ .group .middle {
|
|
|
|
+ margin-right: 10px;
|
|
|
|
+ color: #999;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.filter-relation-dialog {
|
|
|
|
+ .el-dialog__body {
|
|
|
|
+ min-height: 600px;
|
|
|
|
+ .title {
|
|
|
|
+ line-height: 40px;
|
|
|
|
+ font-weight: 600;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.weidu {
|
|
|
|
+ line-height: 24px;
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
+ border: 1px solid #1d54d5;
|
|
|
|
+ background-color: #e4eafa;
|
|
|
|
+ padding: 0 10px;
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ white-space: nowrap;
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
+ margin: 3px 0;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+}
|
|
|
|
+.zhibiao {
|
|
|
|
+ line-height: 24px;
|
|
|
|
+ box-sizing: border-box;
|
|
|
|
+ border: 1px solid #00b375;
|
|
|
|
+ background-color: #d4f2e8;
|
|
|
|
+ padding: 0 10px;
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ white-space: nowrap;
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
+ margin: 3px 0;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+}
|
|
|
|
+</style>
|