mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 13:39:24 +08:00
171 lines
5.1 KiB
TypeScript
171 lines
5.1 KiB
TypeScript
/**
|
|
* This file is part of the NocoBase (R) project.
|
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
* Authors: NocoBase Team.
|
|
*
|
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
*/
|
|
|
|
import { Model } from '@nocobase/database';
|
|
import { Plugin } from '@nocobase/server';
|
|
import PluginLocalizationServer from '@nocobase/plugin-localization';
|
|
import { tval } from '@nocobase/utils';
|
|
import actions, { Context } from '@nocobase/actions';
|
|
|
|
export class PluginMobileServer extends Plugin {
|
|
async load() {
|
|
this.registerActionHandlers();
|
|
this.bindNewMenuToRoles();
|
|
this.setACL();
|
|
this.registerLocalizationSource();
|
|
|
|
this.app.db.on('mobileRoutes.afterUpdate', async (instance: Model, { transaction }) => {
|
|
if (instance.changed('enableTabs')) {
|
|
const repository = this.app.db.getRepository('mobileRoutes');
|
|
await repository.update({
|
|
filter: {
|
|
parentId: instance.id,
|
|
},
|
|
values: {
|
|
hidden: !instance.enableTabs,
|
|
},
|
|
transaction,
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
setACL() {
|
|
this.app.acl.registerSnippet({
|
|
name: `ui.mobile`,
|
|
actions: ['mobileRoutes:create', 'mobileRoutes:update', 'mobileRoutes:move', 'mobileRoutes:destroy'],
|
|
});
|
|
|
|
this.app.acl.registerSnippet({
|
|
name: `pm.mobile`,
|
|
actions: ['mobileRoutes:list', 'roles.mobileRoutes:*'],
|
|
});
|
|
|
|
this.app.acl.allow('mobileRoutes', 'listAccessible', 'loggedIn');
|
|
}
|
|
|
|
/**
|
|
* used to implement: roles with permission (allowNewMobileMenu is true) can directly access the newly created menu
|
|
*/
|
|
bindNewMenuToRoles() {
|
|
this.app.db.on('roles.beforeCreate', async (instance: Model) => {
|
|
instance.set('allowNewMobileMenu', ['admin', 'member'].includes(instance.name));
|
|
});
|
|
this.app.db.on('mobileRoutes.afterCreate', async (instance: Model, { transaction }) => {
|
|
const addNewMenuRoles = await this.app.db.getRepository('roles').find({
|
|
filter: {
|
|
allowNewMobileMenu: true,
|
|
},
|
|
transaction,
|
|
});
|
|
|
|
// @ts-ignore
|
|
await this.app.db.getRepository('mobileRoutes.roles', instance.id).add({
|
|
tk: addNewMenuRoles.map((role) => role.name),
|
|
transaction,
|
|
});
|
|
});
|
|
}
|
|
|
|
registerActionHandlers() {
|
|
this.app.resourceManager.registerActionHandler('mobileRoutes:listAccessible', async (ctx, next) => {
|
|
const mobileRoutesRepository = ctx.db.getRepository('mobileRoutes');
|
|
const rolesRepository = ctx.db.getRepository('roles');
|
|
|
|
if (ctx.state.currentRole === 'root') {
|
|
ctx.body = await mobileRoutesRepository.find({
|
|
tree: true,
|
|
...ctx.query,
|
|
});
|
|
return await next();
|
|
}
|
|
|
|
const role = await rolesRepository.findOne({
|
|
filterByTk: ctx.state.currentRole,
|
|
appends: ['mobileRoutes'],
|
|
});
|
|
|
|
const mobileRoutesId = role.get('mobileRoutes').map((item) => item.id);
|
|
|
|
ctx.body = await mobileRoutesRepository.find({
|
|
tree: true,
|
|
...ctx.query,
|
|
filter: {
|
|
id: mobileRoutesId,
|
|
},
|
|
});
|
|
|
|
await next();
|
|
});
|
|
const processRoleMobileRoutes = async (ctx: Context, next) => {
|
|
const actionName = ctx.action.actionName;
|
|
await actions[actionName](ctx, next);
|
|
|
|
const tabs = await this.app.db.getRepository('mobileRoutes').find({
|
|
where: {
|
|
parentId: ctx.action.params.values,
|
|
},
|
|
});
|
|
if (tabs.length > 1 || !tabs[0].hidden) {
|
|
return;
|
|
}
|
|
const repository = this.app.db.getRepository('rolesMobileRoutes');
|
|
const whereOrValues = {
|
|
roleName: ctx.action.params.associatedIndex,
|
|
mobileRouteId: tabs[0].id,
|
|
};
|
|
const rolesMobileRoute = await repository.findOne({ where: whereOrValues });
|
|
|
|
if (actionName === 'add') {
|
|
!rolesMobileRoute && (await repository.create({ values: whereOrValues }));
|
|
}
|
|
if (actionName === 'remove') {
|
|
rolesMobileRoute && (await repository.destroy({ filter: whereOrValues }));
|
|
}
|
|
};
|
|
this.app.resourceManager.registerActionHandlers({
|
|
'roles.mobileRoutes:add': processRoleMobileRoutes,
|
|
'roles.mobileRoutes:remove': processRoleMobileRoutes,
|
|
});
|
|
}
|
|
|
|
registerLocalizationSource() {
|
|
const localizationPlugin = this.app.pm.get('localization') as PluginLocalizationServer;
|
|
if (!localizationPlugin) {
|
|
return;
|
|
}
|
|
localizationPlugin.sourceManager.registerSource('mobile-routes', {
|
|
title: tval('Mobile routes'),
|
|
sync: async (ctx) => {
|
|
const mobileRoutes = await ctx.db.getRepository('mobileRoutes').find({
|
|
raw: true,
|
|
});
|
|
const resources = {};
|
|
mobileRoutes.forEach((route: { title?: string }) => {
|
|
if (route.title) {
|
|
resources[route.title] = '';
|
|
}
|
|
});
|
|
return {
|
|
'lm-mobile-routes': resources,
|
|
};
|
|
},
|
|
namespace: 'lm-mobile-routes',
|
|
collections: [
|
|
{
|
|
collection: 'mobileRoutes',
|
|
fields: ['title'],
|
|
},
|
|
],
|
|
});
|
|
}
|
|
}
|
|
|
|
export default PluginMobileServer;
|