diff --git a/lerna.json b/lerna.json index 8f9feb0376..5608c7c137 100644 --- a/lerna.json +++ b/lerna.json @@ -2,9 +2,7 @@ "version": "1.4.10", "npmClient": "yarn", "useWorkspaces": true, - "npmClientArgs": [ - "--ignore-engines" - ], + "npmClientArgs": ["--ignore-engines"], "command": { "version": { "forcePublish": true, diff --git a/packages/core/client/src/schema-component/antd/form-v2/Templates.tsx b/packages/core/client/src/schema-component/antd/form-v2/Templates.tsx index b38f7d0504..65434b3a98 100644 --- a/packages/core/client/src/schema-component/antd/form-v2/Templates.tsx +++ b/packages/core/client/src/schema-component/antd/form-v2/Templates.tsx @@ -19,6 +19,7 @@ import { useCollectionManager_deprecated } from '../../../collection-manager'; import { compatibleDataId } from '../../../schema-settings/DataTemplates/FormDataTemplates'; import { useToken } from '../__builtins__'; import { RemoteSelect } from '../remote-select'; +import { useDataSourceHeaders, useDataSourceKey } from '../../../data-source'; export interface ITemplate { config?: { @@ -101,11 +102,13 @@ export const Templates = ({ style = {}, form }: { style?: React.CSSProperties; f const [targetTemplateData, setTemplateData] = useState(null); const api = useAPIClient(); const { t } = useTranslation(); + const dataSource = useDataSourceKey(); + const headers = useDataSourceHeaders(dataSource); useEffect(() => { if (enabled && defaultTemplate && form) { form.__template = true; if (defaultTemplate.key === 'duplicate') { - handleTemplateDataChange(defaultTemplate.dataId, defaultTemplate); + handleTemplateDataChange(defaultTemplate.dataId, defaultTemplate, headers); } } }, []); @@ -139,10 +142,10 @@ export const Templates = ({ style = {}, form }: { style?: React.CSSProperties; f form?.reset(); }, []); - const handleTemplateDataChange: any = useCallback(async (value, option) => { + const handleTemplateDataChange: any = useCallback(async (value, option, headers) => { const template = { ...option, dataId: value }; setTemplateData(option); - fetchTemplateData(api, template, t) + fetchTemplateData(api, template, headers) .then((data) => { if (form && data) { // 切换之前先把之前的数据清空 @@ -194,7 +197,7 @@ export const Templates = ({ style = {}, form }: { style?: React.CSSProperties; f filter: template?.dataScope, }, }} - onChange={(value) => handleTemplateDataChange(value?.id, { ...value, ...template })} + onChange={(value) => handleTemplateDataChange(value?.id, { ...value, ...template }, headers)} targetField={getCollectionJoinField(`${template?.collection}.${template.titleField}`)} /> )} @@ -211,12 +214,16 @@ function findDataTemplates(fieldSchema): ITemplate { return {} as ITemplate; } -export async function fetchTemplateData(api, template: { collection: string; dataId: number; fields: string[] }, t) { +export async function fetchTemplateData( + api, + template: { collection: string; dataId: number; fields: string[] }, + headers?, +) { if (template.fields.length === 0 || !template.dataId) { return; } return api - .resource(template.collection) + .resource(template.collection, undefined, headers) .get({ filterByTk: template.dataId, fields: template.fields, diff --git a/packages/core/server/src/middlewares/data-template.ts b/packages/core/server/src/middlewares/data-template.ts index 023e12145f..69c6121ed0 100644 --- a/packages/core/server/src/middlewares/data-template.ts +++ b/packages/core/server/src/middlewares/data-template.ts @@ -18,7 +18,7 @@ export async function dataTemplate(ctx: Context, next) { if (isTemplate && actionName === 'get') { ctx.body = traverseJSON(JSON.parse(JSON.stringify(ctx.body)), { - collection: ctx.db.getCollection(resourceName), + collection: ctx.getCurrentRepository().collection, include: [...(fields || []), ...(appends || [])], }); } @@ -75,6 +75,7 @@ const traverseJSON = (data, options: TraverseOptions) => { if (!data) { return data; } + const { collection, exclude = [], include = [], excludePk = true } = options; const map = parseInclude(include); const result = {}; @@ -94,9 +95,11 @@ const traverseJSON = (data, options: TraverseOptions) => { result[key] = data[key]; continue; } - if (field.options.primaryKey && excludePk) { + + if (field.options.primaryKey && excludePk && !collection.isMultiFilterTargetKey()) { continue; } + if (field.options.isForeignKey) { continue; } diff --git a/packages/plugins/@nocobase/plugin-action-duplicate/src/client/DuplicateAction.tsx b/packages/plugins/@nocobase/plugin-action-duplicate/src/client/DuplicateAction.tsx index dfcd999ac7..135420e30c 100644 --- a/packages/plugins/@nocobase/plugin-action-duplicate/src/client/DuplicateAction.tsx +++ b/packages/plugins/@nocobase/plugin-action-duplicate/src/client/DuplicateAction.tsx @@ -27,6 +27,9 @@ import { useDesignable, useFormBlockContext, useRecord, + useCollection, + useDataSourceHeaders, + useDataSourceKey, } from '@nocobase/client'; import { App, Button } from 'antd'; import React, { useMemo, useState } from 'react'; @@ -87,6 +90,7 @@ export const DuplicateAction = observer( const { duplicateFields, duplicateMode = 'quickDulicate', duplicateCollection } = fieldSchema['x-component-props']; const record = useRecord(); const parentRecordData: any = useCollectionParentRecordData(); + const collection = useCollection(); const { id, __collection } = record; const ctx = useActionContext(); const { name } = useCollection_deprecated(); @@ -95,6 +99,16 @@ export const DuplicateAction = observer( const collectionFields = getCollectionFields(__collection || name); const formctx = useFormBlockContext(); const aclCtx = useACLActionParamsContext(); + const dataSource = useDataSourceKey(); + const headers = useDataSourceHeaders(dataSource); + const dataId = Array.isArray(collection.filterTargetKey) + ? Object.assign( + {}, + ...collection.filterTargetKey.map((v) => { + return { [v]: record[v] }; + }), + ) + : record[collection.filterTargetKey] || id; const buttonStyle = useMemo(() => { return { opacity: designable && (field?.data?.hidden || !aclCtx) && 0.1, @@ -102,7 +116,7 @@ export const DuplicateAction = observer( }, [designable, field?.data?.hidden]); const template = { key: 'duplicate', - dataId: id, + dataId, default: true, fields: duplicateFields?.filter((v) => { @@ -114,7 +128,7 @@ export const DuplicateAction = observer( const handelQuickDuplicate = async () => { setLoading(true); try { - const data = await fetchTemplateData(api, template, t); + const data = await fetchTemplateData(api, template, headers); await resource['create']({ values: { ...data,