126 lines
3.1 KiB
TypeScript
126 lines
3.1 KiB
TypeScript
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,
|
||
});
|
||
}
|
||
}
|
||
}
|