mirror of
https://github.com/nocobase/nocobase
synced 2024-11-14 22:05:38 +00:00
fix: export with relation repository (#5170)
This commit is contained in:
parent
4fd8122c61
commit
841db6ce9f
@ -55,6 +55,44 @@ export abstract class RelationRepository {
|
||||
return this.db.getCollection(this.targetModel.name);
|
||||
}
|
||||
|
||||
abstract find(options?: FindOptions): Promise<any>;
|
||||
|
||||
async chunk(
|
||||
options: FindOptions & { chunkSize: number; callback: (rows: Model[], options: FindOptions) => Promise<void> },
|
||||
) {
|
||||
const { chunkSize, callback, limit: overallLimit } = options;
|
||||
const transaction = await this.getTransaction(options);
|
||||
|
||||
let offset = 0;
|
||||
let totalProcessed = 0;
|
||||
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
// Calculate the limit for the current chunk
|
||||
const currentLimit = overallLimit !== undefined ? Math.min(chunkSize, overallLimit - totalProcessed) : chunkSize;
|
||||
|
||||
const rows = await this.find({
|
||||
...options,
|
||||
limit: currentLimit,
|
||||
offset,
|
||||
transaction,
|
||||
});
|
||||
|
||||
if (rows.length === 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
await callback(rows, options);
|
||||
|
||||
offset += currentLimit;
|
||||
totalProcessed += rows.length;
|
||||
|
||||
if (overallLimit !== undefined && totalProcessed >= overallLimit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
convertTk(options: any) {
|
||||
let tk = options;
|
||||
if (typeof options === 'object' && options['tk']) {
|
||||
|
@ -0,0 +1,89 @@
|
||||
import { createMockServer, MockServer } from '@nocobase/test';
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import XLSX from 'xlsx';
|
||||
|
||||
describe('export action', () => {
|
||||
let app: MockServer;
|
||||
|
||||
beforeEach(async () => {
|
||||
app = await createMockServer({
|
||||
plugins: ['nocobase'],
|
||||
acl: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('should export with association repository', async () => {
|
||||
await app.db.getRepository('collections').create({
|
||||
values: {
|
||||
name: 'posts',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'string',
|
||||
},
|
||||
{
|
||||
name: 'comments',
|
||||
type: 'hasMany',
|
||||
target: 'comments',
|
||||
},
|
||||
],
|
||||
},
|
||||
context: {},
|
||||
});
|
||||
|
||||
await app.db.getRepository('collections').create({
|
||||
values: {
|
||||
name: 'comments',
|
||||
fields: [
|
||||
{
|
||||
name: 'content',
|
||||
type: 'string',
|
||||
},
|
||||
],
|
||||
},
|
||||
context: {},
|
||||
});
|
||||
|
||||
await app.db.getRepository('posts').create({
|
||||
values: [
|
||||
{
|
||||
title: 'post1',
|
||||
comments: [
|
||||
{
|
||||
content: 'comment1',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'post2',
|
||||
comments: [
|
||||
{
|
||||
content: 'comment2',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const res = await app
|
||||
.agent()
|
||||
.resource('posts.comments', 1)
|
||||
.export({
|
||||
values: {
|
||||
columns: [{ dataIndex: ['content'], defaultTitle: 'content' }],
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.status).toBe(200);
|
||||
|
||||
const buffer = res.body;
|
||||
|
||||
const workbook = XLSX.read(buffer, { type: 'buffer' });
|
||||
const sheetName = workbook.SheetNames[0];
|
||||
const sheet = workbook.Sheets[sheetName];
|
||||
const rows = XLSX.utils.sheet_to_json(sheet);
|
||||
expect(rows.length).toBe(1);
|
||||
});
|
||||
});
|
@ -33,6 +33,7 @@ async function exportXlsxAction(ctx: Context, next: Next) {
|
||||
const xlsxExporter = new XlsxExporter({
|
||||
collectionManager: dataSource.collectionManager,
|
||||
collection,
|
||||
repository,
|
||||
columns,
|
||||
findOptions: {
|
||||
filter,
|
||||
|
@ -29,6 +29,7 @@ type ExportColumn = {
|
||||
type ExportOptions = {
|
||||
collectionManager: ICollectionManager;
|
||||
collection: ICollection;
|
||||
repository?: any;
|
||||
columns: Array<ExportColumn>;
|
||||
findOptions?: FindOptions;
|
||||
chunkSize?: number;
|
||||
@ -51,7 +52,7 @@ class XlsxExporter {
|
||||
constructor(private options: ExportOptions) {}
|
||||
|
||||
async run(ctx?): Promise<XLSX.WorkBook> {
|
||||
const { collection, columns, chunkSize } = this.options;
|
||||
const { collection, columns, chunkSize, repository } = this.options;
|
||||
|
||||
const workbook = XLSX.utils.book_new();
|
||||
const worksheet = XLSX.utils.sheet_new();
|
||||
@ -63,7 +64,7 @@ class XlsxExporter {
|
||||
|
||||
let startRowNumber = 2;
|
||||
|
||||
await collection.repository.chunk({
|
||||
await (repository || collection.repository).chunk({
|
||||
...this.getFindOptions(),
|
||||
chunkSize: chunkSize || 200,
|
||||
callback: async (rows, options) => {
|
||||
|
Loading…
Reference in New Issue
Block a user