mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-08 06:59:26 +08:00
Merge branch 'main' into next
This commit is contained in:
commit
75adb3f865
@ -570,4 +570,46 @@ describe('tree path test', () => {
|
|||||||
// await treeCollection.removeFromDb();
|
// await treeCollection.removeFromDb();
|
||||||
// expect(await db.getCollection(name).existsInDb()).toBeFalsy();
|
// expect(await db.getCollection(name).existsInDb()).toBeFalsy();
|
||||||
// })
|
// })
|
||||||
|
|
||||||
|
it('should update paths when remove children', async () => {
|
||||||
|
const data = await treeCollection.repository.create({
|
||||||
|
values: {
|
||||||
|
name: 'a1',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
name: 'b1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'b2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const b1 = data.get('children')[0];
|
||||||
|
const b2 = data.get('children')[1];
|
||||||
|
const tks = [b1.get(treeCollection.filterTargetKey), b2.get(treeCollection.filterTargetKey)];
|
||||||
|
const paths = await db.getRepository(name).find({
|
||||||
|
filter: {
|
||||||
|
[nodePkColumnName]: {
|
||||||
|
$in: tks,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(paths.length).toBe(2);
|
||||||
|
expect(paths[0].get('path')).toBe('/1/2');
|
||||||
|
expect(paths[1].get('path')).toBe('/1/3');
|
||||||
|
// @ts-ignore
|
||||||
|
await db.getRepository(`${treeCollection.name}.children`, data.get(treeCollection.filterTargetKey)).remove(tks);
|
||||||
|
const paths2 = await db.getRepository(name).find({
|
||||||
|
filter: {
|
||||||
|
[nodePkColumnName]: {
|
||||||
|
$in: tks,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
console.log(paths2);
|
||||||
|
expect(paths2.length).toBe(2);
|
||||||
|
expect(paths2[0].get('path')).toBe('/2');
|
||||||
|
expect(paths2[1].get('path')).toBe('/3');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -14,11 +14,6 @@ import lodash from 'lodash';
|
|||||||
import { Transaction } from 'sequelize';
|
import { Transaction } from 'sequelize';
|
||||||
import { TreeCollection } from './tree-collection';
|
import { TreeCollection } from './tree-collection';
|
||||||
|
|
||||||
const getFilterTargetKey = (model: Model) => {
|
|
||||||
// @ts-ignore
|
|
||||||
return model.constructor.collection.filterTargetKey;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PluginCollectionTreeServer extends Plugin {
|
class PluginCollectionTreeServer extends Plugin {
|
||||||
async beforeLoad() {
|
async beforeLoad() {
|
||||||
const condition = (options) => {
|
const condition = (options) => {
|
||||||
@ -55,7 +50,7 @@ class PluginCollectionTreeServer extends Plugin {
|
|||||||
//afterCreate
|
//afterCreate
|
||||||
this.db.on(`${collection.name}.afterCreate`, async (model: Model, options) => {
|
this.db.on(`${collection.name}.afterCreate`, async (model: Model, options) => {
|
||||||
const { transaction } = options;
|
const { transaction } = options;
|
||||||
const tk = getFilterTargetKey(model);
|
const tk = collection.filterTargetKey;
|
||||||
let path = `/${model.get(tk)}`;
|
let path = `/${model.get(tk)}`;
|
||||||
path = await this.getTreePath(model, path, collection, name, transaction);
|
path = await this.getTreePath(model, path, collection, name, transaction);
|
||||||
const rootPk = path.split('/')[1];
|
const rootPk = path.split('/')[1];
|
||||||
@ -71,49 +66,35 @@ class PluginCollectionTreeServer extends Plugin {
|
|||||||
|
|
||||||
//afterUpdate
|
//afterUpdate
|
||||||
this.db.on(`${collection.name}.afterUpdate`, async (model: Model, options) => {
|
this.db.on(`${collection.name}.afterUpdate`, async (model: Model, options) => {
|
||||||
const tk = getFilterTargetKey(model);
|
const tk = collection.filterTargetKey;
|
||||||
// only update parentId and filterTargetKey
|
// only update parentId and filterTargetKey
|
||||||
if (!(model._changed.has(tk) || model._changed.has(parentForeignKey))) {
|
if (!(model._changed.has(tk) || model._changed.has(parentForeignKey))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { transaction } = options;
|
const { transaction } = options;
|
||||||
let path = `/${model.get(tk)}`;
|
await this.updateTreePath(model, collection, name, transaction);
|
||||||
path = await this.getTreePath(model, path, collection, name, transaction);
|
});
|
||||||
const collectionTreePath = this.db.getCollection(name);
|
|
||||||
const nodePkColumnName = collectionTreePath.getField('nodePk').columnName();
|
|
||||||
const pathData = await this.app.db.getRepository(name).findOne({
|
|
||||||
filter: {
|
|
||||||
[nodePkColumnName]: model.get(tk),
|
|
||||||
},
|
|
||||||
transaction,
|
|
||||||
});
|
|
||||||
|
|
||||||
const relatedNodes = await this.app.db.getRepository(name).find({
|
// after remove
|
||||||
filter: {
|
this.db.on(`${collection.name}.afterBulkUpdate`, async (options) => {
|
||||||
path: {
|
const tk = collection.filterTargetKey;
|
||||||
$startsWith: `${pathData.get('path')}`,
|
if (!(options.where && options.where[tk])) {
|
||||||
},
|
return;
|
||||||
|
}
|
||||||
|
const instances = await this.db.getRepository(collection.name).find({
|
||||||
|
where: {
|
||||||
|
[tk]: options.where[tk],
|
||||||
},
|
},
|
||||||
transaction,
|
transaction: options.transaction,
|
||||||
});
|
});
|
||||||
const rootPk = path.split('/')[1];
|
for (const model of instances) {
|
||||||
for (const node of relatedNodes) {
|
await this.updateTreePath(model, collection, name, options.transaction);
|
||||||
await this.app.db.getRepository(name).update({
|
|
||||||
values: {
|
|
||||||
path: node.get('path').replace(`${pathData.get('path')}`, path),
|
|
||||||
rootPk: rootPk ? Number(rootPk) : null,
|
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
[nodePkColumnName]: node.get('nodePk'),
|
|
||||||
},
|
|
||||||
transaction,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//afterDestroy
|
//afterDestroy
|
||||||
this.db.on(`${collection.name}.afterDestroy`, async (model: Model, options: DestroyOptions) => {
|
this.db.on(`${collection.name}.afterDestroy`, async (model: Model, options: DestroyOptions) => {
|
||||||
const tk = getFilterTargetKey(model);
|
const tk = collection.filterTargetKey;
|
||||||
await this.app.db.getRepository(name).destroy({
|
await this.app.db.getRepository(name).destroy({
|
||||||
filter: {
|
filter: {
|
||||||
nodePk: model.get(tk),
|
nodePk: model.get(tk),
|
||||||
@ -164,7 +145,7 @@ class PluginCollectionTreeServer extends Plugin {
|
|||||||
pathCollectionName: string,
|
pathCollectionName: string,
|
||||||
transaction?: Transaction,
|
transaction?: Transaction,
|
||||||
) {
|
) {
|
||||||
const tk = getFilterTargetKey(model);
|
const tk = collection.filterTargetKey;
|
||||||
const parentForeignKey = collection.treeParentField?.foreignKey || 'parentId';
|
const parentForeignKey = collection.treeParentField?.foreignKey || 'parentId';
|
||||||
if (model.get(parentForeignKey) && model.get(parentForeignKey) !== null) {
|
if (model.get(parentForeignKey) && model.get(parentForeignKey) !== null) {
|
||||||
const parent = await this.app.db.getRepository(collection.name).findOne({
|
const parent = await this.app.db.getRepository(collection.name).findOne({
|
||||||
@ -195,6 +176,48 @@ class PluginCollectionTreeServer extends Plugin {
|
|||||||
}
|
}
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async updateTreePath(
|
||||||
|
model: Model,
|
||||||
|
collection: Collection,
|
||||||
|
pathCollectionName: string,
|
||||||
|
transaction: Transaction,
|
||||||
|
) {
|
||||||
|
const tk = collection.filterTargetKey;
|
||||||
|
let path = `/${model.get(tk)}`;
|
||||||
|
path = await this.getTreePath(model, path, collection, pathCollectionName, transaction);
|
||||||
|
const collectionTreePath = this.db.getCollection(pathCollectionName);
|
||||||
|
const nodePkColumnName = collectionTreePath.getField('nodePk').columnName();
|
||||||
|
const pathData = await this.app.db.getRepository(pathCollectionName).findOne({
|
||||||
|
filter: {
|
||||||
|
[nodePkColumnName]: model.get(tk),
|
||||||
|
},
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
|
||||||
|
const relatedNodes = await this.app.db.getRepository(pathCollectionName).find({
|
||||||
|
filter: {
|
||||||
|
path: {
|
||||||
|
$startsWith: `${pathData.get('path')}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
const rootPk = path.split('/')[1];
|
||||||
|
for (const node of relatedNodes) {
|
||||||
|
const newPath = node.get('path').replace(pathData.get('path'), path);
|
||||||
|
await this.app.db.getRepository(pathCollectionName).update({
|
||||||
|
values: {
|
||||||
|
path: newPath,
|
||||||
|
rootPk: rootPk ? Number(rootPk) : null,
|
||||||
|
},
|
||||||
|
filter: {
|
||||||
|
[nodePkColumnName]: node.get('nodePk'),
|
||||||
|
},
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PluginCollectionTreeServer;
|
export default PluginCollectionTreeServer;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user