diff --git a/package.json b/package.json index e95f43d..fa63551 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "shrimp-admin", - "version": "0.7.1", + "version": "0.7.5", "private": true, "description": "Shrimp 框架前端 — 消费 ShrimpServer + ShrimpTable 契约的经典 Vue3 + Element Plus 实现", "main": "src/index.ts", diff --git a/src/components/ShrimpTable.vue b/src/components/ShrimpTable.vue index 3f896e1..ee77fec 100644 --- a/src/components/ShrimpTable.vue +++ b/src/components/ShrimpTable.vue @@ -212,9 +212,24 @@ const formFields = computed(() => { return list.filter(f => f.editable !== 'readonly') }) const searchableFields = computed(() => fields.value.filter(f => f.searchable)) +// 递归收集 filterable 字段(含 object/tab 嵌套叶子),生成 key=点路径的"合成字段"。 +// 这样筛选抽屉/buildFilter/URL 同步全按 field.key 走即可——key 就是 condition.level 这种路径。 +function collectFilterablePaths(list: IFieldConfig[], base: string[], out: any[]) { + for (const f of list) { + const path = [...base, f.key] + if (f.filterable) out.push({ ...f, key: path.join('.') }) + if (f.type === 'tab' && Array.isArray((f as any).tabs)) { + for (const t of (f as any).tabs) collectFilterablePaths(t.fields, path, out) + } else if (f.type === 'object' && Array.isArray((f as any).fields)) { + collectFilterablePaths((f as any).fields, path, out) + } + } +} const filterableFields = computed(() => { const lockedKeys = new Set(Object.keys(props.baseFilter || {})) - return fields.value.filter(f => f.filterable && !lockedKeys.has(f.key)) + const out: any[] = [] + collectFilterablePaths(fields.value, [], out) + return out.filter(f => !lockedKeys.has(f.key)) }) const formSlotNames = computed(() => Object.keys(slots).filter(name => name.startsWith('form-')))