Feature/destroy lock (#60)

* feat: load collection actions for custom options

* fix: test case

* optimization

Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
Junyi 2021-01-26 22:16:22 +08:00 committed by GitHub
parent 613c4a14ad
commit db3a8a7499
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 93 additions and 24 deletions

View File

@ -142,9 +142,9 @@ const data = [
const [Collection, Page, User] = database.getModels(['collections', 'pages', 'users']);
const tables = database.getTables([]);
for (let table of tables) {
console.log(table.getName());
// console.log(table.getName());
if (table.getName() === 'roles') {
console.log('roles', table.getOptions())
// console.log('roles', table.getOptions())
}
await Collection.import(table.getOptions(), { update: true, migrate: false });
}

View File

@ -205,8 +205,12 @@ export class Table {
return this.options.name;
}
public getOptions(): TableOptions {
return this.options;
/**
*
* @param key key
*/
public getOptions(key?: any): TableOptions {
return key ? _.get(this.options, key) : this.options;
}
public getModel(): ModelCtor<Model> {

View File

@ -55,10 +55,12 @@ export class CollectionModel extends BaseModel {
*/
async loadTableOptions(opts: any = {}) {
const options = await this.getOptions();
const prevTable = this.database.getTable(this.get('name'));
const prevOptions = prevTable ? prevTable.getOptions() : {};
// const prevTable = this.database.getTable(this.get('name'));
// const prevOptions = prevTable ? prevTable.getOptions() : {};
// table 是初始化和重新初始化
const table = this.database.table({...prevOptions, ...options});
const table = this.database.extend(options);
// console.log({options, actions: table.getOptions()['actions']})
// 如果关系表未加载,一起处理
// const associationTableNames = [];
// for (const [key, association] of table.getAssociations()) {
@ -120,6 +122,7 @@ export class CollectionModel extends BaseModel {
async getOptions(): Promise<TableOptions> {
return {
...this.get(),
actions: await this.getActions(),
fields: await this.getFieldsOptions(),
};
}

View File

@ -37,8 +37,6 @@ export async function get(ctx: actions.Context, next: actions.Next) {
limit: 1,
});
console.log(permission);
ctx.body = {
...permissions,
description: _.get(permission, 'description'),

View File

@ -30,6 +30,16 @@ export default {
showInForm: true,
},
},
{
interface: 'boolean',
type: 'boolean',
name: 'locked',
title: '锁定',
defaultValue: false,
component: {
showInTable: true,
}
},
{
type: 'belongsTo',
name: 'collection',

View File

@ -14,6 +14,16 @@ export default extend({
list: {
sort: 'id',
},
update: {
filter: {
locked: false
}
},
destroy: {
filter: {
locked: false
}
}
},
component: {
type: 'drawerSelect',

View File

@ -84,6 +84,39 @@ export default {
name: 'permissions'
},
],
actions: [
{
type: 'list',
name: 'list',
title: '查看',
},
// {
// type: 'get',
// name: 'get',
// title: '详情',
// },
{
type: 'create',
name: 'create',
title: '新增',
viewName: 'form',
},
{
type: 'update',
name: 'update',
title: '编辑',
viewName: 'form',
},
{
type: 'destroy',
name: 'destroy',
title: '删除',
filter: {
type: ROLE_TYPE_USER,
default: false
}
},
],
views: [
{
type: 'form',

View File

@ -35,18 +35,20 @@ export class Permissions {
});
database.getModel('collections').addHook('afterCreate', async (model: any, options) => {
console.log('plugin-permissions hook');
// console.log('plugin-permissions hook');
await model.updateAssociations({
scopes: [
{
title: '全部数据',
filter: {},
locked: true
},
{
title: '用户自己的数据',
filter: {
"created_by_id.$currentUser": true,
},
locked: true
},
]
}, options);

View File

@ -1,5 +1,5 @@
import Koa from 'koa';
import request from 'supertest';
import supertest from 'supertest';
import http from 'http';
import Resourcer from '@nocobase/resourcer';
import Database from '@nocobase/database';
@ -9,6 +9,7 @@ describe('middleware', () => {
let app: Koa;
let resourcer: Resourcer;
let database: Database;
let agent;
beforeAll(() => {
app = new Koa();
@ -39,6 +40,7 @@ describe('middleware', () => {
collate: 'utf8mb4_unicode_ci',
},
});
agent = supertest.agent(app.callback());
app.use(middleware({
prefix: '/api',
database,
@ -49,7 +51,7 @@ describe('middleware', () => {
database.table({
name: 'tests',
});
const response = await request(http.createServer(app.callback())).get('/api/tests');
const response = await agent.get('/api/tests');
expect(response.body).toEqual([1,2]);
});
it('shound work', async () => {
@ -71,9 +73,9 @@ describe('middleware', () => {
},
],
});
let response = await request(http.createServer(app.callback())).get('/api/foos/1/bars');
let response = await agent.get('/api/foos/1/bars');
expect(response.body).toEqual([1,2]);
response = await request(http.createServer(app.callback())).get('/api/bars/1/foo');
response = await agent.get('/api/bars/1/foo');
expect(response.body).toEqual([3,4]);
});
it('shound work', async () => {
@ -95,9 +97,9 @@ describe('middleware', () => {
},
],
});
let response = await request(http.createServer(app.callback())).get('/api/foo2s/1/bar2s');
let response = await agent.get('/api/foo2s/1/bar2s');
expect(response.body).toEqual([5,6]);
response = await request(http.createServer(app.callback())).get('/api/bar2s/1/foo2s');
response = await agent.get('/api/bar2s/1/foo2s');
expect(response.body).toEqual([1,2]);
});
});

View File

@ -1,7 +1,6 @@
import qs from 'qs';
import compose from 'koa-compose';
import { pathToRegexp } from 'path-to-regexp';
import Resourcer, { getNameByParams, KoaMiddlewareOptions, parseRequest, parseQuery, ResourcerContext } from '@nocobase/resourcer';
import Resourcer, { getNameByParams, KoaMiddlewareOptions, parseRequest, parseQuery, ResourcerContext, ResourceType } from '@nocobase/resourcer';
import Database, { BELONGSTO, BELONGSTOMANY, HASMANY, HASONE } from '@nocobase/database';
interface MiddlewareOptions extends KoaMiddlewareOptions {
@ -36,22 +35,25 @@ export function middleware(options: MiddlewareOptions = {}) {
}
try {
const resourceName = nameRule(params);
// 如果资源名称未被定义
if (!resourcer.isDefined(resourceName)) {
const names = resourceName.split('.');
const tableName = names.shift();
const [tableName, fieldName] = resourceName.split('.');
const Collection = database.getModel('collections');
// 检查资源对应的表名是否已经定义
if (!database.isDefined(tableName) && Collection) {
// 未定义则尝试通过 collection 表来加载
await Collection.load({
where: {
name: tableName,
},
});
}
// 如果经过加载后是已经定义的表
if (database.isDefined(tableName)) {
const table = database.getTable(tableName);
const field = table.getField(names[0]) as BELONGSTO | HASMANY | BELONGSTOMANY | HASONE;
if (names.length == 0 || field) {
let resourceType = 'single';
const field = table.getField(fieldName) as BELONGSTO | HASMANY | BELONGSTOMANY | HASONE;
if (!fieldName || field) {
let resourceType: ResourceType = 'single';
let actions = {};
if (field) {
if (field instanceof HASONE) {
@ -66,9 +68,14 @@ export function middleware(options: MiddlewareOptions = {}) {
if (field.options.actions) {
actions = field.options.actions;
}
} else {
const items = table.getOptions('actions')||[];
for (const item of (items as any[])) {
actions[item.name] = item;
}
}
resourcer.define({
type: resourceType as any,
type: resourceType,
name: resourceName,
actions,
});