diff --git a/packages/core/client/src/block-provider/BlockProvider.tsx b/packages/core/client/src/block-provider/BlockProvider.tsx index 414118bb3f..3480e75661 100644 --- a/packages/core/client/src/block-provider/BlockProvider.tsx +++ b/packages/core/client/src/block-provider/BlockProvider.tsx @@ -52,7 +52,11 @@ const useResource = (props: UseResourceProps) => { } const withoutTableFieldResource = useContext(WithoutTableFieldResource); const __parent = useContext(BlockRequestContext); - if (!withoutTableFieldResource && __parent?.block === 'TableField' && __parent?.resource instanceof TableFieldResource) { + if ( + !withoutTableFieldResource && + __parent?.block === 'TableField' && + __parent?.resource instanceof TableFieldResource + ) { return __parent.resource; } if (!association) { @@ -61,7 +65,7 @@ const useResource = (props: UseResourceProps) => { if (sourceId) { return api.resource(resource, sourceId); } - + return api.resource(resource, record[association?.sourceKey || 'id']); }; @@ -76,14 +80,24 @@ export const useResourceAction = (props, opts = {}) => { const { fields } = useCollection(); const appends = fields?.filter((field) => field.target).map((field) => field.name); const params = useActionParams(props); - if (appends?.length) { + if (!Object.keys(params).includes('appends') && appends?.length) { params['appends'] = appends; } const result = useRequest( - (params) => (action ? resource[action](params).then((res) => res.data) : Promise.resolve({})), + (opts) => { + if (!action) { + return Promise.resolve({}); + } + const actionParams = { ...opts }; + if (params.appends) { + actionParams.appends = params.appends; + } + return resource[action](actionParams).then((res) => res.data); + }, { ...opts, defaultParams: [params], + refreshDeps: [JSON.stringify(params.appends)], }, ); return result; @@ -152,8 +166,8 @@ export const useFilterByTk = () => { return recordIndex; } } - - if (assoc) { + + if (assoc) { const association = getCollectionField(assoc); return record?.[association.targetKey || 'id']; } diff --git a/packages/core/client/src/block-provider/TableBlockProvider.tsx b/packages/core/client/src/block-provider/TableBlockProvider.tsx index 60df78e51e..b6829500cd 100644 --- a/packages/core/client/src/block-provider/TableBlockProvider.tsx +++ b/packages/core/client/src/block-provider/TableBlockProvider.tsx @@ -1,6 +1,7 @@ -import { ArrayField } from '@formily/core'; -import { Schema, useField, useFieldSchema } from '@formily/react'; -import React, { createContext, useContext, useEffect } from 'react'; +import { ArrayField, createForm } from '@formily/core'; +import { FormContext, Schema, useField, useFieldSchema } from '@formily/react'; +import uniq from 'lodash/uniq'; +import React, { createContext, useContext, useEffect, useMemo } from 'react'; import { useCollectionManager } from '../collection-manager'; import { BlockProvider, useBlockRequestContext } from './BlockProvider'; @@ -30,48 +31,69 @@ const InternalTableBlockProvider = (props) => { ); }; -const useAssociationNames = (collection) => { +export const useAssociationNames = (collection) => { const { getCollectionFields } = useCollectionManager(); - const names = getCollectionFields(collection) - ?.filter((field) => field.target) - .map((field) => field.name); - return names; + const collectionFields = getCollectionFields(collection); + const associationFields = new Set(); + for (const collectionField of collectionFields) { + if (collectionField.target) { + associationFields.add(collectionField.name); + const fields = getCollectionFields(collectionField.target); + for (const field of fields) { + if (field.target) { + associationFields.add(`${collectionField.name}.${field.name}`); + } + } + } + } const fieldSchema = useFieldSchema(); const tableSchema = fieldSchema.reduceProperties((buf, schema) => { if (schema['x-component'] === 'TableV2') { return schema; } return buf; - }, null) as Schema; - return tableSchema.reduceProperties((buf, schema) => { - if (schema['x-component'] === 'TableV2.Column') { - const s = schema.reduceProperties((buf, s) => { - if (s['x-collection-field'] && names.includes(s.name)) { - return s; + }, new Schema({})); + return uniq( + tableSchema.reduceProperties((buf, schema) => { + if (schema['x-component'] === 'TableV2.Column') { + const s = schema.reduceProperties((buf, s) => { + const [name] = (s.name as string).split('.'); + if (s['x-collection-field'] && associationFields.has(name)) { + return s; + } + return buf; + }, null); + if (s) { + // 关联字段和关联的关联字段 + const [firstName] = s.name.split('.'); + if (associationFields.has(s.name)) { + buf.push(s.name); + } else if (associationFields.has(firstName)) { + buf.push(firstName); + } } - return buf; - }, null); - if (s) { - buf.push(s.name); } - } - return buf; - }, []); + return buf; + }, []), + ); }; export const TableBlockProvider = (props) => { const params = { ...props.params }; const appends = useAssociationNames(props.collection); + const form = useMemo(() => createForm(), []); if (props.dragSort) { params['sort'] = ['sort']; } - if (appends?.length) { + if (!Object.keys(params).includes('appends')) { params['appends'] = appends; } return ( - - - + + + + + ); }; @@ -119,7 +141,11 @@ export const useTableBlockProps = () => { ctx.service.refresh(); }, onChange({ current, pageSize }, filters, sorter) { - let sort = sorter.order ? (sorter.order === `ascend` ? [sorter.field] : [`-${sorter.field}`]) : globalSort || null; + let sort = sorter.order + ? sorter.order === `ascend` + ? [sorter.field] + : [`-${sorter.field}`] + : globalSort || null; ctx.service.run({ ...ctx.service.params?.[0], page: current, pageSize, sort }); },