Browse Source

docs: 文档整理

pull/89/head
王军 4 years ago
parent
commit
5c93b3765d
  1. 126
      docs/content/user-guide/zh/extension/统一返回值格式.md
  2. 3
      docs/content/user-guide/zh/getting-started/quick-start.md
  3. 35
      docs/content/user-guide/zh/infrastructure/frontend.md
  4. 46
      docs/content/user-guide/zh/modules/setting.md

126
docs/content/user-guide/zh/extension/统一返回值格式.md

@ -59,117 +59,35 @@ public class WrapResultAttribute : Attribute
}
```
- 实现 IAsyncExceptionFilter(拦截异常,抛异常时指定返回格式)
- 添加异常过滤器(拦截异常,抛异常时指定返回格式)
```csharp
public sealed class ResultExceptionFilter : IAsyncExceptionFilter, ITransientDependency
{
public async Task OnExceptionAsync(ExceptionContext context)
{
if (!ShouldHandleException(context))
{
return;
}
await HandleAndWrapException(context);
}
private bool ShouldHandleException(ExceptionContext context)
{
if (context.ActionDescriptor.AsControllerActionDescriptor().ControllerTypeInfo.GetCustomAttributes(typeof(WrapResultAttribute), true).Any())
{
return true;
}
if (context.ActionDescriptor.GetMethodInfo().GetCustomAttributes(typeof(WrapResultAttribute), true).Any())
{
return true;
}
return false;
}
private async Task HandleAndWrapException(ExceptionContext context)
{
var exceptionHandlingOptions = context.GetRequiredService<IOptions<AbpExceptionHandlingOptions>>().Value;
var exceptionToErrorInfoConverter = context.GetRequiredService<IExceptionToErrorInfoConverter>();
var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(context.Exception, options =>
{
options.SendExceptionsDetailsToClients = exceptionHandlingOptions.SendExceptionsDetailsToClients;
options.SendStackTraceToClients = exceptionHandlingOptions.SendStackTraceToClients;
});
- [LionExceptionFilter](https://github.com/WangJunZzz/abp-vnext-pro/blob/main/aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Microsoft/AspNetCore/Mvc/Filters/LionExceptionFilter.cs)
var logLevel = context.Exception.GetLogLevel();
- 添加结果过滤器
- [LionResultFilter](https://github.com/WangJunZzz/abp-vnext-pro/blob/main/aspnet-core/shared/Lion.AbpPro.Shared.Hosting.Microservices/Microsoft/AspNetCore/Mvc/Filters/LionResultFilter.cs)
var remoteServiceErrorInfoBuilder = new StringBuilder();
remoteServiceErrorInfoBuilder.AppendLine($"---------- {nameof(RemoteServiceErrorInfo)} ----------");
remoteServiceErrorInfoBuilder.AppendLine(context.GetRequiredService<IJsonSerializer>().Serialize(remoteServiceErrorInfo, indented: true));
var logger = context.GetService<ILogger<ResultExceptionFilter>>(NullLogger<ResultExceptionFilter>.Instance);
logger.LogWithLevel(logLevel, remoteServiceErrorInfoBuilder.ToString());
logger.LogException(context.Exception, logLevel);
await context.GetRequiredService<IExceptionNotifier>().NotifyAsync(new ExceptionNotificationContext(context.Exception));
context.HttpContext.Response.StatusCode = 200;
var result = SimplifyMessage(context);
context.Result = new ObjectResult(result);
context.Exception = null; //Handled!
}
## 注册 Filter
private WrapResult<object> SimplifyMessage(ExceptionContext context)
{
var result = new WrapResult<object>();
var localizer = context.GetService<IStringLocalizer<AbpProResource>>();
switch (context.Exception)
```csharp
/// <summary>
/// 异常处理
/// </summary>
private void ConfigureAbpExceptions(ServiceConfigurationContext context)
{
context.Services.AddMvc
(
options =>
{
case AbpAuthorizationException:
result.SetFail("权限不足", 401);
break;
case AbpValidationException:
result.SetFail("请求参数验证失败", 400);
break;
case EntityNotFoundException:
result.SetFail("实体不存在", 506);
break;
case NotImplementedException:
result.SetFail("未实现功能", 507);
break;
default:
{
if (context.Exception is IHasErrorCode codeException)
{
result.SetFail(localizer[codeException.Code]);
foreach (var key in context.Exception.Data.Keys)
{
result.SetFail(result.Message.Replace("{" + key + "}", context.Exception.Data[key]?.ToString()));
}
}
else
{
result.SetFail(context.Exception.Message);
}
break;
}
options.Filters.Add(typeof(LionExceptionFilter));
options.Filters.Add(typeof(LionResultFilter));
}
return result;
}
);
}
```
## 注册 Filter
```csharp
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddMvc(options =>
{
options.Filters.Add(typeof(ResultExceptionFilter));
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
ConfigureAbpExceptions(context);
}
```
## 使用
@ -199,3 +117,5 @@ public sealed class ResultExceptionFilter : IAsyncExceptionFilter, ITransientDep
}
```
- 不管接口时有异常还是成功返回结果都是 WrapResult,PermissionOutput 在 WrapResult.Data 中。

3
docs/content/user-guide/zh/getting-started/quick-start.md

@ -66,7 +66,6 @@ lion.abp new abp-vnext-pro-basic-no-ocelot -c 公司名称 -p 项目名称 -v
- Redis 连接字符串
- RabbitMq(如果不需要启用设置为 false)
- Es 地址即可(如果没有 es 也可以运行,只是前端 es 日志页面无法使用而已,不影响后端项目启动)
- 修改 IdentityServer-> appsettings.json 数据库连接字符串
- 修改 DbMigrator-> appsettings.json 数据库连接字符串
- 右键单击.DbMigrator 项目,设置为启动项目运行,按 F5(或 Ctrl + F5) 运行应用程序. 它将具有如下所示的输出:
![](../../../img/migrating.png)
@ -95,5 +94,5 @@ pnpm install
### 启动项目
```bash
npm run dev
pnpm run dev
```

35
docs/content/user-guide/zh/infrastructure/frontend.md

@ -1,14 +1,14 @@
# 前端
[Vben Admin 文档](https://vvbin.cn/doc-next/)
[Vben Admin 文档](https://vvbin.cn/doc-next/)
## 代码生成
!!! info "前端接口,参数,自动生成,全部采用 Post 方式"
- 所有访问后端接口代码自动生成 [NSwag](https://github.com/RicoSuter/NSwag)
!!! info "前端接口,参数,自动生成,全部采用 Post 方式"
- 所有访问后端接口代码自动生成 [NSwag](https://github.com/RicoSuter/NSwag)
### 配置代理的地址
### 配置代理的地址
- nswag->nswag.json
@ -16,7 +16,7 @@
"documentGenerator": {
"fromDocument": {
// 代理地址,只有生成的时候用,不区分环境
"url": "http://localhost:44315/swagger/v1/swagger.json",
"url": "http://localhost:44315/swagger/v1/swagger.json",
}
}
```
@ -27,7 +27,7 @@
npm run nswag
```
### 后端Api格式
### 后端 Api 格式
```csharp
// 一定要打Tags,因为前端会根据这个生成代理类
@ -40,9 +40,10 @@ public Task<LoginOutput> LoginAsync(LoginInput input)
```
## 前端多环境
- .env.development 和.env.production
- VITE_API_URL:后端接口地址
- VITE_AUTH_URL:IdentityServer接口地址
- .env.development 和.env.production
- VITE_API_URL:后端接口地址
- VITE_WEBSOCKE_URL: WEBSOCKE 地址
## 权限配置
@ -102,15 +103,25 @@ export default tenant;
},
{
auth: 'System.Users.Enable', // 按钮权限
label: !record.isActive ? t('common.enabled') : t('common.disEnabled'),
label: !record.isActive
? t('common.enabled')
: t('common.disEnabled'),
onClick: handleLock.bind(null, record),
},
]"
/>
</template>
</BasicTable>
<CreateAbpUser @register="registerCreateAbpUserModal" @reload="reload" :bodyStyle="{ 'padding-top': '0' }" />
<EditAbpUser @register="registerEditAbpUserModal" @reload="reload" :bodyStyle="{ 'padding-top': '0' }" />
<CreateAbpUser
@register="registerCreateAbpUserModal"
@reload="reload"
:bodyStyle="{ 'padding-top': '0' }"
/>
<EditAbpUser
@register="registerEditAbpUserModal"
@reload="reload"
:bodyStyle="{ 'padding-top': '0' }"
/>
</div>
</template>
```

46
docs/content/user-guide/zh/modules/setting.md

@ -1,14 +1,15 @@
# 设置管理
[官方Setting模块参考文档](https://docs.abp.io/zh-Hans/abp/latest/Settings)
[官方 Setting 模块参考文档](https://docs.abp.io/zh-Hans/abp/latest/Settings)
配置系统是在启动时配置应用程序很好的方式. 除了配置之外, ABP提供了另外一种设置和获取应用程序设置的方式.
配置系统是在启动时配置应用程序很好的方式. 除了配置之外, ABP 提供了另外一种设置和获取应用程序设置的方式.
设置存储在动态数据源(通常是数据库)中的键值对. 设置系统预构建了用户,租户,全局和默认设置方法并且可以进行扩展.
## 定义设置
使用设置之前需要定义它. ABP是 模块化的, 不同的模块可以拥有不同的设置. 只需要实现SettingDefinitionProvider类既可. 示例如下:
!!! info "和官方Setting模块区别,值添加了2个属性,一个分组,一个组件类型"
使用设置之前需要定义它. ABP 是 模块化的, 不同的模块可以拥有不同的设置. 只需要实现 SettingDefinitionProvider 类既可. 示例如下:
!!! info "和官方 Setting 模块区别,值添加了 2 个属性,一个分组,一个组件类型"
```csharp
public class CustomSettingProvider : SettingDefinitionProvider
@ -23,24 +24,27 @@ public class CustomSettingProvider : SettingDefinitionProvider
L("Description:" + AbpProSettings.Other.Github)
)
// 分组
.WithProperty(AbpProSettings.Group.Default,AbpProSettings.Group.OtherManagement)
.WithProperty(AbpProSettings.Group.Default,AbpProSettings.Group.OtherManagement)
// 前端组件类型
.WithProperty(AbpProSettings.ControlType.Default,AbpProSettings.ControlType.TypeText));
.WithProperty(AbpProSettings.ControlType.Default,AbpProSettings.ControlType.TypeText));
}
}
```
- SettingDefinition 类具有以下属性:
- Name: 应用程序中设置的唯一名称. 是具有约束的唯一属性, 在应用程序获取/设置此设置的值 (设置名称定义为常量而不是魔法字符串是个好主意).
- DefaultValue: 设置的默认值.
- DisplayName: 本地化的字符串,用于在UI上显示名称.
- Description: 本地化的字符串,用于在UI上显示描述.
- 上面添加了2个属性,为了适配vue前端,一个设置Setting属于哪个分组,一个是根据Setting的类型指定对应的前端组件,比如字符串就是,Input组件。
- 支持以下组件:Text,CheckBox,Number
- Name: 应用程序中设置的唯一名称. 是具有约束的唯一属性, 在应用程序获取/设置此设置的值 (设置名称定义为常量而不是魔法字符串是个好主意).
- DefaultValue: 设置的默认值.
- DisplayName: 本地化的字符串,用于在 UI 上显示名称.
- Description: 本地化的字符串,用于在 UI 上显示描述.
- 上面添加了 2 个属性,为了适配 vue 前端,一个设置 Setting 属于哪个分组,一个是根据 Setting 的类型指定对应的前端组件,比如字符串就是,Input 组件。
- 支持以下组件:Text,CheckBox,Number
## 读取设置值
ISettingProvider 用于获取指定设置的值或所有设置的值. 示例用法:
```csharp
public class MyService
{
@ -75,16 +79,14 @@ public class MyService
}
}
```
> ISettingProvider 是非常常用的服务,一些基类中(如IApplicationService)已经将其属性注入. 这种情况下可以直接使用SettingProvider.
ISettingProvider 使用设置值提供程序来获取设置值. 如果值提供程序无法获取设置值,则会回退到下一个值提供程序.
DefaultValueSettingValueProvider: 从设置定义的默认值中获取值.
ConfigurationSettingValueProvider: 从IConfiguration服务中获取值.
GlobalSettingValueProvider: 获取设置的全局值.
TenantSettingValueProvider: 获取当前租户的设置值.
UserSettingValueProvider: 获取当前用户的设置值.
> 设置回退系统从底部 (用户) 到 顶部(默认) 方向起作用.
> ISettingProvider 是非常常用的服务,一些基类中(如 IApplicationService)已经将其属性注入. 这种情况下可以直接使用 SettingProvider.
- ISettingProvider 使用设置值提供程序来获取设置值. 如果值提供程序无法获取设置值,则会回退到下一个值提供程序.
- DefaultValueSettingValueProvider: 从设置定义的默认值中获取值.
- ConfigurationSettingValueProvider: 从 IConfiguration 服务中获取值.
- GlobalSettingValueProvider: 获取设置的全局值.
- TenantSettingValueProvider: 获取当前租户的设置值.
- UserSettingValueProvider: 获取当前用户的设置值.
> 设置回退系统从底部 (用户) 到 顶部(默认) 方向起作用.

Loading…
Cancel
Save