mirror of
https://gitee.com/nocobase/nocobase.git
synced 2024-12-03 04:38:15 +08:00
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:
parent
613c4a14ad
commit
db3a8a7499
@ -142,9 +142,9 @@ const data = [
|
|||||||
const [Collection, Page, User] = database.getModels(['collections', 'pages', 'users']);
|
const [Collection, Page, User] = database.getModels(['collections', 'pages', 'users']);
|
||||||
const tables = database.getTables([]);
|
const tables = database.getTables([]);
|
||||||
for (let table of tables) {
|
for (let table of tables) {
|
||||||
console.log(table.getName());
|
// console.log(table.getName());
|
||||||
if (table.getName() === 'roles') {
|
if (table.getName() === 'roles') {
|
||||||
console.log('roles', table.getOptions())
|
// console.log('roles', table.getOptions())
|
||||||
}
|
}
|
||||||
await Collection.import(table.getOptions(), { update: true, migrate: false });
|
await Collection.import(table.getOptions(), { update: true, migrate: false });
|
||||||
}
|
}
|
||||||
|
@ -205,8 +205,12 @@ export class Table {
|
|||||||
return this.options.name;
|
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> {
|
public getModel(): ModelCtor<Model> {
|
||||||
|
@ -55,10 +55,12 @@ export class CollectionModel extends BaseModel {
|
|||||||
*/
|
*/
|
||||||
async loadTableOptions(opts: any = {}) {
|
async loadTableOptions(opts: any = {}) {
|
||||||
const options = await this.getOptions();
|
const options = await this.getOptions();
|
||||||
const prevTable = this.database.getTable(this.get('name'));
|
// const prevTable = this.database.getTable(this.get('name'));
|
||||||
const prevOptions = prevTable ? prevTable.getOptions() : {};
|
// const prevOptions = prevTable ? prevTable.getOptions() : {};
|
||||||
// table 是初始化和重新初始化
|
// table 是初始化和重新初始化
|
||||||
const table = this.database.table({...prevOptions, ...options});
|
const table = this.database.extend(options);
|
||||||
|
// console.log({options, actions: table.getOptions()['actions']})
|
||||||
|
|
||||||
// 如果关系表未加载,一起处理
|
// 如果关系表未加载,一起处理
|
||||||
// const associationTableNames = [];
|
// const associationTableNames = [];
|
||||||
// for (const [key, association] of table.getAssociations()) {
|
// for (const [key, association] of table.getAssociations()) {
|
||||||
@ -120,6 +122,7 @@ export class CollectionModel extends BaseModel {
|
|||||||
async getOptions(): Promise<TableOptions> {
|
async getOptions(): Promise<TableOptions> {
|
||||||
return {
|
return {
|
||||||
...this.get(),
|
...this.get(),
|
||||||
|
actions: await this.getActions(),
|
||||||
fields: await this.getFieldsOptions(),
|
fields: await this.getFieldsOptions(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,6 @@ export async function get(ctx: actions.Context, next: actions.Next) {
|
|||||||
limit: 1,
|
limit: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(permission);
|
|
||||||
|
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
...permissions,
|
...permissions,
|
||||||
description: _.get(permission, 'description'),
|
description: _.get(permission, 'description'),
|
||||||
|
@ -30,6 +30,16 @@ export default {
|
|||||||
showInForm: true,
|
showInForm: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
interface: 'boolean',
|
||||||
|
type: 'boolean',
|
||||||
|
name: 'locked',
|
||||||
|
title: '锁定',
|
||||||
|
defaultValue: false,
|
||||||
|
component: {
|
||||||
|
showInTable: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'belongsTo',
|
type: 'belongsTo',
|
||||||
name: 'collection',
|
name: 'collection',
|
||||||
|
@ -14,6 +14,16 @@ export default extend({
|
|||||||
list: {
|
list: {
|
||||||
sort: 'id',
|
sort: 'id',
|
||||||
},
|
},
|
||||||
|
update: {
|
||||||
|
filter: {
|
||||||
|
locked: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
destroy: {
|
||||||
|
filter: {
|
||||||
|
locked: false
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
component: {
|
component: {
|
||||||
type: 'drawerSelect',
|
type: 'drawerSelect',
|
||||||
|
@ -84,6 +84,39 @@ export default {
|
|||||||
name: 'permissions'
|
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: [
|
views: [
|
||||||
{
|
{
|
||||||
type: 'form',
|
type: 'form',
|
||||||
|
@ -35,18 +35,20 @@ export class Permissions {
|
|||||||
});
|
});
|
||||||
|
|
||||||
database.getModel('collections').addHook('afterCreate', async (model: any, options) => {
|
database.getModel('collections').addHook('afterCreate', async (model: any, options) => {
|
||||||
console.log('plugin-permissions hook');
|
// console.log('plugin-permissions hook');
|
||||||
await model.updateAssociations({
|
await model.updateAssociations({
|
||||||
scopes: [
|
scopes: [
|
||||||
{
|
{
|
||||||
title: '全部数据',
|
title: '全部数据',
|
||||||
filter: {},
|
filter: {},
|
||||||
|
locked: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '用户自己的数据',
|
title: '用户自己的数据',
|
||||||
filter: {
|
filter: {
|
||||||
"created_by_id.$currentUser": true,
|
"created_by_id.$currentUser": true,
|
||||||
},
|
},
|
||||||
|
locked: true
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}, options);
|
}, options);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Koa from 'koa';
|
import Koa from 'koa';
|
||||||
import request from 'supertest';
|
import supertest from 'supertest';
|
||||||
import http from 'http';
|
import http from 'http';
|
||||||
import Resourcer from '@nocobase/resourcer';
|
import Resourcer from '@nocobase/resourcer';
|
||||||
import Database from '@nocobase/database';
|
import Database from '@nocobase/database';
|
||||||
@ -9,6 +9,7 @@ describe('middleware', () => {
|
|||||||
let app: Koa;
|
let app: Koa;
|
||||||
let resourcer: Resourcer;
|
let resourcer: Resourcer;
|
||||||
let database: Database;
|
let database: Database;
|
||||||
|
let agent;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
app = new Koa();
|
app = new Koa();
|
||||||
@ -39,6 +40,7 @@ describe('middleware', () => {
|
|||||||
collate: 'utf8mb4_unicode_ci',
|
collate: 'utf8mb4_unicode_ci',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
agent = supertest.agent(app.callback());
|
||||||
app.use(middleware({
|
app.use(middleware({
|
||||||
prefix: '/api',
|
prefix: '/api',
|
||||||
database,
|
database,
|
||||||
@ -49,7 +51,7 @@ describe('middleware', () => {
|
|||||||
database.table({
|
database.table({
|
||||||
name: 'tests',
|
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]);
|
expect(response.body).toEqual([1,2]);
|
||||||
});
|
});
|
||||||
it('shound work', async () => {
|
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]);
|
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]);
|
expect(response.body).toEqual([3,4]);
|
||||||
});
|
});
|
||||||
it('shound work', async () => {
|
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]);
|
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]);
|
expect(response.body).toEqual([1,2]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import qs from 'qs';
|
|
||||||
import compose from 'koa-compose';
|
import compose from 'koa-compose';
|
||||||
import { pathToRegexp } from 'path-to-regexp';
|
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';
|
import Database, { BELONGSTO, BELONGSTOMANY, HASMANY, HASONE } from '@nocobase/database';
|
||||||
|
|
||||||
interface MiddlewareOptions extends KoaMiddlewareOptions {
|
interface MiddlewareOptions extends KoaMiddlewareOptions {
|
||||||
@ -36,22 +35,25 @@ export function middleware(options: MiddlewareOptions = {}) {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const resourceName = nameRule(params);
|
const resourceName = nameRule(params);
|
||||||
|
// 如果资源名称未被定义
|
||||||
if (!resourcer.isDefined(resourceName)) {
|
if (!resourcer.isDefined(resourceName)) {
|
||||||
const names = resourceName.split('.');
|
const [tableName, fieldName] = resourceName.split('.');
|
||||||
const tableName = names.shift();
|
|
||||||
const Collection = database.getModel('collections');
|
const Collection = database.getModel('collections');
|
||||||
|
// 检查资源对应的表名是否已经定义
|
||||||
if (!database.isDefined(tableName) && Collection) {
|
if (!database.isDefined(tableName) && Collection) {
|
||||||
|
// 未定义则尝试通过 collection 表来加载
|
||||||
await Collection.load({
|
await Collection.load({
|
||||||
where: {
|
where: {
|
||||||
name: tableName,
|
name: tableName,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// 如果经过加载后是已经定义的表
|
||||||
if (database.isDefined(tableName)) {
|
if (database.isDefined(tableName)) {
|
||||||
const table = database.getTable(tableName);
|
const table = database.getTable(tableName);
|
||||||
const field = table.getField(names[0]) as BELONGSTO | HASMANY | BELONGSTOMANY | HASONE;
|
const field = table.getField(fieldName) as BELONGSTO | HASMANY | BELONGSTOMANY | HASONE;
|
||||||
if (names.length == 0 || field) {
|
if (!fieldName || field) {
|
||||||
let resourceType = 'single';
|
let resourceType: ResourceType = 'single';
|
||||||
let actions = {};
|
let actions = {};
|
||||||
if (field) {
|
if (field) {
|
||||||
if (field instanceof HASONE) {
|
if (field instanceof HASONE) {
|
||||||
@ -66,9 +68,14 @@ export function middleware(options: MiddlewareOptions = {}) {
|
|||||||
if (field.options.actions) {
|
if (field.options.actions) {
|
||||||
actions = 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({
|
resourcer.define({
|
||||||
type: resourceType as any,
|
type: resourceType,
|
||||||
name: resourceName,
|
name: resourceName,
|
||||||
actions,
|
actions,
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user