开源地址: https://github.com/EasyAbp/Abp.SettingUi

一直想宣传一下SettingUi, 因为 懒 工作比较忙, 所以才拖到今天.

关于ABP就不需要我再多废口舌了, 已经是一个非常出名的.NET Core的框架, 在国内也已经有很多企业在正式项目中广泛使用了.

Abp.SettingUi是一个用来管理Abp中设置的模块, 简单来讲它可以让用户通过UI来管理ABP中各个设置的值, 比如修改默认语言, 设置密码复杂度等等, 可以说装上这个模块你就开启了ABP的"隐藏功能".

应该说设置管理是一个很重要的功能, 但是ABP的社区版没有内置, 只在ABP的商业版中才有设置的UI, 但仍需开发者通过代码来为各个设置项进行适配才可以.

而SettingUi会自动扫描系统中所有的设置, 并在UI中显示出来, 无需开发者过多干预, 开箱即用.

从发布至今, SettingUi在NUGET上已经有近7000次下载, 可以说是ABP中非常实用一个模块, 甚至也有ABP商业版用户来使用这个模块, 可见SettingUi得到了很多ABP开发者的认可.

为了更好的让国内开发者使用, SettingUi 1.3.0版增加了中文文档, 该文档是我花了很多心思写的一个Step by Step的教程, 所以接下来就是该文档复制过来, 希望能吸引更多的使用者:)


Abp.SettingUi

一个用来管理ABP设置的模块

如果你在使用 ABP v2.1.1 之前的版本, 请查看Abp.SettingManagement.Mvc.UI

功能

  • 通过UI管理ABP设置的值
  • 支持本地化
  • 设置分组
  • 为不同设置显示适当的控件
  • 可通过权限控制设置的显示

在线演示

我们为这个模块创建了一个在线演示: https://settingui.samples.easyabp.io

安装

使用AbpHelper (推荐)

在你的ABP项目的根文件夹中运行以下命令:

abphelper module add EasyAbp.Abp.SettingUi -acshlw

手动安装包

  1. 安装以下 NuGet 包.

    • EasyAbp.Abp.SettingUi.Application
    • EasyAbp.Abp.SettingUi.Application.Contracts
    • EasyAbp.Abp.SettingUi.Domain.Shared
    • EasyAbp.Abp.SettingUi.HttpApi
    • EasyAbp.Abp.SettingUi.HttpApi.Client (只有 分层结构 才需要)
    • EasyAbp.Abp.SettingUi.Web
  2. 添加 DependsOn(typeof(AbpSettingUiXxxModule)) 属性来配置模块依赖. (帮助)

配置本地化资源

为了让SettingUi模块使用应用程序的本地化资源, 我们需要将它们添加进SettingUiResource:

  • MyAbpApp.Domain.Shared 项目 - MyAbpAppDomainSharedModule

    Configure<AbpLocalizationOptions>(options =>
    {
    ...
    options.Resources
    .Get<SettingUiResource>()
    .AddVirtualJson("/Localization/MyAbpApp");
    });

使用

  1. 授权 ("Setting UI" - "Show Setting Page")

  2. 刷新浏览器, 然后你就可以使用 "Administration" - "Settings" 菜单来看见所有ABP内置的设置了

管理自定义设置

除了ABP自定义设置以外, 你也可以使用这个模块来管理你自己的设置.

  1. 定义一个设置

    • MyAbpApp.Domain 项目 - Settings/MyAbpAppSettingDefinitionProvider

      public class MyAbpAppSettingDefinitionProvider : SettingDefinitionProvider
      {
      public override void Define(ISettingDefinitionContext context)
      {
      context.Add(
      new SettingDefinition(
      "Connection.Ip", // 设置的名称
      "127.0.0.1", // 默认值
      L("DisplayName:Connection.Ip"), // 显示名称
      L("Description:Connection.Ip") // 描述
      ));
      } private static LocalizableString L(string name)
      {
      return LocalizableString.Create<MyAbpAppResource>(name);
      }
      }
      • 设置的名称为"Connection.Ip"
      • 提供了一个默认值: "127.0.0.1"
      • 使用帮助方法 L显示名称描述 赋予了可本地化的字符串. 格式 "DisplayName:{SettingName}" 是ABP推荐的形式.

      ABP的设置系统, 请参见 设置文档

  2. 定义本地化资源, 出于演示目的, 我们定义了英语和简体中文的本地化资源

    • MyAbpApp.Domain.Shared 项目

      • Localization/MyAbpApp/en.json

        {
        "culture": "en",
        "texts": {
        ...
        "DisplayName:Connection.Ip": "IP",
        "Description:Connection.Ip": "The IP address of the server."
        }
        }
      • Localization/MyAbpApp/zh-Hans.json

        {
        "culture": "zh-Hans",
        "texts": {
        ...
        "DisplayName:Connection.Ip": "IP",
        "Description:Connection.Ip": "服务器的IP地址."
        }
        }
  3. 重新启动应用程序, 我们可以看到设置显示了, 并且本地化也正常工作

分组

你可能注意到我们的自定义设置显示在"其它"标签, "其它"卡片中, 这些是默认的分组, 分别称之为"Group1"和"Group2"

那么我们如何自定义这些设置的分组呢? 有两种方式:

  1. 使用 WithProperty 方法

    WithProperty 方法是由ABPSettingDefinition类提供的一个方法, 我们可以直接在设置定义中使用它:

    • MyAbpApp.Domain 项目 - Settings/MyAbpAppSettingDefinitionProvider

      context.Add(
      new SettingDefinition(
      "Connection.Ip", // 设置名称
      "127.0.0.1", // 默认值
      L("DisplayName:Connection.Ip"), // 显示名称
      L("Description:Connection.Ip") // 描述
      )
      .WithProperty(SettingUiConst.Group1, "Server")
      .WithProperty(SettingUiConst.Group2, "Connection")
      );
      • 常量 Group1Group2 定义在 SettingUiConst类中
      • 设置 "Group1" 为 "Server", "Group2" 为 "Connection"

    然后我们应该为这两个分组名字提供本地化资源:

    • MyAbpApp.Domain.Shared 项目

      • Localization/MyAbpApp/en.json

        {
        "culture": "en",
        "texts": {
        ...
        "Server": "Server",
        "Connection": "Connection"
        }
        }
      • Localization/MyAbpApp/zh-Hans.json

        {
        "culture": "zh-Hans",
        "texts": {
        ...
        "Server": "服务器",
        "Connection": "连接"
        }
        }

    重新启动应用程序查看分组名称是否正确设置

  2. 使用设置属性文件

    另一种分组方式是使用设置分组文件, 该方式由SettingUi模块提供. 当你不太容易修改设置的定义, 或者你想将分组信息汇集在一个单独的位置时, 这种方式很有用.

    为了演示这种方式, 让我们定义一个新设置:

    • MyAbpApp.Domain 项目 - Settings/MyAbpAppSettingDefinitionProvider

      new SettingDefinition(
      "Connection.Port",
      8080.ToString(),
      L("DisplayName:Connection.Port"),
      L("Description:Connection.Port")
      )

    为这个设置添加本地化的步骤省略了.

    然后我们需要创建一个新的任意名字的JSON文件, 但是路径必须为"/SettingProperties", 这是因为SettingUi模块将会从这个路径下查找设置属性文件.

    • MyAbpApp.Domain.Shared 项目 - /SettingProperties/MySettingProperties.json 文件

      {
      "Connection.Port": {
      "Group1": "Server",
      "Group2": "Connection"
      }
      }
      • 设置名称 Connection.Port 做为JSON对象的键
      • 使用 "Group1" 和 "Group2" 来设置分组名称
    • 重新启动应用程序来查看新分组的设置

设置类型

默认情况下, 一个设置的值是字符串类型, 将会在UI中渲染为一个文本输入控件. 我们可以简单地提供一个设置属性"Type"来定制它:

  • MyAbpApp.Domain.Shared 项目 - /SettingProperties/MySettingProperties.json 文件

    {
    "Connection.Port": {
    "Group1": "Server",
    "Group2": "Connection",
    "Type": "number"
    }
    }
    • "Connection.Port" 设置类型为 "number"

不用重新启动应用程序, 只需要按下F5来刷新浏览器, 你可以立即看到效果:

现在输入的类型变更为了"数字", 并且前端的验证也生效了.

设置类型也可以通过 WithProperty 方法来配置, 如 WithProperty("Type", "number")

目前SettingUi支持以下几种设置类型:

  • text (默认)
  • number
  • checkbox
  • select
    • 需要一个额外属性 "Options" 来提供选项, 是一个使用竖线(|)分隔的字符串

      "Connection.Protocol": {
      "Group1": "Server",
      "Group2": "Connection",
      "Type": "select",
      "Options": "|HTTP|TCP|RDP|FTP|SFTP"
      }

      渲染结果:

到这里教程就结束了. 通过本教程, 你应该可以轻松地使用SettingUi来管理你的设置了. 教程的源码可以在sample文件夹中找到.

本地化

SettingUi模块使用ABP的本地化系统来显示设置的本地化信息. 现在支持的语言有:

  • 英语
  • 简体中文
  • 土耳其语

本地化资源存放在EasyAbp.Abp.SettingUi.Domain.Shared项目的/Localization/SettingUi中.

你可以添加更多的资源文件来让这个模块支持更多语言. 欢迎PR .

ABP的本地化系统, 请查看文档

权限

SettingUi通过检查SettingUi.ShowSettingPage权限,来控制是否显示SettingUi的页面.

只要赋予了该权限, 那么系统中所有的设置都可以通过SettingUi来修改.

但有些时候, 我们不想让用户在SettingUi中看到某些设置, 这可以通过定义特定的权限来实现这个目的.

比如我们需要对用户隐藏"系统"分组, 那么需要在SettingUi.ShowSettingPage下添加一个子权限, 权限的名字为SettingUi.System. 代码如下:

public override void Define(IPermissionDefinitionContext context)
{
var settingUiPage = context.GetPermissionOrNull(SettingUiPermissions.ShowSettingPage); // 取得ShowSettingPage权限
var systemGroup = settingUiPage.AddChild("SettingUi.System", L("Permission:SettingUi.System")); // 添加控制 Group1: System 的权限
}

这样当SettingUi遍历设置时, 如果发现有SettingUi.Group1形式的权限, 则只有显式的赋予该权限后, 分组Group1才会显示.

我们可以继续添加对Group2控制的权限, 如"系统" -> "密码"分组, 需要继续添加后缀为Group2的权限, 代码如下:

public override void Define(IPermissionDefinitionContext context)
{
...
var passwordGroup = systemGroup.AddChild("SettingUi.System.Password", L("Permission:SettingUi.System.Password")); // 添加控制 Group2: Password 的权限
}

这样当SettingUi遍历设置时, 如果发现有SettingUi.Group1.Group2形式的权限, 则只有显示的赋予该权限后, 分组Group1中的Group2才会显示.

当然, 我们也可继续添加精确控制某一设置的权限, 如"系统" -> "密码" -> "要求长度", 需要继续添加后缀为设置名称的权限, 代码如下:

public override void Define(IPermissionDefinitionContext context)
{
...
var requiredLength = passwordGroup.AddChild("SettingUi.System.Password.Abp.Identity.Password.RequiredLength", L("Permission:SettingUi.System.Password.RequiredLength")); // 添加控制设置Abp.Identity.Password.RequiredLength的权限
}

这样当SettingUi遍历设置时, 如果发现有SettingUi.Group1.Group2.SettingName形式的权限, 则只有显示的赋予该权限后, 分组Group1中的Group2中的SettingName才会显示.

通过以上3级的权限定义方式, 我们就可以在SettingUi中任意控制设置的显示了.

下图是Setting Ui权限的截图, 和显示的结果:

关于ABP中权限系统, 请查看该文档

ABP设置管理模块: Abp.SettingUi的更多相关文章

  1. ABP(现代ASP.NET样板开发框架)系列之9、ABP设置管理

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之9.ABP设置管理 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)” ...

  2. 初识ABP vNext(10):ABP设置管理

    Tips:本篇已加入系列文章阅读目录,可点击查看更多相关文章. 目录 前言 开始 定义设置 使用设置 最后 前言 上一篇介绍了ABP模块化开发的基本步骤,完成了一个简单的文件上传功能.通常的模块都有一 ...

  3. ABP module-zero +AdminLTE+Bootstrap Table+jQuery权限管理系统第十三节--RBAC模式及ABP权限管理(附送福利)

    ABP+AdminLTE+Bootstrap Table权限管理系统一期 Github:https://github.com/Jimmey-Jiang/ABP-ASP.NET-Boilerplate- ...

  4. ABP框架 - 设置管理

    文档目录 本节内容: 简介 关于ISettingStore 定义设置 setting scope(设置范围) 重写设置定义 获取设置值 服务端 客户端 修改设置 关于缓存 简介 每个应用必需存储一些设 ...

  5. ABP理论学习之设置管理

    返回总目录 本篇目录 介绍 定义设置 获取设置值 更改设置 关于缓存 介绍 每个应用程序都需要存储一些设置信息,然后在应用程序中的某个地方使用这些设置.ABP提供了健壮的基础设施来存储或检索服务端和客 ...

  6. ABP官方文档翻译 2.5 设置管理

    设置管理 介绍 关于 ISettingStore 定义设置 设置范围 重写设置定义 获取设置值 服务端 客户端 更改设置 关于缓存 介绍 每个应用都需要存储设置,并且在应用的某些地方需要使用这些设置. ...

  7. X-Admin&ABP框架开发-设置管理

    在网站开发中,设置是不可缺少的一环,如用户设置.系统设置.甚至是租户设置等.ABP对于设置的管理已经做了很好的处理,我们可以借助巨人的力量来完成我们的冒险. ABP官网地址:https://aspne ...

  8. ABP开发框架前后端开发系列---(6)ABP基础接口处理和省份城市行政区管理模块的开发

    最近没有更新ABP框架的相关文章,一直在研究和封装相关的接口,总算告一段落,开始继续整理下开发心得.上次我在随笔<ABP开发框架前后端开发系列---(5)Web API调用类在Winform项目 ...

  9. 初识ABP vNext(8):ABP特征管理

    Tips:本篇已加入系列文章阅读目录,可点击查看更多相关文章. 目录 前言 开始 定义特征 应用特征 用户数量 社交登录 最后 前言 上一篇提到了ABP功能管理(特征管理),它来自ABP的Featur ...

随机推荐

  1. 【Java】运算符(算术、赋值、比较(关系)、逻辑、条件、位运算符)

    运算符 文章目录 运算符 1. 算术运算符 2. 赋值运算符 3. 比较运算符 4. 逻辑运算符 5. 条件运算符 6. 位运算符 7. 运算符优先级 8. 运算符操作数类型说明 9.code 算术运 ...

  2. zabbix自动发现主机并注册

  3. 不要把file,process或者super权限授予管理员以外的账号

    file权限的主要作用是通过select ....into outfile 写到服务器上具有写权限的目录下,作为文本格式存放,具有权限的目录也就是启动mysql时的用户权限目录.(没有理解) 可以将有 ...

  4. 【MySQL】Last_SQL_Errno: 1594Relay log read failure: Could not parse relay log event entry...问题总结处理

    备库报错: Last_SQL_Errno: 1594 Last_SQL_Error: Relay log read failure: Could not parse relay log event e ...

  5. SAP中用户口令状态的一点说明

    数据元素:XUPWDSTATE 数值      内涵 -2(通常)不能更改口令.-1(每天只允许一次)今天不能更改口令.0可以更改口令,但没有必要更改.1口令为初始值必须更改口令.2口令过期必须更改口 ...

  6. 响应式编程库RxJava初探

    引子 在读 Hystrix 源码时,发现一些奇特的写法.稍作搜索,知道使用了最新流行的响应式编程库RxJava.那么响应式编程究竟是怎样的呢? 本文对响应式编程及 RxJava 库作一个初步的探索. ...

  7. UI测试框架

    1. 从上到下共分成4层: 用例层  组件管理层  元素管理层  公共数据层 2. 用例层: 将每条用例使用参数化, 公共参数存储到"公共数据层", 中间参数通过组件层传递 3. ...

  8. 基于Redo Log和Undo Log的MySQL崩溃恢复流程

    在之前的文章「简单了解InnoDB底层原理」聊了一下MySQL的Buffer Pool.这里再简单提一嘴,Buffer Pool是MySQL内存结构中十分核心的一个组成,你可以先把它想象成一个黑盒子. ...

  9. Mysql数据库下InnoDB数据引擎下的事务详解

    一.什么是数据库事务? 数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位.事务由事务开始与事务结束之 ...

  10. postgres多知识点综合案例

    使用到的知识点: 1.使用with临时存储sql语句,格式[with as xxx(), as xxx2() ]以减少代码: 2.使用round()取小数点后几位: 3.使用to_char()将时间格 ...