fix: do not clear data when migrating data

This commit is contained in:
chenos 2020-12-16 08:42:37 +08:00
parent 1aa7ee65ab
commit 866549ce26
4 changed files with 227 additions and 141 deletions

View File

@ -5,10 +5,14 @@ import Database, { Model } from '@nocobase/database';
import actions from '../../../actions/src'; import actions from '../../../actions/src';
import associated from '../../../actions/src/middlewares/associated'; import associated from '../../../actions/src/middlewares/associated';
console.log(process.argv);
const clean = false;
const sync = { const sync = {
force: true, force: clean,
alter: { alter: {
drop: true, drop: clean,
}, },
}; };
@ -38,102 +42,120 @@ const api = Api.create({
api.resourcer.use(associated); api.resourcer.use(associated);
api.resourcer.registerActionHandlers({...actions.common, ...actions.associate}); api.resourcer.registerActionHandlers({...actions.common, ...actions.associate});
const data = { const data = [
title: '后台应用', {
path: '/', title: '后台应用',
type: 'layout', path: '/',
template: 'TopMenuLayout', type: 'layout',
sort: 10, template: 'TopMenuLayout',
children: [ sort: 10,
{ children: [
title: '仪表盘', {
type: 'page', title: '仪表盘',
path: '/dashboard', type: 'page',
icon: 'DashboardOutlined', path: '/dashboard',
template: 'page1', icon: 'DashboardOutlined',
sort: 20, template: 'page1',
showInMenu: true, sort: 20,
}, showInMenu: true,
{ },
title: '数据', {
type: 'layout', title: '数据',
path: '/collections', type: 'layout',
icon: 'DatabaseOutlined', path: '/collections',
template: 'SideMenuLayout', icon: 'DatabaseOutlined',
sort: 30, template: 'SideMenuLayout',
showInMenu: true, sort: 30,
children: [ showInMenu: true,
// { children: [
// title: '页面3', // {
// type: 'page', // title: '页面3',
// path: '/collections/page3', // type: 'page',
// icon: 'dashboard', // path: '/collections/page3',
// template: 'page3', // icon: 'dashboard',
// sort: 40, // template: 'page3',
// }, // sort: 40,
// { // },
// title: '页面4', // {
// type: 'page', // title: '页面4',
// path: '/collections/page4', // type: 'page',
// icon: 'dashboard', // path: '/collections/page4',
// template: 'page4', // icon: 'dashboard',
// sort: 50, // template: 'page4',
// }, // sort: 50,
] // },
}, ]
{ },
title: '用户', {
type: 'layout', title: '用户',
path: '/users', type: 'layout',
icon: 'TeamOutlined', path: '/users',
template: 'SideMenuLayout', icon: 'TeamOutlined',
sort: 70, template: 'SideMenuLayout',
showInMenu: true, sort: 70,
children: [ showInMenu: true,
{ children: [
title: '用户管理', {
type: 'collection', title: '用户管理',
path: '/users/users', type: 'collection',
icon: 'UserOutlined', path: '/users/users',
template: 'collection', icon: 'UserOutlined',
collection: 'users', template: 'collection',
sort: 80, collection: 'users',
showInMenu: true, sort: 80,
}, showInMenu: true,
] },
}, ]
{ },
title: '配置', {
type: 'layout', title: '配置',
path: '/settings', type: 'layout',
icon: 'SettingOutlined', path: '/settings',
template: 'SideMenuLayout', icon: 'SettingOutlined',
sort: 90, template: 'SideMenuLayout',
showInMenu: true, sort: 90,
children: [ showInMenu: true,
{ children: [
title: '页面与菜单', {
type: 'collection', title: '页面与菜单',
collection: 'pages', type: 'collection',
path: '/settings/pages', collection: 'pages',
icon: 'MenuOutlined', path: '/settings/pages',
sort: 100, icon: 'MenuOutlined',
developerMode: true, sort: 100,
showInMenu: true, developerMode: true,
}, showInMenu: true,
{ },
title: '数据表配置', {
type: 'collection', title: '数据表配置',
collection: 'collections', type: 'collection',
path: '/settings/collections', collection: 'collections',
icon: 'TableOutlined', path: '/settings/collections',
sort: 110, icon: 'TableOutlined',
showInMenu: true, sort: 110,
}, showInMenu: true,
] },
}, ]
], },
}; ],
},
{
title: '登录页面',
path: '/login',
type: 'page',
inherit: false,
template: 'login',
order: 120,
},
{
title: '注册页面',
path: '/register',
type: 'page',
inherit: false,
template: 'register',
order: 130,
}
];
(async () => { (async () => {
await api await api
@ -150,44 +172,23 @@ const data = {
await database.sync({ await database.sync({
// tables: ['collections', 'fields', 'actions', 'views', 'tabs'], // tables: ['collections', 'fields', 'actions', 'views', 'tabs'],
}); });
const [Collection, Page, User] = database.getModels(['collections', 'pages', 'users']);
const Collection = database.getModel('collections');
const tables = database.getTables([]); const tables = database.getTables([]);
for (let table of tables) { for (let table of tables) {
await Collection.import(table.getOptions(), { migrate: false }); await Collection.import(table.getOptions(), { update: true, migrate: false });
} }
await Page.import(data);
const Page = database.getModel('pages'); await User.findOrCreate({
const page = await Page.create(data); where: {
await page.updateAssociations(data); username: "admin",
},
await Page.create({ defaults: {
title: '登录页面', nickname: "超级管理员",
path: '/login', password: "admin",
type: 'page', username: "admin",
inherit: false, token: "38979f07e1fca68fb3d2",
template: 'login', },
order: 120,
}); });
await Page.create({
title: '注册页面',
path: '/register',
type: 'page',
inherit: false,
template: 'register',
order: 130,
});
await database.getModel('users').create({
nickname: "超级管理员",
password: "admin",
username: "admin",
token: "38979f07e1fca68fb3d2",
});
await database.getModel('collections').import(require('./collections/example').default); await database.getModel('collections').import(require('./collections/example').default);
await database.close(); await database.close();
})(); })();

View File

@ -129,21 +129,66 @@ export class CollectionModel extends BaseModel {
static async import(data: TableOptions, options: SaveOptions = {}): Promise<CollectionModel> { static async import(data: TableOptions, options: SaveOptions = {}): Promise<CollectionModel> {
data = _.cloneDeep(data); data = _.cloneDeep(data);
const collection = await this.create({ // @ts-ignore
...data, const { update } = options;
}, options); let collection;
const items: any = {}; if (data.name) {
collection = await this.findOne({
...options,
where: {
name: data.name,
},
});
} else if (data.title) {
collection = await this.findOne({
...options,
where: {
title: data.title,
},
});
}
if (collection && update) {
await collection.update(data, options);
}
if (!collection) {
collection = await this.create(data, options);
}
const associations = ['fields', 'tabs', 'actions', 'views']; const associations = ['fields', 'tabs', 'actions', 'views'];
for (const key of associations) { for (const key of associations) {
if (!Array.isArray(data[key])) { if (!Array.isArray(data[key])) {
continue; continue;
} }
items[key] = data[key].map((item, sort) => ({ const Model = this.database.getModel(key);
...item, for (const item of data[key]) {
sort, let model;
})); if (item.name) {
model = await Model.findOne({
...options,
where: {
collection_name: collection.name,
name: item.name,
},
});
} else if (item.title) {
model = await Model.findOne({
...options,
where: {
collection_name: collection.name,
title: item.title,
},
});
}
if (model && update) {
await model.update(item, options);
}
if (!model) {
model = await Model.create({
...item,
collection_name: collection.name,
}, options);
}
}
} }
await collection.updateAssociations(items, options);
return collection; return collection;
} }
} }

View File

@ -4,3 +4,4 @@ export * from './collection';
export * from './field'; export * from './field';
export * from './tab'; export * from './tab';
export * from './view'; export * from './view';
export * from './page';

View File

@ -0,0 +1,39 @@
import _ from 'lodash';
import BaseModel from './base';
import { SaveOptions, Op } from 'sequelize';
interface PageImportOptions extends SaveOptions {
parentId?: number;
}
/**
*
*/
export class PageModel extends BaseModel {
static async import(items: any, options: PageImportOptions = {}): Promise<any> {
const { parentId } = options;
if (!Array.isArray(items)) {
items = [items];
}
for (const item of items) {
let page = await this.findOne({
...options,
where: {
path: item.path,
},
});
if (!page) {
page = await this.create({
...item,
parent_id: parentId,
}, options);
}
if (Array.isArray(item.children)) {
await this.import(item.children, {
...options,
parentId: page.id,
});
}
}
}
}