mirror of
https://gitee.com/nocobase/nocobase.git
synced 2024-12-02 20:27:49 +08:00
feat: collection extender
This commit is contained in:
parent
479676d678
commit
a942eee769
@ -27,6 +27,7 @@ describe('sort', function () {
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expect(collection.getField('parent').options.target).toBe('categories');
|
||||
expect(collection.getField('parent').options.foreignKey).toBe('parentId');
|
||||
expect(collection.getField('children').options.target).toBe('categories');
|
||||
|
@ -0,0 +1,66 @@
|
||||
import lodash from 'lodash';
|
||||
import { Model } from '../model';
|
||||
|
||||
import { CollectionExtender } from '.';
|
||||
|
||||
export class AdjacencyListExtender implements CollectionExtender {
|
||||
static condition(options) {
|
||||
return options.tree;
|
||||
}
|
||||
|
||||
apply(collection) {
|
||||
this.treeHook(collection);
|
||||
}
|
||||
|
||||
treeHook(collection) {
|
||||
if (!collection.options.tree) {
|
||||
return;
|
||||
}
|
||||
|
||||
collection.on('field.beforeAdd', (name, opts, { collection }) => {
|
||||
console.log('field beforeAdd');
|
||||
if (!collection.options.tree) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (name === 'parent' || name === 'children') {
|
||||
opts.target = collection.name;
|
||||
opts.foreignKey = 'parentId';
|
||||
}
|
||||
});
|
||||
|
||||
collection.model.afterFind(async (instances, options: any) => {
|
||||
if (!options.tree) {
|
||||
return;
|
||||
}
|
||||
const arr: Model[] = Array.isArray(instances) ? instances : [instances];
|
||||
let index = 0;
|
||||
for (const instance of arr) {
|
||||
const opts = {
|
||||
...lodash.pick(options, ['tree', 'fields', 'appends', 'except', 'sort']),
|
||||
};
|
||||
let __index = `${index++}`;
|
||||
if (options.parentIndex) {
|
||||
__index = `${options.parentIndex}.${__index}`;
|
||||
}
|
||||
instance.setDataValue('__index', __index);
|
||||
const children = await collection.repository.find({
|
||||
filter: {
|
||||
parentId: instance.id,
|
||||
},
|
||||
transaction: options.transaction,
|
||||
...opts,
|
||||
// @ts-ignore
|
||||
parentIndex: `${__index}.children`,
|
||||
context: options.context,
|
||||
});
|
||||
if (children?.length > 0) {
|
||||
instance.setDataValue(
|
||||
'children',
|
||||
children.map((r) => r.toJSON()),
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
19
packages/core/database/src/collection-extenders/index.ts
Normal file
19
packages/core/database/src/collection-extenders/index.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { Collection } from '../collection';
|
||||
import { AdjacencyListExtender } from './adjacency-list-extender';
|
||||
|
||||
export abstract class CollectionExtender {
|
||||
static condition: (options: any) => boolean;
|
||||
apply: (collection: Collection) => void;
|
||||
}
|
||||
|
||||
export function applyExtenders(collection: Collection) {
|
||||
const extenderClasses = [AdjacencyListExtender];
|
||||
|
||||
for (const extenderClass of extenderClasses) {
|
||||
if (extenderClass.condition(collection.options)) {
|
||||
console.log('apply extender', extenderClass.name);
|
||||
const extender = new extenderClass();
|
||||
extender.apply(collection);
|
||||
}
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@ import {
|
||||
QueryInterfaceDropTableOptions,
|
||||
SyncOptions,
|
||||
Transactionable,
|
||||
Utils
|
||||
Utils,
|
||||
} from 'sequelize';
|
||||
import { Database } from './database';
|
||||
import { Field, FieldOptions } from './fields';
|
||||
@ -85,7 +85,8 @@ export class Collection<
|
||||
|
||||
this.db.modelCollection.set(this.model, this);
|
||||
this.db.tableNameCollectionMap.set(this.model.tableName, this);
|
||||
this.treeHook();
|
||||
|
||||
this.db.emit('definingCollection', this);
|
||||
|
||||
if (!options.inherits) {
|
||||
this.setFields(options.fields);
|
||||
@ -95,54 +96,6 @@ export class Collection<
|
||||
this.setSortable(options.sortable);
|
||||
}
|
||||
|
||||
treeHook() {
|
||||
if (!this.options.tree) {
|
||||
return;
|
||||
}
|
||||
this.on('field.beforeAdd', (name, opts, { collection }) => {
|
||||
if (!collection.options.tree) {
|
||||
return;
|
||||
}
|
||||
if (name === 'parent' || name === 'children') {
|
||||
opts.target = collection.name;
|
||||
opts.foreignKey = 'parentId';
|
||||
}
|
||||
});
|
||||
this.model.afterFind(async (instances, options: any) => {
|
||||
if (!options.tree) {
|
||||
return;
|
||||
}
|
||||
const arr: Model[] = Array.isArray(instances) ? instances : [instances];
|
||||
let index = 0;
|
||||
for (const instance of arr) {
|
||||
const opts = {
|
||||
...lodash.pick(options, ['tree', 'fields', 'appends', 'except', 'sort']),
|
||||
};
|
||||
let __index = `${index++}`;
|
||||
if (options.parentIndex) {
|
||||
__index = `${options.parentIndex}.${__index}`;
|
||||
}
|
||||
instance.setDataValue('__index', __index);
|
||||
const children = await this.repository.find({
|
||||
filter: {
|
||||
parentId: instance.id,
|
||||
},
|
||||
transaction: options.transaction,
|
||||
...opts,
|
||||
// @ts-ignore
|
||||
parentIndex: `${__index}.children`,
|
||||
context: options.context,
|
||||
});
|
||||
if (children?.length > 0) {
|
||||
instance.setDataValue(
|
||||
'children',
|
||||
children.map((r) => r.toJSON()),
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private checkOptions(options: CollectionOptions) {
|
||||
checkIdentifier(options.name);
|
||||
this.checkTableName();
|
||||
|
@ -64,6 +64,7 @@ import { patchSequelizeQueryInterface, snakeCase } from './utils';
|
||||
|
||||
import DatabaseUtils from './database-utils';
|
||||
import { BaseValueParser, registerFieldValueParsers } from './value-parsers';
|
||||
import { applyExtenders } from './collection-extenders';
|
||||
|
||||
export interface MergeOptions extends merge.Options {}
|
||||
|
||||
@ -336,6 +337,10 @@ export class Database extends EventEmitter implements AsyncEmitter {
|
||||
options.schema = this.options.schema;
|
||||
}
|
||||
});
|
||||
|
||||
this.on('definingCollection', (collection) => {
|
||||
applyExtenders(collection);
|
||||
});
|
||||
}
|
||||
|
||||
addMigration(item: MigrationItem) {
|
||||
|
@ -4236,7 +4236,7 @@
|
||||
dependencies:
|
||||
"@formily/shared" "2.0.20"
|
||||
|
||||
"@formulajs/formulajs@^4.2.0":
|
||||
"@formulajs/formulajs@4.2.0", "@formulajs/formulajs@^4.2.0":
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@formulajs/formulajs/-/formulajs-4.2.0.tgz#e5c6a98fa5863442cb68f93b8b9b28d75070abc4"
|
||||
integrity sha512-egxyvwj08iwOznFgxv7dvjgHUC7C8jdtznAs+15uThIti7TwDGhB3wsbJt1dlfhSHKvlRAiW4MDYxNkvgmyjyg==
|
||||
|
Loading…
Reference in New Issue
Block a user