文章组件模板post.component.html
<nz-card> <div> <button nz-button (click)="st.reload()"><i nz-icon nzType="reload" nzTheme="outline"></i>刷新</button> <button nz-button (click)="create()" acl="Root.Admin.Blogs.Post.Create"><i nz-icon type="plus-circle" theme="outline"></i>新增</button> <app-ad-search [request]="request" [columns]="columns" (submited)="search($event)"></app-ad-search> </div> <st #st [data]="readUrl" [columns]="columns" [req]="req" [res]="res" [(pi)]="request.PageCondition.PageIndex" [(ps)]="request.PageCondition.PageSize" [page]="page" size="small" [scroll]="{x:'900px'}" multiSort (change)="change($event)" (error)="error($event)"></st> </nz-card> <nz-modal #modal [nzVisible]="false" [nzTitle]="editTitle" [nzClosable]="false" [nzFooter]="null"> <sf #sf mode="edit" [schema]="schema" [ui]="ui" [formData]="editRow" button="none"> <div> <button nz-button type="button" (click)="close()">关闭</button> <button nz-button type="submit" [nzType]="'primary'" (click)="save(sf.value)" [disabled]="!sf.valid" [nzLoading]="http.loading" [acl]="'Root.Admin.Blogs.Post.Update'">保存</button> </div> </sf> </nz-modal> 模块路由 blogs.routing.ts前端路由负责前端页面的连接导航,一个模块中的路由很简单,只要将组件导航起来即可。
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { ACLGuard } from '@delon/acl'; import { BlogComponent } from './blog/blog.component'; import { PostComponent } from './post/post.component'; const routes: Routes = [ { path: 'blog', component: BlogComponent, canActivate: [ACLGuard], data: { title: '博客管理', reuse: true, guard: 'Root.Admin.Blogs.Blog.Read' } }, { path: 'post', component: PostComponent, canActivate: [ACLGuard], data: { title: '文章管理', reuse: true, guard: 'Root.Admin.Blogs.Post.Read' } }, ]; @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class BlogsRoutingModule { }此外,还需要在根路由配置 routes.routing.ts 上注册当前模块的路由,并使用延迟加载特性
{ path: 'blogs', loadChildren: './blogs/blogs.module#BlogsModule', canActivateChild: [ACLGuard], data: { guard: 'Root.Admin.Blogs' } }, 模块入口 blogs.module.ts模块入口声明一个Angular模块,负责引入其他的公开模块,并声明自己的组件/服务
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { SharedModule } from '@shared'; import { BlogsRoutingModule } from './blogs.routing'; import { BlogComponent } from './blog/blog.component'; import { PostComponent } from './post/post.component'; @NgModule({ imports: [ CommonModule, SharedModule, BlogsRoutingModule ], declarations: [ BlogComponent, PostComponent, ] }) export class BlogsModule { } 菜单数据菜单数据指的是后台管理界面左侧导航菜单,在 assets/osharp/app-data.json 文件中进行配置。
{ "app": { "name": "OSharp Framework", "description": "一个开源的基于 .NETCORE 的快速开发框架" }, "menu": [{ "text": "导航菜单", "i18n": "menu.nav", "group": true, "hideInBreadcrumb": true, "children": [{ "text": "主页", "i18n": "menu.nav.home", "icon": "anticon-dashboard", "link": "/dashboard", "acl": "Root.Admin.Dashboard" }] }, { "text": "业务模块", "i18n": "menu.nav.business", "group": true, "hideInBreadcrumb": true, "children": [{ "text": "博客模块", "group": "true", "icon": "anticon-border", "acl": "Root.Admin.Blogs", "children": [{ "text": "博客管理", "link": "/blogs/blog", "acl": "Root.Admin.Blogs.Blog" }, { "text": "文章管理", "link": "/blogs/post", "acl": "Root.Admin.Blogs.Post" }] }] }, { "text": "权限模块", // ... }] } 前端权限控制OSharp的Angular前端项目的权限控制,是基于 NG-ALAIN 的 ACL 功能来实现的。ACL 全称叫访问控制列表(Access Control List),是一种非常简单的基于角色权限控制方式。
前端权限控制流程代码实现时,基于ACL功能,给需要权限控制的节点配置需要的功能点字符串。配置原则为:执行当前功能主要需要涉及后端的哪个功能点,就在ACL设置哪个功能点的字符串
用户登录时,缓存用户的所有可用功能点集合
前端页面初始化或刷新时(前端路由跳转是无刷新的,只有主动F5或浏览器刷新时,才会刷新),从后端获取当前用户的可用功能点集合
将功能点集合缓存到 ACLService 中,作为ACL权限判断的数据源,然后一切权限判断的事就交给ACL了
ACL 根据 数据源中是否包含设置的ACL功能点 来决定是否显示/隐藏菜单项或按钮,从而达到前端权限控制的目的