tachybase_todo/packages/plugins/@nocobase/plugin-snapshot-field/src/server/plugin.ts
2023-10-09 23:05:23 +08:00

136 lines
3.9 KiB
TypeScript

import { Model } from '@nocobase/database';
import { InstallOptions, Plugin } from '@nocobase/server';
import { resolve } from 'path';
import { SnapshotField } from './fields/snapshot-field';
export class SnapshotFieldPlugin extends Plugin {
afterAdd() {}
async beforeLoad() {
const collectionHandler = async (model: Model, { transaction }) => {
const collectionDoc = model.toJSON();
const collectionsHistoryRepository = this.app.db.getRepository('collectionsHistory');
const fieldsHistoryRepository = this.app.db.getRepository('fieldsHistory');
const existCollection: Model = await collectionsHistoryRepository.findOne({
filter: {
name: collectionDoc.name,
},
transaction,
});
if (existCollection) {
// 删除表和其关联字段
await existCollection.destroy({
transaction,
});
}
await collectionsHistoryRepository.create({
values: collectionDoc,
transaction,
});
await fieldsHistoryRepository.createMany({
records: collectionDoc.fields ?? [],
transaction,
});
};
this.app.db.on('collections.afterCreateWithAssociations', collectionHandler);
const deleteField = async (field, transaction) => {
const fieldsHistoryRepository = this.app.db.getRepository('fieldsHistory');
const { name, collectionName } = field;
await fieldsHistoryRepository.destroy({
filter: { name, collectionName },
transaction,
});
};
const fieldHandler = async (model: Model, { transaction }) => {
const fieldsHistoryRepository = this.app.db.getRepository('fieldsHistory');
const fieldDoc = model.get();
await deleteField(fieldDoc, transaction);
const reverseField = fieldDoc.reverseField;
if (reverseField) {
await deleteField(reverseField, transaction);
}
await fieldsHistoryRepository.create({
values: JSON.parse(JSON.stringify(fieldDoc)),
transaction,
});
};
this.app.db.on('fields.afterCreateWithAssociations', fieldHandler);
this.app.db.on('fields.beforeCreate', this.autoFillTargetCollection);
}
autoFillTargetCollection = async (model: Model) => {
const { collectionName, targetField } = model.get();
const collection = this.db.getCollection(collectionName);
if (!collection) {
return;
}
const field = collection.getField(targetField);
if (field?.target) {
model.set('targetCollection', field.target);
}
};
async load() {
// 导入 collection
await this.db.import({
directory: resolve(__dirname, 'collections'),
});
this.app.db.registerFieldTypes({
snapshot: SnapshotField,
});
this.app.acl.allow('collectionsHistory', 'list', 'loggedIn');
}
// 初始化安装的时候
async install(options?: InstallOptions) {
await this.app.db.sequelize.transaction(async (transaction) => {
const collectionsRepository = this.app.db.getRepository('collections');
const collectionsHistoryRepository = this.app.db.getRepository('collectionsHistory');
if ((await collectionsHistoryRepository.find()).length === 0) {
const collectionsModels: Model[] = await collectionsRepository.find();
await collectionsHistoryRepository.createMany({
records: collectionsModels.map((m) => m.get()),
transaction,
});
}
const fieldsRepository = this.app.db.getRepository('fields');
const fieldsHistoryRepository = this.app.db.getRepository('fieldsHistory');
if ((await fieldsHistoryRepository.find()).length === 0) {
const fieldsModels: Model[] = await fieldsRepository.find();
await fieldsHistoryRepository.createMany({
records: fieldsModels.map((m) => m.get()),
transaction,
});
}
});
}
async afterEnable() {}
async afterDisable() {}
async remove() {}
}
export default SnapshotFieldPlugin;