From 36ceb699fe0a935df84c91cfedb672fb2859201e Mon Sep 17 00:00:00 2001 From: lxmdream Date: Fri, 15 Mar 2024 18:59:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=90=9C=E7=B4=A2=E6=A0=8F=E6=94=AF?= =?UTF-8?q?=E6=8C=81exists=E6=93=8D=E4=BD=9C=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../filter-mode-select/filter-mode-select.tsx | 2 + .../search-bar/filter-tree/filter-tree.scss | 10 ++ .../search-bar/filter-tree/filter-tree.tsx | 144 ++++++++++++++++-- 3 files changed, 141 insertions(+), 15 deletions(-) diff --git a/src/control/search-bar/filter-mode-select/filter-mode-select.tsx b/src/control/search-bar/filter-mode-select/filter-mode-select.tsx index 024afdeb..cd41dd31 100644 --- a/src/control/search-bar/filter-mode-select/filter-mode-select.tsx +++ b/src/control/search-bar/filter-mode-select/filter-mode-select.tsx @@ -15,6 +15,8 @@ const FilterModes = [ { valueOP: ValueOP.LIKE, label: '文本包含(%)' }, { valueOP: ValueOP.LIFT_LIKE, label: '文本左包含(%#)' }, { valueOP: ValueOP.RIGHT_LIKE, label: '文本右包含(#%)' }, + { valueOP: ValueOP.EXISTS, label: '存在(EXISTS)' }, + { valueOP: ValueOP.NOT_EXISTS, label: '不存在(NOTEXISTS)' }, ] as const; export const FilterModeSelect = defineComponent({ diff --git a/src/control/search-bar/filter-tree/filter-tree.scss b/src/control/search-bar/filter-tree/filter-tree.scss index f6625085..0f67d329 100644 --- a/src/control/search-bar/filter-tree/filter-tree.scss +++ b/src/control/search-bar/filter-tree/filter-tree.scss @@ -66,6 +66,16 @@ color: getCssVar(color, danger,hover) } } + + // Exists和not exists样式 + @include m(items){ + > .#{bem(filter-tree-group, actions)}{ + display: flex; + > .#{bem(filter-tree-item)}{ + width: auto; + } + } + } } @include b(filter-tree-item){ diff --git a/src/control/search-bar/filter-tree/filter-tree.tsx b/src/control/search-bar/filter-tree/filter-tree.tsx index b747a7dc..380ce56a 100644 --- a/src/control/search-bar/filter-tree/filter-tree.tsx +++ b/src/control/search-bar/filter-tree/filter-tree.tsx @@ -4,12 +4,19 @@ import { IFilterLeafNode, IFilterNode, SearchBarFilterController, + SearchBarFilterItemsController, ValueOP, } from '@ibiz-template/runtime'; import { useNamespace } from '@ibiz-template/vue3-util'; import { computed, defineComponent, h, PropType, resolveComponent } from 'vue'; import './filter-tree.scss'; +type FieldInfo = { + name: string; + label: string; + valueOPs: string[]; +}; + const FilterModes = [ { valueOP: ValueOP.EQ, label: '等于(=)' }, { valueOP: ValueOP.NOT_EQ, label: '不等于(<>)' }, @@ -24,6 +31,8 @@ const FilterModes = [ { valueOP: ValueOP.LIKE, label: '文本包含(%)' }, { valueOP: ValueOP.LIFT_LIKE, label: '文本左包含(%#)' }, { valueOP: ValueOP.RIGHT_LIKE, label: '文本右包含(#%)' }, + { valueOP: ValueOP.EXISTS, label: '存在(EXISTS)' }, + { valueOP: ValueOP.NOT_EXISTS, label: '不存在(NOTEXISTS)' }, ] as const; /** 不需要编辑器的OP */ @@ -84,17 +93,16 @@ export const FilterTreeControl = defineComponent({ }); }; - const allFields: Array<{ - name: string; - label: string; - valueOPs: string[]; - }> = []; + const allFields: Array = []; - const getFilterModes = (fieldName: string | null) => { + const getFilterModes = ( + fieldName: string | null, + fieldInfos: FieldInfo[] = allFields, + ) => { if (!fieldName) { return; } - const field = allFields.find(item => item.name === fieldName); + const field = fieldInfos.find(item => item.name === fieldName); if (!field) { return; } @@ -123,7 +131,13 @@ export const FilterTreeControl = defineComponent({ */ const onFieldSelect = (node: IFilterLeafNode, field: string) => { node.value = null; + node.valueOP = null; node.field = field; + Object.assign(node, { + leaf: true, + logicType: undefined, + children: undefined, + }); }; /** @@ -137,6 +151,21 @@ export const FilterTreeControl = defineComponent({ node.valueOP = valueOP; // 修改条件的同时清空后面的值 node.value = null; + + // 操作父改成存在或者不存在的时候调整参数,变成分组接口 + if (['EXISTS', 'NOTEXISTS'].includes(valueOP)) { + Object.assign(node, { + leaf: false, + logicType: 'ITEMS', + children: [{ leaf: true, field: null, valueOP: null, value: null }], + }); + } else { + Object.assign(node, { + leaf: true, + logicType: undefined, + children: undefined, + }); + } }; /** @@ -224,9 +253,34 @@ export const FilterTreeControl = defineComponent({ * @param node * @returns */ - const renderFilterItem = (node: IFilterLeafNode) => { - const filterC = findFilterController(node.field, node.valueOP); - const availableModes = getFilterModes(node.field); + const renderFilterItem = ( + node: IFilterLeafNode, + itemsC?: SearchBarFilterItemsController, + ) => { + let fieldInfos = allFields; + if (itemsC) { + fieldInfos = itemsC.allFields; + } + const availableModes = getFilterModes(node.field, fieldInfos); + + let editor = null; + if (node.field && node.valueOP) { + // 当属性和操作符号都选择之后才绘制编辑器 + if (itemsC) { + // items的时候编辑器由子filterController控制 + const subFilterC = itemsC.getSubFilterController( + node.field!, + node.valueOP!, + ); + editor = renderEditor(node, subFilterC); + } else { + const filterC = findFilterController(node.field, node.valueOP); + if (filterC && !['EXISTS', 'NOTEXISTS'].includes(filterC.valueOP!)) { + editor = renderEditor(node, filterC); + } + } + } + return (
- {allFields.map(field => { + {fieldInfos.map(field => { return ( )} - {filterC && renderEditor(node, filterC)} + {editor}
); }; + /** 仅占位 */ + let renderFilterItems = (_node: IFilterBranchNode) =>
; + /** * 绘制过滤分组 * @param node * @returns */ - const renderFilterGroup = (node: IFilterBranchNode) => { + const renderFilterGroup = ( + node: IFilterBranchNode, + itemsC?: SearchBarFilterItemsController, + ) => { + if (node.logicType === 'ITEMS') { + return renderFilterItems(node); + } + return (
@@ -306,8 +370,8 @@ export const FilterTreeControl = defineComponent({ {node.children.length > 0 && node.children.map((child, index) => { const childContent = child.leaf - ? renderFilterItem(child) - : renderFilterGroup(child); + ? renderFilterItem(child, itemsC) + : renderFilterGroup(child, itemsC); return (
@@ -330,6 +394,56 @@ export const FilterTreeControl = defineComponent({ ); }; + /** + * 绘制存在,不存在分组 + * @author lxm + * @date 2024-03-14 01:13:23 + * @param {IFilterBranchNode} node + */ + renderFilterItems = (node: IFilterBranchNode) => { + const itemsC = findFilterController( + (node as IData as IFilterLeafNode).field, + node.valueOP!, + ) as SearchBarFilterItemsController; + return ( +
+
+ {renderFilterItem(node as IData as IFilterLeafNode)} + { + addItem(node); + }} + > + 添加项 + +
+
+ {node.children.length > 0 && + node.children.map((child, index) => { + const childContent = child.leaf + ? renderFilterItem(child, itemsC) + : renderFilterGroup(child, itemsC); + + return ( +
+
AND
+ {childContent} + { + node.children.splice(index, 1); + }} + icon={{ cssClass: 'trash' }} + > +
+ ); + })} +
+
+ ); + }; + /** * 确认 */ -- Gitee