From 866549ce263df2f82d4bba7b017b0f8d45984aac Mon Sep 17 00:00:00 2001 From: chenos Date: Wed, 16 Dec 2020 08:42:37 +0800 Subject: [PATCH] fix: do not clear data when migrating data --- packages/app/src/api/migrate.ts | 265 +++++++++--------- .../src/models/collection.ts | 63 ++++- .../plugin-collections/src/models/index.ts | 1 + .../plugin-collections/src/models/page.ts | 39 +++ 4 files changed, 227 insertions(+), 141 deletions(-) create mode 100644 packages/plugin-collections/src/models/page.ts diff --git a/packages/app/src/api/migrate.ts b/packages/app/src/api/migrate.ts index be1f7f135..03f4b7dd9 100644 --- a/packages/app/src/api/migrate.ts +++ b/packages/app/src/api/migrate.ts @@ -5,10 +5,14 @@ import Database, { Model } from '@nocobase/database'; import actions from '../../../actions/src'; import associated from '../../../actions/src/middlewares/associated'; +console.log(process.argv); + +const clean = false; + const sync = { - force: true, + force: clean, alter: { - drop: true, + drop: clean, }, }; @@ -38,102 +42,120 @@ const api = Api.create({ api.resourcer.use(associated); api.resourcer.registerActionHandlers({...actions.common, ...actions.associate}); -const data = { - title: '后台应用', - path: '/', - type: 'layout', - template: 'TopMenuLayout', - sort: 10, - children: [ - { - title: '仪表盘', - type: 'page', - path: '/dashboard', - icon: 'DashboardOutlined', - template: 'page1', - sort: 20, - showInMenu: true, - }, - { - title: '数据', - type: 'layout', - path: '/collections', - icon: 'DatabaseOutlined', - template: 'SideMenuLayout', - sort: 30, - showInMenu: true, - children: [ - // { - // title: '页面3', - // type: 'page', - // path: '/collections/page3', - // icon: 'dashboard', - // template: 'page3', - // sort: 40, - // }, - // { - // title: '页面4', - // type: 'page', - // path: '/collections/page4', - // icon: 'dashboard', - // template: 'page4', - // sort: 50, - // }, - ] - }, - { - title: '用户', - type: 'layout', - path: '/users', - icon: 'TeamOutlined', - template: 'SideMenuLayout', - sort: 70, - showInMenu: true, - children: [ - { - title: '用户管理', - type: 'collection', - path: '/users/users', - icon: 'UserOutlined', - template: 'collection', - collection: 'users', - sort: 80, - showInMenu: true, - }, - ] - }, - { - title: '配置', - type: 'layout', - path: '/settings', - icon: 'SettingOutlined', - template: 'SideMenuLayout', - sort: 90, - showInMenu: true, - children: [ - { - title: '页面与菜单', - type: 'collection', - collection: 'pages', - path: '/settings/pages', - icon: 'MenuOutlined', - sort: 100, - developerMode: true, - showInMenu: true, - }, - { - title: '数据表配置', - type: 'collection', - collection: 'collections', - path: '/settings/collections', - icon: 'TableOutlined', - sort: 110, - showInMenu: true, - }, - ] - }, - ], -}; +const data = [ + { + title: '后台应用', + path: '/', + type: 'layout', + template: 'TopMenuLayout', + sort: 10, + children: [ + { + title: '仪表盘', + type: 'page', + path: '/dashboard', + icon: 'DashboardOutlined', + template: 'page1', + sort: 20, + showInMenu: true, + }, + { + title: '数据', + type: 'layout', + path: '/collections', + icon: 'DatabaseOutlined', + template: 'SideMenuLayout', + sort: 30, + showInMenu: true, + children: [ + // { + // title: '页面3', + // type: 'page', + // path: '/collections/page3', + // icon: 'dashboard', + // template: 'page3', + // sort: 40, + // }, + // { + // title: '页面4', + // type: 'page', + // path: '/collections/page4', + // icon: 'dashboard', + // template: 'page4', + // sort: 50, + // }, + ] + }, + { + title: '用户', + type: 'layout', + path: '/users', + icon: 'TeamOutlined', + template: 'SideMenuLayout', + sort: 70, + showInMenu: true, + children: [ + { + title: '用户管理', + type: 'collection', + path: '/users/users', + icon: 'UserOutlined', + template: 'collection', + collection: 'users', + sort: 80, + showInMenu: true, + }, + ] + }, + { + title: '配置', + type: 'layout', + path: '/settings', + icon: 'SettingOutlined', + template: 'SideMenuLayout', + sort: 90, + showInMenu: true, + children: [ + { + title: '页面与菜单', + type: 'collection', + collection: 'pages', + path: '/settings/pages', + icon: 'MenuOutlined', + sort: 100, + developerMode: true, + showInMenu: true, + }, + { + title: '数据表配置', + type: 'collection', + collection: 'collections', + path: '/settings/collections', + icon: 'TableOutlined', + 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 () => { await api @@ -150,44 +172,23 @@ const data = { await database.sync({ // tables: ['collections', 'fields', 'actions', 'views', 'tabs'], }); - - const Collection = database.getModel('collections'); + const [Collection, Page, User] = database.getModels(['collections', 'pages', 'users']); const tables = database.getTables([]); - for (let table of tables) { - await Collection.import(table.getOptions(), { migrate: false }); + await Collection.import(table.getOptions(), { update: true, migrate: false }); } - - const Page = database.getModel('pages'); - const page = await Page.create(data); - await page.updateAssociations(data); - - await Page.create({ - title: '登录页面', - path: '/login', - type: 'page', - inherit: false, - template: 'login', - order: 120, + await Page.import(data); + await User.findOrCreate({ + where: { + username: "admin", + }, + defaults: { + nickname: "超级管理员", + password: "admin", + username: "admin", + token: "38979f07e1fca68fb3d2", + }, }); - - 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.close(); })(); diff --git a/packages/plugin-collections/src/models/collection.ts b/packages/plugin-collections/src/models/collection.ts index 989102a48..de8965d28 100644 --- a/packages/plugin-collections/src/models/collection.ts +++ b/packages/plugin-collections/src/models/collection.ts @@ -129,21 +129,66 @@ export class CollectionModel extends BaseModel { static async import(data: TableOptions, options: SaveOptions = {}): Promise { data = _.cloneDeep(data); - const collection = await this.create({ - ...data, - }, options); - const items: any = {}; + // @ts-ignore + const { update } = options; + let collection; + 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']; for (const key of associations) { if (!Array.isArray(data[key])) { continue; } - items[key] = data[key].map((item, sort) => ({ - ...item, - sort, - })); + const Model = this.database.getModel(key); + for (const item of data[key]) { + 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; } } diff --git a/packages/plugin-collections/src/models/index.ts b/packages/plugin-collections/src/models/index.ts index 64ef6f13b..91a4aef21 100644 --- a/packages/plugin-collections/src/models/index.ts +++ b/packages/plugin-collections/src/models/index.ts @@ -4,3 +4,4 @@ export * from './collection'; export * from './field'; export * from './tab'; export * from './view'; +export * from './page'; diff --git a/packages/plugin-collections/src/models/page.ts b/packages/plugin-collections/src/models/page.ts new file mode 100644 index 000000000..085fdeb44 --- /dev/null +++ b/packages/plugin-collections/src/models/page.ts @@ -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 { + 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, + }); + } + } + } +}