基于AngularJs的单页面程序
在Abpzero的后台管理系统是一个AngularJs的单页面程序。当你登陆后,系统会跳转到“ApplicationController”,然后再返回到视图的布局页面(模板页)。
注意: 多页面版本是基于MVC和JQuery的我们后续会提到。
应用层的文件夹:
这里有三个主要的文件夹:
- common : 包含了host和tenants 双方用户公用的资源。
- host: host用户也就是上帝视角的特定资源文件。
- tenant: 包含了一些特定租户的资源文件。
所以当我们的视图、services、images、等文件是租户和host共同使用的时候。建议将他们放到common文件夹中。
主菜单
主菜单可以在 AppNavigationProvider 中定义。他的位置自己从图中找哈。如果想对菜单配置文件的有更加深入的了解呢,可以从ABP的文档中"导航菜单"查找。
路由
app.js是SPA管理程序的入口。我们在这定义Angular的模块和Angular的路由。路由是动态的基于当前用户所拥有的权限,如果你有权限可以看到菜单反之则看不见,具体可以参考(授权部分)。
示例代码:
if (abp.auth.hasPermission('Pages.Administration.Tenant.Settings')) {
$stateProvider.state('tenant.settings', {
url: '/settings',
templateUrl: '~/App/tenant/views/settings/index.cshtml',
menu: 'Administration.Settings.Tenant'
});
}
带有条件性质(权限控制)的路由定义,可以防止用户通过url拼接字符串的形式来访问一个页面。
menu: 表示路由访问时,如果有权限的话,会显示到视图上。
虽然.html文件也可以用来当做视图,但是跟.cshtml相比。.cshtml文件可以使用更加强大的razor语法来渲染,这个是html所不具备的。
LAYOUT布局 模板文件
模板页位置/common/views/layout 所有的js、样式表的引用都在模板页中,可以参见“AppBundleConfig ”类。
如果你有新的css或者是js文件都可以放到app中的指定的文件夹,这样他们就可以自动引用到 layout视图模板页中。
后台管理的左侧边栏就是由上图组成。
版本控制
如果你是单租户模式可以选择不用看它。
大多数的 Sass(多租户) 程序中都有版本控制,它可以使得租户们拥有各自的特点。
这样的好处是:你可以提供不同的价格和功能让租户们选择。
登录host 版本,上帝视角 可以进行版本管理:
版本是通过分组的方式将特定的功能分配给租户。
当我们点击“actions”时,可以看到:
ABPZERO制作了3个简单的示例版本。你可以通过删除所有的版本,来创建一个属于你自己的版本功能库。
所有的功能可以在“AppFeatureProvider ”类中定义。
这里功能存储在数据库表“AbpFeatures ”中。
你可以参阅ABP文档 “特征管理”和“版本管理”文档来了解深层次的信息
租户管理
还是那句话,你如果不是开发多租户系统,可以不用看它。
当你从上帝视角登录后,Host模式。在你后台管理中找到以下功能:
租户是由“Tenant”类来实现。在租户类中可以给租户添加新的拓展属性。
目前由有一个默认租户,租户名称:“Default”。 租户名称是唯一的不会重复。
租户可以是“active”或者“passive”的状态。如果是“passive”状态租户用户就无法登陆到程序中。(亲:你的程序需要付费了哦。不然封号了。)
创建一个新的租户
点击“Create new Tenant”按钮
- "Tenancy name" 必须是唯一的并且不能包含任何的空格和特殊字符。因为它可能作为子域名比如:tenancyname.mydomain.com 。
- “ Name” 这里就开心就好,公司名称,项目名称都可以。
- “Admin Email” 作为新租户系统的管理员电子邮件。系统会自动给它创建一个管理员并且会发送一个带了随机密码的账号发送到该电子邮件中。当用户首次登陆的时候,会要求他更改密码。当然这个功能也是可选的
当我们创建一个的租户系统的时候,我们可以选择使用跟“Host”数据库一起使用(单数据库多租户模式)。也可以单独给租户配置一个独立数据库。ABPZERO支持“hybrid”方法。这个意味着你可以将租户和host分开,甚至你可以建立一个group组来区分租户们。
是不是有一种云主机的感觉啊。
所有的租户功能都是由“TenantAppService ”类来统一管理。
举个例子:
这是一个删除租户的例子。
[AbpAuthorize(AppPermissions.Pages_Tenants_Delete)]
public async Task DeleteTenant(EntityRequestInput input)
{
var tenant = await TenantManager.GetByIdAsync(input.Id);
CheckErrors(await TenantManager.DeleteAsync(tenant));
}
TenantAppService 主要是使用TenantManager领域类中的方法来实现管理租客行动。
租客版本控制和功能管理
当编辑或者新建一个租户的时候,可以分配一个版本给它。租户将继承分配版本的所有功能。当然我们也可以重写分配给租户的功能。
下图就是重新给一个租户分配一个个性化的功能。
模拟租户登录
作为Host的用户,我们可以测试下租户的功能。在这种事情,可以点击“actions” 按钮,选择“login as this tenant” 选项
作为选择的租户登录。
点击后,我们就是该租户系统的用户了。我们可以选择任何该用户权限内的可以做的任何事情。详情可以参考“用户模拟”章节
将租户名称用做子域名
激动不。
多租户系统,通常使用子域名来标识当前的房客。如:tenant1.yoyocms.com、tenant2.yoyocms.com 等等。 ABPZERO 只需要你在 “host settings section” 中配置下,就可以自动实现。
组织单位
组织单位(OU) 用于区分不同的分组不同的用户,然后得到他们分组目录下的用户信息。当我们点击进入时:
在这里我们可以(创建、编辑、移动、删除)组织单元以及对成员的(添加、删除)
OrganizationUnitManager 用于管理组织单位
UserManager 可以对处于OU中的用户进行管理
OrganizationUnitAppService 执行具体的业务逻辑
PS:这里大家要明白ABP框架中service和manager的区别。不然你会吃亏的(译者)
在左边的 OU 树中,我们可以操作菜单栏。如果要添加某一个用户,选中它就可以了。
这里的搜索框实际上是个通用搜索模式。你可以用来选择任何类型的实体
见(App/common/views/common/lookup.js 和对应的视图文件)。
我们在CommonLookupAppService类中创建一个FindUsers方法,然后通过实现该方法来选中你需要的用户信息。见( organizationUnits/index.js 文件 中对lookupModal.open的用法)
更加详细的资料可以参考 “ organization unit management document ”文档。
角色管理
当我们点击 角色管理 时,进入角色管理页面:
角色会用到 **group **权限。当一个用户拥有某一个角色时,该用户可以使用该角色下的所有权限。
角色是通过 Role类来实现的。你可以对ROle类添加新的拓展方法。
RoleManger 处理领域层的逻辑。
RoleAppService 执行业务层的逻辑。
角色可以是动态或静态:
- 静态角色:一个静态角色有一个默认名字(如:“admin”),这个名字不可以更改。(我们可以更改显示的昵称)。它是默认在系统启动时就存在了的,并且无法被删除。因此我们可以在静态角色名称上写代码。
- 动态角色:我们在程序部署后创建一个动态角色。然后我们可以授予该角色权限,我们可以将这个角色分配给某些用户,我们可以将该角色删除。
默认角色:
我们可以将一个或者多个角色设置为默认角色。默认角色可以分配给新添加/注册用户的默认值。该功能推荐在部署项目后设置。
在启动项目中,我们的Host(上帝模式)有一个静态角色“Admin”(国内感觉叫系统角色听起来更加的顺耳)。同时我们也给租户们分配了两个静态角色分别为:”admin“和”user“。”admin“顾名思义,可以管理所有租户系统的功能。”user“角色是为默认角色没有权限,每一个新建的用户都会继承”user“角色。
当然我们可以从“StaticRoleName”类中查看所有的静态角色,AppRoleConfig对静态角色进行修改。
角色权限
因为角色使用了组权限,我们可以通过创建、编辑权限来控制角色见下图(该处未显示所有权限):
每一个租户都有他自己的角色,角色发生变化的时候,不会影响到其他租户。
PS:Host的角色也是独立的,不会产生冲突。
用户管理
我们点击“用户管理” ,看到如下界面:
用户可以登录到后台执行某些操作,这个和你分配给他的权限有关。
user通过User类实现。你可以对User类添加新的拓展方法。
UserManger 处理领域层的逻辑
UserAppService 用于处理业务中的逻辑
用户可以拥有0个或者多个角色,没有强制要求。如果他有多个权限将拥有这些角色所有的权限。我们可以给用户单独分配特定的 权限。分配了特定权限的用户会覆盖掉已经拥有角色设置。见下图:
编辑用户对话框:
我们可以修改用户的密码,设置他的 角色为动态或者是静态的等等。用户有一个头像。
用户可以自己修改(见:用户菜单部分)。无法删除admin用户。如果你不想使用该管理员,你可以禁用掉它。
用户模拟
作为管理员(或者拥有权限的用户),我们可能需要某一个用户身份进行登录,而没有他的密码。那么你可以从下图中点击“作为该用户”登录:
当我们点击它时,我们会自动重定向,并且以该身份登录。
这被称为“用户模拟”。当我们模拟用户,需要回到管理员身份的时候点击“返回我的账户”选项,见下图:
当我们模拟该用户的时候,只能执行该用户拥有的权限。这意味着你可以把自己当做该用户操作。唯一的区别就是:审查日志会记录下这个是别人操作的。
注意:返回我的账户时候,这里的图片为红色,提示你在模拟别人的账户。
模拟是在AccountController的web项目中完成的。
语言管理
语言管理页面是用来管理(创建、编辑、删除)语言和修改本地化的文本:
我们可以创建一种新的语言、编辑或删除现有的语言和设置默认语言。当我们点击“更改文本”的时候,我们会跳转到新页面,编辑语言文本。
我们可以选择任何一种语言作为一个基类(base value)并且更改目标(target value)语言文本。你也可以参考本地化文档,来选择需要翻译的源文件。
当我们点击编辑图标的时候,我们可以看到所选的文本编辑模式:
如果有权限的话,Host用户是可以编辑语言和本地化的文本的。这些语言将做为默认语言配置给所有的租户。
租户继承语言和本地化的文本可以重写属于自己的本地化文本,也可以添加新的语言。
这两个网页都使用了 LanguageAppService类作为服务程序。他具有管理语言和本地化的文本方法。
IApplicationLanguageManager 和 IApplicationLanguageTextManager 两个接口用于领域层的业务逻辑。(如使用 LanguageAppService)。
请参阅语言管理文档的详细文档。
审核日志
在审计日志页面中,我们可以看到所有用户的在该系统中的操作。
所有的应用层的服务方法和MVC控制器的操作都将自动记录,可以此处查看。
请参阅 审核日志文件以了解如何配置使用它。
审核日志服务通过 AuditLogService类来实现。
HOST设置
HostSetting 页面用来配置一些系统设置:
Web 站点的根地址是很重要的。尤其是在生产环境中。 {TENANCY_NAME}作为一个占位符。他是可选功能(单租户和多租户都适用)。
如果开启该功能的话,目前租客名称是自动检测的。
为了让子域正常的工作,我们需要在服务层中做以下两点配置:
- 我们应配置DNS并且所有的子域重定向到一个静态ip地址。
- 我们在配置IIS的时候,将这种静态ip绑定到我们的项目中。
当然也可能有其他的做法,可以自行搜索,但目前这个是最简单的做法。
该页面另外一个重要的功能时区,ABPZERO是一个可以工作在多个时区内的程序。所有的 DateTimes 存储都是以“UTC” 时区为默认值,每个用户可以看到当前的时间和自己所在的时区。
当然你也可以在这个页面默认给所有租户以及用户设置默认的时区。
租户和用户可以更改属于自己的时区。
在主机设置中,也有其他的设置功能。点击“全部保存”按钮时,会保存所有的设置信息。
HostSettingAppService 是用于搜索和保存你的设置(具体可以参考 “setting provider” 中的详细内容)。
租户设置
在多租户应用中,显示的租户设置如下图所示:
如果我们禁用掉多租户功能,某些主机设置会显示在此页面中(图为没有主机设置的页面)
PS: 主机设置 就是HOST,也就是上文戏谑过上帝视角
下图为EMAIL 配置信息:
TenantSettingAppService 是用于 查询和设置租客的服务层
启用 (活动目录) LDAP 身份验证
原标题 ENABLING LDAP (ACTIVE DIRECTORY) AUTHENTICATION 还没有想到具体应该怎么翻译。
默认情况下,LDAP(Active Directory)身份验证是被禁用掉的。如果要启动它,如果要启用它,那么应该禁用多租户系统。因为在通常情况下LDAP不适用于多租户中的身份验证。如果要启用它。
在CoreModule类中。位于"Core"类库中,启用代码:
Configuration.Modules.ZeroLdap().Enable(typeof(AppLdapAuthenticationSource));
然后我们就可以看到LDAP设置在页面中的节点:
我们可以验证“Enable LDAP Authentication” 启用LDAP授权来启动它。如果项目在生产环境中,一般是不需要设置域名、用户名和密码的。如果不能启用的话,那么就需要你进行设置这些信息了。
维护
维护功能,只提供给了Host,下图所示:
在“Caches”缓存选项卡中,我们可以清除一些或者所有的缓存。如果你有手动更改数据库,或者想要手动刷项目中的缓存,就需要清除缓存。
CacheingAppService 可以用来清除缓存的服务层。
网站日志 选项卡可用来查看和下载日志:
WebLogAppService 服务层可以获取日志记录
租户工作台(仪表盘)
ABPZERO 启动项目中包含了示例仪表盘,它仅用来演示而已,当然你可以用来作为你真实项目的起点。
此页面中,只有“Member Activity” 数据是从服务器查询出来的(从 TenantDashboardAppService)。你可以单击刷新按钮以生成随机头像。
通知
通知图标位于语言选择按钮旁边。红色圆圈中的数据显示未读的通知计数。
用户可以通过点击此图标查看最近的3条通知。
用户可以标记所有通知为已读通过点击“set all as read”(标记为全部已读),或者通过点击每个通知旁边的“已读”链接来标记单个通知。
通知设置
“设置”链接打开通知设置对话框。
在此对话框中还有对用户设置“启用/禁用”接收通知的全局设置。
如果启用了此设置,用户可以对每个通知进行“启用/禁用”。
AppNotificationProvider 类中进行自定义通知。
新用户的注册通知也是在AppNotificationProvider类中定义,如下图所示:
context.Manager.Add(
new NotificationDefinition(
AppNotificationNames.NewUserRegistered,
displayName: L("NewUserRegisteredNotificationDefinition"),
permissionDependency: new SimplePermissionDependency(AppPermissions.Pages_Administration_Users)
)
);
具体可以参考文档“通知定义”的详细文档。
AppNotifier类用来发布通知。
NotificationAppService用来管理通知的应用层逻辑。
具体可以看“通告文档”
通知列表
在此页面中列出了用户的所有通知。
用户菜单
关联账户
关联账户是将多个账户关联在一起。
以这种方式,用户可以通过“关联账户”功能来浏览他/她的帐户。
当用户要链接新的帐户时,或通过单击“管理账户”链接来删除已关联的帐户。
当要关联一个新的账户时,用户必须输入相关账户的登录凭据。
UserLinkAppService类是用于管理服务层中逻辑的,
UserLinkManager类是用于管理领域层中的逻辑。
个人设置
此处除开“admin”用户名,因为他是数据库中的默认值。其他的用户可以自行修改用户名。
username此项已经做了正则判断,不能输入特殊字符。
控制该功能的类为:ProfileAppService
登录信息
当我们登录成功的时候,就可以本次登录成功的信息,以及上次登录失败的信息。
以上信息均从 UserLoginAppService 获取
图片更改
用户可以更改自己的头像。
ProfileController 控制器有上传和获取用户头像。Angular file upload模块可以选择上传图片到服务端。目前该功能只支持jpg/jpeg两种格式,你可以对它进行拓展。
更改密码
ProfileAppService 用户更改密码
注销
AccountController 注销用户和重定向到登录页。