136 lines
3.9 KiB
TypeScript
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;
|