diff --git a/packages/client/src/components/schema-renderer/index.tsx b/packages/client/src/components/schema-renderer/index.tsx index eafc07a96..e37847f72 100644 --- a/packages/client/src/components/schema-renderer/index.tsx +++ b/packages/client/src/components/schema-renderer/index.tsx @@ -52,7 +52,11 @@ import { Menu } from '../../schemas/menu'; import { Password } from '../../schemas/password'; import { Radio } from '../../schemas/radio'; import { Select } from '../../schemas/select'; -import { Table } from '../../schemas/table'; +import { + CollectionFieldContext, + Table, + TableRowContext, +} from '../../schemas/table'; import { Tabs } from '../../schemas/tabs'; import { TimePicker } from '../../schemas/time-picker'; import { Upload } from '../../schemas/upload'; @@ -69,6 +73,7 @@ import { ISchema, FormilyISchema } from '../../schemas'; import { Resource } from '../../resource'; import { useRequest } from 'ahooks'; import { CascaderOptionType } from 'antd/lib/cascader'; +import { useCollectionContext } from '../../constate'; export const BlockContext = createContext({ dragRef: null }); @@ -149,7 +154,33 @@ const useChinaRegionFieldValue = (field: ArrayField) => { field.value = field?.value?.sort((a, b) => a.level - b.level); } console.log('useChinaRegionFieldValue', field); -} +}; + +const useAssociationResource = (options) => { + const { schema } = useDesignable(); + const collectionField = useContext(CollectionFieldContext); + const { collection } = useCollectionContext(); + const ctx = useContext(TableRowContext); + const associatedKey = ctx?.record?.id; + console.log( + 'useAssociationResource', + collection, + collectionField, + schema['x-component-props'], + ); + const { associatedName, resourceName } = schema['x-component-props'] || {}; + const resource = Resource.make({ + associatedName, + resourceName, + associatedKey, + }); + const service = useRequest((params) => resource.list(params), { + manual: schema['x-component'] === 'Form', + formatResult: (data) => data?.data?.[0] || {}, + onSuccess: options?.onSuccess, + }); + return { resource, service, initialValues: service.data, ...service }; +}; export const SchemaField = createSchemaField({ scope: { @@ -163,6 +194,9 @@ export const SchemaField = createSchemaField({ loadDataSource: loadChinaRegionDataSource, }, Select, + Association: { + useResource: useAssociationResource, + }, }, components: { Card, diff --git a/packages/client/src/resource.ts b/packages/client/src/resource.ts index 33ec627d8..2b3072f9c 100644 --- a/packages/client/src/resource.ts +++ b/packages/client/src/resource.ts @@ -82,8 +82,11 @@ export class Resource { } create(values: any) { - const { resourceName } = this.options; - const url = `${resourceName}:create`; + const { associatedKey, associatedName, resourceName } = this.options; + let url = `${resourceName}:create`; + if (associatedKey && associatedName) { + url = `${associatedName}/${associatedKey}/${url}` + } return request(url, { method: 'post', data: values, @@ -92,8 +95,11 @@ export class Resource { save(values: any, options: SaveOptions = {}) { const resourceKey = options.resourceKey || this.options.resourceKey; - const { resourceName } = this.options; - const url = `${resourceName}:${resourceKey ? `update/${resourceKey}` : 'create'}`; + const { associatedKey, associatedName, resourceName } = this.options; + let url = `${resourceName}:${resourceKey ? `update/${resourceKey}` : 'create'}`; + if (associatedKey && associatedName) { + url = `${associatedName}/${associatedKey}/${url}` + } return request(url, { method: 'post', data: values, diff --git a/packages/client/src/schemas/add-new/index.tsx b/packages/client/src/schemas/add-new/index.tsx index 2bd875173..654def2cc 100644 --- a/packages/client/src/schemas/add-new/index.tsx +++ b/packages/client/src/schemas/add-new/index.tsx @@ -345,6 +345,23 @@ function generateCardItemSchema(component) { }, }, }, + Descriptions: { + type: 'void', + name: uid(), + 'x-decorator': 'CardItem', + 'x-component': 'Form', + 'x-read-pretty': true, + 'x-designable-bar': 'Form.DesignableBar', + properties: { + [uid()]: { + type: 'void', + 'x-component': 'Grid', + 'x-component-props': { + addNewComponent: 'AddNew.FormItem', + }, + }, + }, + }, Kanban: { type: 'array', 'x-component': 'Kanban', @@ -1420,7 +1437,8 @@ AddNew.FormItem = observer((props: any) => { default: [], 'x-component-props': { rowKey: 'id', - defaultSelectedRowKeys: '{{ Select.useSelectedRowKeys() }}', + defaultSelectedRowKeys: + '{{ Select.useSelectedRowKeys() }}', onSelect: '{{ Select.useSelect() }}', collectionName: field.target, // dragSort: true, @@ -1651,6 +1669,7 @@ AddNew.PaneItem = observer((props: any) => { const blockSchema = useContext(BlockSchemaContext); const useResource = `{{ ${blockSchema['x-component']}.useResource }}`; console.log('AddNew.PaneItem.useResource', useResource); + const { collection, fields } = useCollectionContext(); return ( { > 日志 - {/* }> - 评论 - */} + {fields + ?.filter((f) => f.interface === 'linkTo') + ?.map((collectionField) => { + return ( + { + const multiple = + collectionField?.uiSchema?.['x-component-props'] + ?.multiple; + let data = generateCardItemSchema( + multiple ? 'Table' : 'Descriptions', + ); + if (schema['key']) { + data['key'] = uid(); + } + data['x-component-props'] = + data['x-component-props'] || {}; + data['x-component-props']['collectionName'] = + collectionField?.target; + data['x-component-props']['resourceName'] = + collectionField?.name; + data['x-component-props']['associatedName'] = + collection?.name; + data['x-component-props']['useResource'] = + '{{ Association.useResource }}'; + if (isGridBlock(schema)) { + path.pop(); + path.pop(); + data = generateGridBlock(data); + } else if (isGrid(schema)) { + data = generateGridBlock(data); + } + if (data) { + let s; + if (isGrid(schema)) { + s = appendChild(data, [...path]); + } else if (defaultAction === 'insertAfter') { + s = insertAfter(data, [...path]); + } else { + s = insertBefore(data, [...path]); + } + await createSchema(s); + } + }} + > + {collectionField?.uiSchema?.title} + + ); + })}