tachybase_todo/packages/plugin-collections/src/models/collection.ts

126 lines
3.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import _ from 'lodash';
import { Model, TableOptions } from '@nocobase/database';
export interface LoadOptions {
reset?: boolean;
where?: any;
skipExisting?: boolean;
[key: string]: any;
}
export interface MigrateOptions {
[key: string]: any;
}
export class Collection extends Model {
static async create(value?: any, options?: any): Promise<any> {
// console.log({ value });
const attributes = this.toAttributes(value);
// @ts-ignore
const model: Model = await super.create(attributes, options);
return model;
}
static toAttributes(value = {}): any {
const data = _.cloneDeep(value);
const keys = [
...Object.keys(this.rawAttributes),
...Object.keys(this.associations),
];
const attrs = _.pick(data, keys);
const options = _.omit(data, keys);
return { ...attrs, options };
}
async toProps() {
const json = this.toJSON();
const data: any = _.omit(json, ['options', 'created_at', 'updated_at']);
const options = json['options'] || {};
const generalFields = await this.getNestedFields({
where: {
state: 1,
}
});
const systemFields = await this.getNestedFields({
where: {
state: 0,
}
});
return { ...data, ...options, generalFields, systemFields }
}
async getNestedFields(options) {
const fields = await this.getFields({
...options,
order: [['sort', 'asc']],
});
const items = [];
for (const field of fields) {
items.push(await field.toProps());
}
return items;
}
/**
* DOTO
* - database.table 初始化可能存在一些缺陷
* - 是否需要考虑关系数据的重载?
*
* @param opts
*/
async loadTableOptions(opts: any = {}) {
const options = await this.toProps();
const { generalFields = [], systemFields = [], ...others } = options;
const table = this.database.table({ ...others, fields: generalFields.concat(systemFields) });
return table;
}
/**
* 迁移
*/
async migrate(options: MigrateOptions = {}) {
const { isNewRecord } = options;
const table = await this.loadTableOptions(options);
// 如果不是新增数据force 必须为 false
if (!isNewRecord) {
return await table.sync({
force: false,
alter: {
drop: false,
}
});
}
// TODO: 暂时加了个 collectionSync 解决 collection.create 的数据不清空问题
// @ts-ignore
const sync = this.sequelize.options.collectionSync;
return await table.sync(sync || {
force: false,
alter: {
drop: false,
}
});
}
/**
* TODO需要考虑是初次加载还是重载
*
* @param options
*/
static async load(options: LoadOptions = {}) {
const { skipExisting = false, reset = false, where = {}, transaction } = options;
const collections = await this.findAll({
transaction,
where,
});
for (const collection of collections) {
if (skipExisting && this.database.isDefined(collection.get('name'))) {
continue;
}
await collection.loadTableOptions({
transaction,
reset,
});
}
}
}