Commit 7da2cf4d authored by 张耀's avatar 张耀

feat:

优化指标配置逻辑
parent 26f4c4e9
...@@ -7,33 +7,28 @@ ...@@ -7,33 +7,28 @@
:key="header.prop" :key="header.prop"
:label="header.label" :label="header.label"
:width="header.width"> :width="header.width">
<template #default="{ $index }"> <template #default="{ row, $index }">
<div v-if="header.prop == 'indicator_tag'"> <div v-if="header.prop == 'indicator_tag'">
<el-form-item :prop="`[${$index}].input_indicator_tag`" :rules="tableRules.input_indicator_tag"> <el-form-item :prop="`[${$index}].input_indicator_tag`" :rules="tableRules.input_indicator_tag">
<div class="indictor-tag"> <div class="indictor-tag">
<el-popover <el-popover :visible="row.visible" popper-class="cascader-operation" placement="bottom-start">
:visible="state.form.warningScopeRows[$index].visible"
popper-class="cascader-operation"
placement="bottom-start">
<template #reference> <template #reference>
<el-input <el-input
v-model="state.form.warningScopeRows[$index].input_indicator_tag" v-model="state.form.warningScopeRows[$index].input_indicator_tag"
placeholder="请选择指标标签" placeholder="请选择指标标签"
:ref=" ref="inputRef"
(i_el) => {
inputRef[$index] = i_el;
}
"
@blur="blurInput($index)" @blur="blurInput($index)"
@focus="inputLabel($index, false)" @focus="inputLabel($index, false)"
@input="inputLabel($index, true)"></el-input> @input="inputLabel($index, true)"></el-input>
</template> </template>
<div class="filter-first-tree-lists" @mousedown.prevent=""> <div class="filter-first-tree-lists" @mousedown.prevent="">
<ul class="bg-scroll" v-show="state.form.warningScopeRows[$index].firstOptions.length > 0"> <ul class="bg-scroll" ref="first_options_lists" v-show="row.firstOptions.length > 0">
<li <li
v-for="data in state.form.warningScopeRows[$index].firstOptions" v-for="data in row.firstOptions"
:key="data" :key="data"
:class="{ active: state.form.warningScopeRows[$index].indicator_scope == data.label }"> :class="{
active: row.indicator_scope == data.label,
}">
<div class="first-label-main" @click="chooseTreeFirst($index, data)"> <div class="first-label-main" @click="chooseTreeFirst($index, data)">
<div class="tree-label" v-html="data.label_html"></div> <div class="tree-label" v-html="data.label_html"></div>
<div class="tree-icon"> <div class="tree-icon">
...@@ -47,30 +42,30 @@ ...@@ -47,30 +42,30 @@
</div> </div>
</li> </li>
</ul> </ul>
<ul v-show="state.form.warningScopeRows[$index].firstOptions.length == 0"> <ul v-show="row.firstOptions.length == 0">
<li class="no-data"> <li class="no-data">
{{ {{
state.form.warningScopeRows[$index].input_indicator_tag row.input_indicator_tag
? "未查询到相关指标范围数据" ? row.firstOptionsLoading
? "查询中"
: "未查询到相关指标范围数据"
: "请输入查询" : "请输入查询"
}} }}
</li> </li>
</ul> </ul>
<ul class="bg-scroll" v-show="state.form.warningScopeRows[$index].lastOptions?.length > 0"> <ul class="bg-scroll" v-show="row.lastOptions?.length > 0">
<li <li
v-for="child in state.form.warningScopeRows[$index].lastOptions" v-for="child in row.lastOptions"
:key="child" :key="child"
@click="chooseTreeLast(child, $index, false)" @click="chooseTreeLast(child, $index, false)"
:class="{ active: state.form.warningScopeRows[$index].indicator_tag == child }"> :class="{ active: row.indicator_tag == child }">
{{ child }} {{ child }}
</li> </li>
</ul> </ul>
<ul <ul v-show="row.indicator_scope && row.lastOptions?.length == 0">
v-show=" <li class="no-data">
state.form.warningScopeRows[$index].indicator_scope && {{ row.lastOptionsLoading ? "查询中" : "未查询到相关指标标签" }}
state.form.warningScopeRows[$index].lastOptions?.length == 0 </li>
">
<li class="no-data">未查询到相关指标标签</li>
</ul> </ul>
</div> </div>
</el-popover> </el-popover>
...@@ -167,8 +162,9 @@ const tableRules = { ...@@ -167,8 +162,9 @@ const tableRules = {
const dataTreeDefault = ref([]); const dataTreeDefault = ref([]);
// 是否是输入触发 // 是否是输入触发
const isInput = ref(false); const isInput = ref(false);
const first_options_lists = ref(null);
// 指标输入框元素集合 // 指标输入框元素集合
const inputRef = ref([]); const inputRef = ref(null);
// 监听父组件传过来的指标表达式 // 监听父组件传过来的指标表达式
watch( watch(
() => props.indicator_expression, () => props.indicator_expression,
...@@ -187,7 +183,9 @@ watch( ...@@ -187,7 +183,9 @@ watch(
indicator_scope: "", indicator_scope: "",
indicator_tag: "", indicator_tag: "",
oldQuery: "", oldQuery: "",
firstOptionsLoading: false,
firstOptions: [], firstOptions: [],
lastOptionsLoading: false,
lastOptions: [], lastOptions: [],
cname: "", cname: "",
visible: false, visible: false,
...@@ -201,7 +199,9 @@ watch( ...@@ -201,7 +199,9 @@ watch(
); );
// 选择第一级,获取第二级数据 // 选择第一级,获取第二级数据
const chooseTreeFirst = (index, data, isInfo = false) => { const chooseTreeFirst = (index, data, isInfo = false) => {
state.form.warningScopeRows[index].lastOptionsLoading = true;
let i = ""; let i = "";
// 是否是父组件传过来的默认展示数据
if (!isInfo) { if (!isInfo) {
inputRef.value[index].focus(); inputRef.value[index].focus();
i = state.form.warningScopeRows[index].firstOptions.findIndex((e) => e.label == data.label); i = state.form.warningScopeRows[index].firstOptions.findIndex((e) => e.label == data.label);
...@@ -223,6 +223,7 @@ const chooseTreeFirst = (index, data, isInfo = false) => { ...@@ -223,6 +223,7 @@ const chooseTreeFirst = (index, data, isInfo = false) => {
} }
}) })
.finally(() => { .finally(() => {
state.form.warningScopeRows[index].lastOptionsLoading = false;
if (i === "") return; if (i === "") return;
state.form.warningScopeRows[index].firstOptions[i].isLoading = false; state.form.warningScopeRows[index].firstOptions[i].isLoading = false;
}); });
...@@ -249,6 +250,7 @@ const TreeFilter = (index, type) => { ...@@ -249,6 +250,7 @@ const TreeFilter = (index, type) => {
let options = dataTreeDefault.value; let options = dataTreeDefault.value;
const { input_indicator_tag, oldQuery } = state.form.warningScopeRows[index]; const { input_indicator_tag, oldQuery } = state.form.warningScopeRows[index];
state.form.warningScopeRows[index].firstOptions = []; state.form.warningScopeRows[index].firstOptions = [];
// 如果没有输入,或者清空输入,则清除已选中的所有东西和所有下拉数据,并返回
if (input_indicator_tag == "") { if (input_indicator_tag == "") {
state.form.warningScopeRows[index].lastOptions = []; state.form.warningScopeRows[index].lastOptions = [];
state.form.warningScopeRows[index].indicator_scope = ""; state.form.warningScopeRows[index].indicator_scope = "";
...@@ -256,25 +258,36 @@ const TreeFilter = (index, type) => { ...@@ -256,25 +258,36 @@ const TreeFilter = (index, type) => {
state.form.warningScopeRows[index].oldQuery = ""; state.form.warningScopeRows[index].oldQuery = "";
return; return;
} }
// 如果只是聚焦,则使用旧的输入查询过滤,如果是输入,则使用输入的内容过滤
let query = type ? input_indicator_tag : oldQuery; let query = type ? input_indicator_tag : oldQuery;
// 提升性能问题使用for循环遍历
for (let i = 0; i < options.length; i++) { for (let i = 0; i < options.length; i++) {
if (options[i].label.includes(query)) { // 不符合直接跳出当次循环
state.form.warningScopeRows[index].firstOptions.push({ if (!options[i].label.includes(query)) continue;
...options[i], state.form.warningScopeRows[index].firstOptions.push({
label_html: options[i].label.replaceAll( ...options[i],
input_indicator_tag, // 高亮显示和输入匹配的项
`<span class='mate-str'>${input_indicator_tag}</span>` label_html: options[i].label.replaceAll(
), input_indicator_tag,
}); `<span class='mate-str'>${input_indicator_tag}</span>`
} ),
});
} }
// 如果第一级下拉没有数据,则隐藏第二级下拉,并清除当前现在的指标范围
if (state.form.warningScopeRows[index].firstOptions.length == 0) { if (state.form.warningScopeRows[index].firstOptions.length == 0) {
state.form.warningScopeRows[index].lastOptions = []; state.form.warningScopeRows[index].lastOptions = [];
state.form.warningScopeRows[index].indicator_scope = ""; state.form.warningScopeRows[index].indicator_scope = "";
} }
// 结束查询中
state.form.warningScopeRows[index].firstOptionsLoading = false;
// 查询后第一级滚动条滚动到顶部
first_options_lists.value[index].scrollTop = 0;
}; };
// 输入模糊查询数据 // 输入模糊查询数据
const inputLabel = async (index, type) => { const inputLabel = async (index, type) => {
// 第一级显示查询中
state.form.warningScopeRows[index].firstOptionsLoading = true;
// 记录当前是聚焦还是输入
inputType.value = type; inputType.value = type;
// 用户输入节流 // 用户输入节流
if (timer) { if (timer) {
...@@ -284,15 +297,19 @@ const inputLabel = async (index, type) => { ...@@ -284,15 +297,19 @@ const inputLabel = async (index, type) => {
timer = setTimeout( timer = setTimeout(
() => { () => {
state.form.warningScopeRows[index].visible = true; state.form.warningScopeRows[index].visible = true;
// 过滤下拉数据
TreeFilter(index, type); TreeFilter(index, type);
}, },
// 如果是聚集input的时候不需要节流,输入节流
type ? 500 : 0 type ? 500 : 0
); );
}; };
// 失去焦点是隐藏popper // 失去焦点是隐藏popper
const blurInput = (index) => { const blurInput = (index) => {
const { input_indicator_tag, oldQuery } = state.form.warningScopeRows[index]; const { input_indicator_tag, oldQuery } = state.form.warningScopeRows[index];
// 判断是聚焦失去焦点还是输入后失去焦点,输入后失去焦点记录输入的内容,聚焦失去焦点还是使用之前的记录
state.form.warningScopeRows[index].oldQuery = inputType.value ? input_indicator_tag : oldQuery; state.form.warningScopeRows[index].oldQuery = inputType.value ? input_indicator_tag : oldQuery;
// 隐藏popper
state.form.warningScopeRows[index].visible = false; state.form.warningScopeRows[index].visible = false;
}; };
// 选择范围中的属性 // 选择范围中的属性
...@@ -336,7 +353,9 @@ watch( ...@@ -336,7 +353,9 @@ watch(
input_indicator_tag: e.indicator_tag, input_indicator_tag: e.indicator_tag,
indicator_scope: e.indicator_scope, indicator_scope: e.indicator_scope,
indicator_tag: e.indicator_tag, indicator_tag: e.indicator_tag,
firstOptionsLoading: false,
firstOptions: [], firstOptions: [],
lastOptionsLoading: false,
lastOptions: [], lastOptions: [],
oldQuery: e.indicator_scope, oldQuery: e.indicator_scope,
visible: false, visible: false,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment