From 88cc322a8c12dee4eaf665c62a73d1c3768ca9dc Mon Sep 17 00:00:00 2001 From: ChengLei Shao Date: Wed, 6 Nov 2024 13:17:27 +0800 Subject: [PATCH] fix: import with belongs to associations (#5417) * fix: import with belongs to associations * chore: test --- .../src/interfaces/to-one-interface.ts | 7 +- .../server/__tests__/xlsx-importer.test.ts | 145 ++++++++++++++++++ .../src/server/services/xlsx-importer.ts | 1 + 3 files changed, 150 insertions(+), 3 deletions(-) diff --git a/packages/core/database/src/interfaces/to-one-interface.ts b/packages/core/database/src/interfaces/to-one-interface.ts index e2e58b6c8e..568cc6281a 100644 --- a/packages/core/database/src/interfaces/to-one-interface.ts +++ b/packages/core/database/src/interfaces/to-one-interface.ts @@ -19,7 +19,7 @@ export class ToOneInterface extends BaseInterface { return null; } - const { filterKey, targetCollection, transaction } = ctx; + const { filterKey, associationField, targetCollection, transaction } = ctx; const targetInstance = await targetCollection.repository.findOne({ filter: { @@ -31,8 +31,9 @@ export class ToOneInterface extends BaseInterface { if (!targetInstance) { throw new Error(`"${str}" not found in ${targetCollection.model.name} ${filterKey}`); } - const primaryKeyAttribute = targetCollection.model.primaryKeyAttribute; - return targetInstance[primaryKeyAttribute]; + const targetKey = associationField.targetKey || targetCollection.model.primaryKeyAttribute; + + return targetInstance[targetKey]; } } diff --git a/packages/plugins/@nocobase/plugin-action-import/src/server/__tests__/xlsx-importer.test.ts b/packages/plugins/@nocobase/plugin-action-import/src/server/__tests__/xlsx-importer.test.ts index 130a5f8ee1..f8f0d0beff 100644 --- a/packages/plugins/@nocobase/plugin-action-import/src/server/__tests__/xlsx-importer.test.ts +++ b/packages/plugins/@nocobase/plugin-action-import/src/server/__tests__/xlsx-importer.test.ts @@ -281,6 +281,151 @@ describe('xlsx importer', () => { }); }); + describe('import with belongs to association', async () => { + let Profile; + let User; + + beforeEach(async () => { + Profile = app.db.collection({ + name: 'profiles', + autoGenId: false, + fields: [ + { + type: 'bigInt', + name: 'id', + primaryKey: true, + autoIncrement: true, + }, + { + type: 'string', + name: 'name', + }, + { + type: 'string', + name: 'userName', + }, + { + type: 'belongsTo', + name: 'user', + target: 'users', + foreignKey: 'userName', + targetKey: 'name', + }, + ], + }); + + User = app.db.collection({ + name: 'users', + autoGenId: false, + fields: [ + { + type: 'bigInt', + name: 'id', + primaryKey: true, + autoIncrement: true, + }, + { + type: 'string', + name: 'name', + unique: true, + }, + ], + }); + + await app.db.sync(); + + const user = await User.repository.create({ + values: { + name: 'User1', + }, + }); + }); + + it('should import with foreignKey', async () => { + const columns = [ + { + dataIndex: ['name'], + defaultTitle: '名称', + }, + { + dataIndex: ['userName'], + defaultTitle: '用户名', + }, + ]; + + const templateCreator = new TemplateCreator({ + collection: Profile, + columns, + }); + + const template = await templateCreator.run(); + + const worksheet = template.Sheets[template.SheetNames[0]]; + + XLSX.utils.sheet_add_aoa(worksheet, [['test', 'User1']], { + origin: 'A2', + }); + + const importer = new XlsxImporter({ + collectionManager: app.mainDataSource.collectionManager, + collection: Profile, + columns, + workbook: template, + }); + + await importer.run(); + + const profile = await Profile.repository.findOne({ + appends: ['user'], + }); + + expect(profile.get('user').get('name')).toBe('User1'); + expect(profile.get('name')).toBe('test'); + }); + + it('should import with association field', async () => { + const columns = [ + { + dataIndex: ['name'], + defaultTitle: '名称', + }, + { + dataIndex: ['user', 'name'], + defaultTitle: '用户名', + }, + ]; + + const templateCreator = new TemplateCreator({ + collection: Profile, + columns, + }); + + const template = await templateCreator.run(); + + const worksheet = template.Sheets[template.SheetNames[0]]; + + XLSX.utils.sheet_add_aoa(worksheet, [['test', 'User1']], { + origin: 'A2', + }); + + const importer = new XlsxImporter({ + collectionManager: app.mainDataSource.collectionManager, + collection: Profile, + columns, + workbook: template, + }); + + await importer.run(); + + const profile = await Profile.repository.findOne({ + appends: ['user'], + }); + + expect(profile.get('user').get('name')).toBe('User1'); + expect(profile.get('name')).toBe('test'); + }); + }); + describe('import with associations', () => { let User; let Post; diff --git a/packages/plugins/@nocobase/plugin-action-import/src/server/services/xlsx-importer.ts b/packages/plugins/@nocobase/plugin-action-import/src/server/services/xlsx-importer.ts index be60ea8df9..d1ea59d950 100644 --- a/packages/plugins/@nocobase/plugin-action-import/src/server/services/xlsx-importer.ts +++ b/packages/plugins/@nocobase/plugin-action-import/src/server/services/xlsx-importer.ts @@ -172,6 +172,7 @@ export class XlsxImporter extends EventEmitter { }; if (column.dataIndex.length > 1) { + ctx.associationField = field; ctx.targetCollection = (field as IRelationField).targetCollection(); ctx.filterKey = column.dataIndex[1]; }