feat: 添加 .net10 配置和项目文件

main
zangch@mesnac.com 2 weeks ago
parent 788f075fa9
commit 6d8d0cc5fb

@ -0,0 +1,144 @@
# Repository Guidelines
## Backend Reading Context
Before reading or changing backend code under `Admin.NET/`, read the root document `BACKEND_INFRA_CONTEXT.md` first. It summarizes the project's common backend wrappers, infrastructure entry points, SqlSugar/Furion adaptation layers, and the recommended lookup order for cache, tenant, auth, data access, scheduling, and plugin integrations.
## Project Structure & Module Organization
`Admin.NET/` contains the backend solution `Admin.NET.sln`. Core business and infrastructure live in `Admin.NET.Core/`, example application services in `Admin.NET.Application/`, host bootstrapping in `Admin.NET.Web.Core/` and `Admin.NET.Web.Entry/`, automated tests in `Admin.NET.Test/`, and optional integrations in `Admin.NET/Plugins/`. `Web/` is the Vue 3 + Vite frontend; main code is under `Web/src/`, static files under `Web/public/`, localization under `Web/lang/`, and API generation scripts under `Web/api_build/`. Deployment and reference material live in `docker/` and `doc/`.
## Build, Test, and Development Commands
- `dotnet restore Admin.NET/Admin.NET.sln` restores backend dependencies.
- `dotnet build Admin.NET/Admin.NET.sln -c Debug` builds all backend projects and plugins.
- `dotnet run --project Admin.NET/Admin.NET.Web.Entry` starts the backend entry host locally.
- `dotnet test Admin.NET/Admin.NET.Test/Admin.NET.Test.csproj` runs xUnit/Furion tests.
- `pnpm install --dir Web` installs frontend dependencies. Use Node `>=18`.
- `pnpm --dir Web dev` starts the Vite dev server.
- `pnpm --dir Web build` creates the production frontend bundle.
- `pnpm --dir Web lint-fix` runs ESLint autofixes; `pnpm --dir Web format` applies Prettier.
## Coding Style & Naming Conventions
Backend style is defined by `Admin.NET/.editorconfig`: 4-space indentation, CRLF line endings, file-scoped namespaces, braces enabled, explicit types preferred over `var`, PascalCase for types and members, and `I` prefixes for interfaces. Frontend formatting is defined in `Web/.prettierrc.cjs`: tabs with width 2, LF line endings, single quotes, semicolons, and trailing commas where valid. Keep feature folders stable and follow existing descriptive names in `Web/src/views/` and `Web/src/api-services/`.
## Testing Guidelines
Backend tests live in `Admin.NET/Admin.NET.Test/` and currently use `Furion.Xunit`, `Microsoft.NET.Test.Sdk`, and xUnit assertions. Add tests near the relevant feature area and prefer names like `DateTimeUtilTests.cs` or `UserTest.cs`, matching the current convention. Frontend automated tests are not present in this workspace; for UI changes, run `pnpm --dir Web dev`, verify critical pages manually, and include lint/format results with the change.
## Commit & Pull Request Guidelines
This workspace does not include `.git` metadata, so local history could not be inspected. Use concise, imperative commit messages and prefer a conventional format such as `feat(web): add tenant switcher` or `fix(core): guard null claim`. PRs should describe scope, affected modules, configuration changes, validation steps, and include screenshots for `Web/` UI updates.
## Security & Configuration Tips
Do not hardcode connection strings, tokens, tenant rules, or approval logic. Keep environment-specific values in configuration files or deployment variables, and prefer extending dictionaries, seed data, or plugin modules over editing shared core behavior directly.
---
## A. 技术栈总览
- 运行时:后端核心项目均为 `net8.0;net10.0` 双目标(`Admin.NET.Web.Entry`、`Admin.NET.Web.Core`、`Admin.NET.Application`、`Admin.NET.Core`)。
- 基础框架:以 Furion 为主干,使用 `AppStartup` 装配、`IDynamicApiController` 动态 API、统一返回、JWT、事件总线、任务调度、远程请求等能力。
- 数据访问:`Startup.AddSqlSugar()` 统一接入,`SqlSugarSetup` 负责全局初始化/AOP/过滤器/种子,`SqlSugarRepository<T>` 负责仓储访问与租户切库,`SqlSugarUnitOfWork` 适配工作单元。
- 架构形态:分层结构 + 插件模块化。`Web.Entry` 宿主,`Web.Core` 启动装配,`Application` 应用接口,`Core` 实体与基础设施,`Plugins` 扩展模块。
- 能力归属确认:
- 缓存:`CacheSetup` + `SysCacheService` + `SqlSugarCache`
- 鉴权:`AddJwt<JwtHandler>` + `SignatureAuthenticationHandler` + `SysAuthService`/`SysOpenAccessService`
- 事件总线:`AddEventBus` + `RetryEventHandlerExecutor` + `RedisEventSourceStorer` + `AppEventSubscriber`
- 任务调度:`AddSchedule` + `UseScheduleUI` + `DynamicJobCompiler` + `SysScheduleService`
- 多租户:`SysTenantService` + `SqlSugarRepository<T>` + `SqlSugarSetup` 查询过滤器
- 前端现状README 文案仍写 `Vue3 + Element Plus + Vite5`,但 `Web/package.json` 实际依赖为 `vue ^3.5.28`、`element-plus ^2.13.2`、`vite ^7.3.1`(以代码配置为准)。
## B. 关键依据文件
1. `Admin.NET/Admin.NET.sln`(解决方案与插件挂载结构)
2. `Admin.NET/Admin.NET.Web.Entry/Program.cs`(应用启动入口)
3. `Admin.NET/Admin.NET.Web.Core/Startup.cs`(核心服务注册与中间件链)
4. `Admin.NET/Admin.NET.Web.Core/ProjectOptions.cs`(配置绑定)
5. `Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj`Furion/SqlSugar 等核心依赖)
6. `Admin.NET/Admin.NET.Web.Entry/Admin.NET.Web.Entry.csproj`.NET 目标框架确认)
7. `Admin.NET/Admin.NET.Web.Core/Admin.NET.Web.Core.csproj`
8. `Admin.NET/Admin.NET.Application/Admin.NET.Application.csproj`(应用层与插件引用)
9. `Admin.NET/Admin.NET.Core/SqlSugar/SqlSugarSetup.cs`SqlSugar 接入主入口)
10. `Admin.NET/Admin.NET.Core/SqlSugar/SqlSugarRepository.cs`(仓储与租户切库)
11. `Admin.NET/Admin.NET.Core/Cache/CacheSetup.cs`、`Admin.NET/Admin.NET.Core/Service/Cache/SysCacheService.cs`、`Admin.NET/Admin.NET.Core/Cache/SqlSugarCache.cs`
12. `Admin.NET/Admin.NET.Web.Core/Handlers/JwtHandler.cs`、`Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs`
13. `Admin.NET/Admin.NET.Core/SignatureAuth/SignatureAuthenticationHandler.cs`、`Admin.NET/Admin.NET.Core/Service/OpenAccess/SysOpenAccessService.cs`
14. `Admin.NET/Admin.NET.Core/Service/Tenant/SysTenantService.cs`
15. `Admin.NET/Admin.NET.Core/EventBus/AppEventSubscriber.cs`、`Admin.NET/Admin.NET.Core/EventBus/RetryEventHandlerExecutor.cs`、`Admin.NET/Admin.NET.Core/EventBus/RedisEventSourceStorer.cs`
16. `Admin.NET/Admin.NET.Core/Job/DynamicJobCompiler.cs`、`Admin.NET/Admin.NET.Core/Service/Schedule/SysScheduleService.cs`
17. `Admin.NET/Admin.NET.Application/OpenApi/DemoOpenApi.cs`(动态 API 与签名鉴权示例)
18. `Admin.NET/Admin.NET.Core/Service/Plugin/SysPluginService.cs`(动态插件热加载)
19. `Admin.NET/Plugins/*/Startup.cs`(插件装配入口)
20. `README.md` + `Web/package.json`(前端栈声明与实际依赖对照)
## C. 后端模块结构树
- `Admin.NET.sln`
- 启动层:`Admin.NET.Web.Entry`
- 最薄宿主,`Serve.Run` + `WebComponent`日志过滤、Kestrel 限制)
- 启动装配层:`Admin.NET.Web.Core`
- `Startup` 汇总注册中间件与基础能力,`ProjectOptions` 统一绑定配置
- 接口/应用层:`Admin.NET.Application`
- 示例开放接口(`OpenApi/DemoOpenApi.cs`),承接业务服务暴露;默认引用 `Core` 与部分插件
- 实体层:`Admin.NET.Core/Entity`
- 领域实体、表特性、租户/日志/系统表标记
- 基础设施层:`Admin.NET.Core`
- `SqlSugar/`、`Cache/`、`SignatureAuth/`、`EventBus/`、`SignalR/`、`Job/`、`Service/`、`Option/`、`Utils/`、`Extension/`
- 测试层:`Admin.NET.Test`
- 插件模块:`Admin.NET/Plugins/*`
- `ApprovalFlow`、`DingTalk`、`GoView`、`K3Cloud`、`ReZero`、`WorkWeixin`,各自有 `Startup.cs` 与独立 Option/Service/Proxy/Dto按插件而异
- 业务模块注册/加载/扩展方式
- 编译期:通过 `Application.csproj``ProjectReference` 显式引用插件(当前默认引用 `ApprovalFlow`、`DingTalk`、`GoView`)。
- 启动期Furion 扫描 `[AppStartup]``Application`、`Plugins`、`Web.Core`)并执行对应 `ConfigureServices/Configure`
- 运行期:`SysPluginService` 支持编译 C# 动态程序集,并通过 `IDynamicApiRuntimeChangeProvider` 热增删 API。
## D. 核心启动流程
1. 入口阶段:`Program.cs` 调用 `Serve.Run(RunOptions.Default.AddWebComponent<WebComponent>())` 启动应用,并设置日志过滤与 Kestrel 超时/上传限制。
2. Startup 扫描阶段Furion 根据 `[AppStartup]` 扫描并装配 `Application`、`Plugins`、`Web.Core` 的 `Startup`
3. 服务注册阶段(`Web.Core/Startup.ConfigureServices`
- 基础配置:`AddProjectOptions`
- 基础设施:`AddCache`、`AddSqlSugar`
- 鉴权:`AddJwt<JwtHandler>(enableGlobalAuthorize: true)` + `AddSignatureAuthentication`
- 应用能力:`AddCorsAccessor`、`AddHttpRemote`、`AddTaskQueue`、`AddSchedule`、`AddEventBus`
- Web 能力控制器与统一返回、OAuth、ElasticSearch、限流、SignalR、OSS、日志、验证码、虚拟文件系统等
4. 中间件阶段(`Web.Core/Startup.Configure`
- 压缩/转发/异常/静态资源
- `UseOAuth` -> `UseUnifyResultStatusCodes` -> `UseAppLocalization` -> `UseRouting`
- `UseCorsAccessor` -> `UseAuthentication` -> `UseAuthorization`
- 限流、`UseScheduleUI`、Swagger/Scalar 注入、`MapHubs`、MVC 路由
5. 插件扩展阶段:插件 `Startup` 按自身实现追加注册如审批流中间件、DingTalk 声明式远程 API、GoView 返回规范化等)。
## E. 请求处理链路
- 接口暴露方式
- 主体为 `IDynamicApiController` 服务类Furion 自动生成路由。
- 示例:`DemoOpenApi` 通过 `[Authorize(AuthenticationSchemes = SignatureAuthenticationDefaults.AuthenticationScheme)]` 走签名鉴权。
- 鉴权链路
- 全局 JWT`AddJwt<JwtHandler>(enableGlobalAuthorize: true)`。
- 开放接口签名:`AddSignatureAuthentication` + `SignatureAuthenticationHandler` + `SysOpenAccessService.GetSignatureAuthenticationEventImpl()`
- 中间件顺序:`UseCorsAccessor` 之后进入 `UseAuthentication``UseAuthorization`
- 统一返回链路
- `AddInjectWithUnifyResult<AdminResultProvider>()` 统一成功/异常响应。
- 数据访问链路
- API/动态控制器 -> 业务 Service -> `SqlSugarRepository<T>` -> `SqlSugarScope` -> DB。
- `SqlSugarRepository<T>` 在构造时根据实体特性(系统表/日志表/租户表)+ 请求头 TenantId + 用户 Claim TenantId 决定连接。
- `SqlSugarSetup.SetDbAop()` 统一注入软删过滤、租户过滤、数据权限过滤、审计字段与慢 SQL/错误 SQL 记录。
- 多租户介入阶段
- 请求进入仓储前:仓储构造函数根据 Header/Claim 切租户库。
- 查询执行前SqlSugar 全局过滤器按租户与数据权限过滤。
- 租户库维护:`SysTenantService.GetTenantDbConnectionScope` + `SqlSugarSetup.InitTenantDatabase`
- 缓存介入阶段
- 启动期:`AddCache` 根据配置选择 Redis未配置则内存兜底。
- 运行期:业务缓存统一经 `SysCacheService`SqlSugar 二级缓存经 `SqlSugarCache` 桥接。
- 鉴权/开放接口也依赖缓存(如黑名单、签名重放 nonce
- 事件与调度介入阶段
- 事件总线:`AddEventBus` 注册执行器、监视器;可替换 `RedisEventSourceStorer`;消费由 `EventConsumer`
- 调度:`AddSchedule` 注册持久化/监控,`UseScheduleUI` 提供运维看板;动态任务编译由 `DynamicJobCompiler`
## F. 插件式模块机制说明
- 插件目录与职责
- `Admin.NET/Plugins` 下每个插件都有独立项目与 `Startup.cs`按功能拆分集成能力审批流、钉钉、可视化大屏、K3Cloud、ReZero、企业微信等
- 插件注册与加载
- 解决方案层面:插件项目挂在 `Admin.NET.sln`
- 应用层面:`Admin.NET.Application.csproj` 当前默认引用 `ApprovalFlow`、`DingTalk`、`GoView`;其它插件可按需追加引用启用。
- 运行层面:插件 `Startup` 使用 `[AppStartup(100)]` 参与全局服务装配。
- 插件扩展模式
- 配置扩展:插件 `Option` + `AddConfigurableOptions<T>()`
- 通讯扩展:声明式远程请求(如 DingTalk `AddHttpRemote().AddHttpDeclarative<...>()`
- 返回规范扩展:插件可注册自身 `UnifyProvider`(如 GoView
- 中间件扩展:插件可在 `Configure` 注入专属中间件(如 ApprovalFlow
- 动态插件(运行时热扩展)
- `SysPluginService` 支持把 C# 代码编译为程序集,并通过 `IDynamicApiRuntimeChangeProvider` 进行 API 热添加/热移除。
- 该机制使“插件化扩展”同时支持静态项目插件和动态代码插件两条路径。

@ -0,0 +1,25 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md

@ -0,0 +1,177 @@
[*.cs]
#### 命名样式 ####
# 命名规则
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
# 符号规范
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =
# 命名样式
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
csharp_using_directive_placement = outside_namespace:silent
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = true:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_accessors = true:silent
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = false:silent
csharp_style_conditional_delegate_call = true:suggestion
csharp_style_var_for_built_in_types = false:silent
csharp_style_var_when_type_is_apparent = false:silent
csharp_style_var_elsewhere = false:silent
csharp_prefer_simple_using_statement = true:suggestion
csharp_prefer_braces = true:silent
csharp_style_namespace_declarations = file_scoped:silent
csharp_style_prefer_top_level_statements = true:silent
csharp_style_prefer_method_group_conversion = true:silent
csharp_prefer_static_local_function = true:suggestion
csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true:silent
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent
csharp_style_prefer_switch_expression = true:suggestion
csharp_style_prefer_pattern_matching = true:silent
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_prefer_not_pattern = true:suggestion
csharp_style_prefer_extended_property_pattern = true:suggestion
csharp_style_throw_expression = true:suggestion
csharp_style_prefer_null_check_over_type_check = true:suggestion
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_prefer_local_over_anonymous_function = true:suggestion
csharp_style_prefer_index_operator = true:suggestion
csharp_style_prefer_range_operator = true:suggestion
csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
csharp_style_prefer_tuple_swap = true:suggestion
csharp_style_prefer_utf8_string_literals = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
csharp_space_around_binary_operators = before_and_after
csharp_indent_labels = one_less_than_current
[*.vb]
#### 命名样式 ####
# 命名规则
dotnet_naming_rule.interface_should_be_以_i_开始.severity = suggestion
dotnet_naming_rule.interface_should_be_以_i_开始.symbols = interface
dotnet_naming_rule.interface_should_be_以_i_开始.style = 以_i_开始
dotnet_naming_rule.类型_should_be_帕斯卡拼写法.severity = suggestion
dotnet_naming_rule.类型_should_be_帕斯卡拼写法.symbols = 类型
dotnet_naming_rule.类型_should_be_帕斯卡拼写法.style = 帕斯卡拼写法
dotnet_naming_rule.非字段成员_should_be_帕斯卡拼写法.severity = suggestion
dotnet_naming_rule.非字段成员_should_be_帕斯卡拼写法.symbols = 非字段成员
dotnet_naming_rule.非字段成员_should_be_帕斯卡拼写法.style = 帕斯卡拼写法
# 符号规范
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.类型.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.类型.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected
dotnet_naming_symbols.类型.required_modifiers =
dotnet_naming_symbols.非字段成员.applicable_kinds = property, event, method
dotnet_naming_symbols.非字段成员.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected
dotnet_naming_symbols.非字段成员.required_modifiers =
# 命名样式
dotnet_naming_style.以_i_开始.required_prefix = I
dotnet_naming_style.以_i_开始.required_suffix =
dotnet_naming_style.以_i_开始.word_separator =
dotnet_naming_style.以_i_开始.capitalization = pascal_case
dotnet_naming_style.帕斯卡拼写法.required_prefix =
dotnet_naming_style.帕斯卡拼写法.required_suffix =
dotnet_naming_style.帕斯卡拼写法.word_separator =
dotnet_naming_style.帕斯卡拼写法.capitalization = pascal_case
dotnet_naming_style.帕斯卡拼写法.required_prefix =
dotnet_naming_style.帕斯卡拼写法.required_suffix =
dotnet_naming_style.帕斯卡拼写法.word_separator =
dotnet_naming_style.帕斯卡拼写法.capitalization = pascal_case
[*.{cs,vb}]
end_of_line = crlf
dotnet_style_qualification_for_field = false:silent
dotnet_style_qualification_for_property = false:silent
dotnet_style_qualification_for_method = false:silent
dotnet_style_qualification_for_event = false:silent
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
dotnet_code_quality_unused_parameters = all:suggestion
dotnet_style_readonly_field = true:suggestion
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
dotnet_style_allow_multiple_blank_lines_experimental = true:silent
dotnet_style_allow_statement_immediately_after_block_experimental = true:silent
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_simplified_interpolation = true:suggestion
dotnet_style_namespace_match_folder = true:suggestion
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
dotnet_style_predefined_type_for_member_access = true:silent
indent_size = 4
tab_width = 4
dotnet_style_operator_placement_when_wrapping = beginning_of_line
# Add copyright file header
file_header_template = Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。\n\n本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。\n\n不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动任何基于本项目二次开发而产生的一切法律纠纷和责任我们不承担任何责任

@ -0,0 +1,35 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
<NoWarn>1701;1702;1591;8632</NoWarn>
<DocumentationFile></DocumentationFile>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<Nullable>disable</Nullable>
<Copyright>Admin.NET</Copyright>
<Description>Admin.NET 通用权限开发平台</Description>
</PropertyGroup>
<ItemGroup>
<Content Include="Configuration\**\*">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Include="wwwroot\**\*">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Admin.NET.Core\Admin.NET.Core.csproj" />
<ProjectReference Include="..\Plugins\Admin.NET.Plugin.ApprovalFlow\Admin.NET.Plugin.ApprovalFlow.csproj" />
<ProjectReference Include="..\Plugins\Admin.NET.Plugin.DingTalk\Admin.NET.Plugin.DingTalk.csproj" />
<ProjectReference Include="..\Plugins\Admin.NET.Plugin.GoView\Admin.NET.Plugin.GoView.csproj" />
<ProjectReference Include="..\Plugins\Admin.NET.Plugin.HwPortal\Admin.NET.Plugin.HwPortal.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,34 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"APIJSON": {
"Roles": [
{
"RoleName": "Role1", //
"Select": { //
"Table": [ "*" ], //
"Column": [ "*" ], //
"Filter": []
},
"Insert": { //
"Table": [ "table1", "table2", "table3" ],
"Column": [ "*", "*", "tb.*" ]
},
"Update": { //
"Table": [ "table1", "table2", "table3" ],
"Column": [ "*", "tb.*", "tb.*" ]
},
"Delete": { //
"Table": [ "table1", "table2", "table3" ]
}
},
{
"RoleName": "Role2",
"Select": {
"Table": [ "table1" ],
"Column": [ "tb.*" ]
}
}
]
}
}

@ -0,0 +1,34 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
// https://openhome.alipay.com/develop/sandbox/app
"Alipay": {
"ServerUrl": "https://openapi-sandbox.dl.alipaydev.com/gateway.do", //
"WebsocketUrl": "openchannel-sandbox.dl.alipaydev.com", // websocket
//"AuthUrl": "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm", //
"AuthUrl": "https://openauth-sandbox.dl.alipaydev.com/oauth2/publicAppAuthorize.htm", //
"AppAuthUrl": "http://xxxxxxxxxx", //
"NotifyUrl": "http://xxxxxxxxx/api/sysAlipay/Notify", //
"RootCertPath": "AlipayCrt/alipayRootCert.crt", //
"AccountList": [
{
"Name": "sandbox 默认应用",
"AppId": "xxxxxxxxxxxxxx",
"SignType": "RSA2",
"PrivateKey": "xxxxxxxxxxxxxxxxx",
"EncryptKey": "xxxxxxxxxxxxxxxxxxxx",
"AppCertPath": "AlipayCrt/appPublicCert.crt", //
"AlipayPublicCertPath": "AlipayCrt/alipayPublicCert.crt" //
},
{
"Name": "sandbox 默认应用2",
"AppId": "xxxxxxxxxxxxxx",
"SignType": "RSA2",
"PrivateKey": "xxxxxxxxxxxxxxxxx",
"EncryptKey": "xxxxxxxxxxxxxxxxxxxx",
"AppCertPath": "AlipayCrt/appPublicCert.crt", //
"AlipayPublicCertPath": "AlipayCrt/alipayPublicCert.crt" //
}
]
}
}

@ -0,0 +1,65 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"Urls": "http://*:5005", //
"AllowedHosts": "*", //
"AppSettings": {
"InjectSpecificationDocument": true, // Swagger
"ExternalAssemblies": [ "plugins" ], //
"VirtualPath": "" //
},
"DynamicApiControllerSettings": {
//"DefaultRoutePrefix": "api", //
"CamelCaseSeparator": "", //
"SplitCamelCase": false, // ()/
"LowercaseRoute": false, //
"AsLowerCamelCase": true, //
"KeepVerb": false, //
"KeepName": false //
},
"FriendlyExceptionSettings": {
"DefaultErrorMessage": "系统异常,请联系管理员",
"ThrowBah": true, // Oops.Oh
"LogError": false //
},
// (访)".*": "application/octet-stream"访
"StaticContentTypeMappings": {
".dll": "application/octet-stream",
".exe": "application/octet-stream",
".pdb": "application/octet-stream",
".so": "application/octet-stream"
},
"LocalizationSettings": {
"SupportedCultures": [ "zh-CN", "en" ], //
"DefaultCulture": "zh-CN", //
"DateTimeFormatCulture": "zh-CN" //
},
"CorsAccessorSettings": {
//"PolicyName": "App.Cors.Policy", //
//"WithOrigins": [ "http://localhost:5005", "https://gitee.com" ], //
"WithExposedHeaders": [ "Content-Disposition", "X-Pagination", "access-token", "x-access-token", "Access-Control-Expose-Headersx-access-token" ], // axios
"SignalRSupport": true // SignalR
},
// /
"JobSchedule": {
"Enabled": true //
},
// Id
"SnowId": {
"WorkerId": 1, // Id
"WorkerIdBitLength": 6, // 6 [1, 19]
"SeqBitLength": 6, // 6 [3, 21]4Id
"WorkerPrefix": "adminnet_" //
},
//
"Cryptogram": {
"StrongPassword": false, //
"PasswordStrengthValidation": "(?=^.{6,16}$)(?=.*\\d)(?=.*\\W+)(?=.*[A-Z])(?=.*[a-z])(?!.*\\n).*$", // 6-16
"PasswordStrengthValidationMsg": "密码必须包含大小写字母、数字和特殊字符的组合长度在6-16之间", //
"CryptoType": "SM2", // MD5SM2SM4
// (http://localhost:5005/api/sysCommon/smKeyPair)VITE_SM_PUBLIC_KEY
"PublicKey": "0484C7466D950E120E5ECE5DD85D0C90EAA85081A3A2BD7C57AE6DC822EFCCBD66620C67B0103FC8DD280E36C3B282977B722AAEC3C56518EDCEBAFB72C5A05312", //
"PrivateKey": "8EDB615B1D48B8BE188FC0F18EC08A41DF50EA731FA28BF409E6552809E3A111" //
}
}

@ -0,0 +1,20 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"CDConfig": {
"Enabled": true, //
"Owner": "zuohuaijun", // gitee
"Repo": "Admin.NET", //
"Branch": "v2", //
"AccessToken": "xxxxxxxxxxxxxxxxxxxxxxxxx", // gitee
"UpdateInterval": 0, // ()0
"BackupCount": 10, // 0
"BackendOutput": "D:\\Admin.NET", //
"Publish": { //
"Configuration": "Release", //
"TargetFramework": "net8.0", // .NET
"RuntimeIdentifier": "linux-x64" //
},
"ExcludeFiles": [ "Configuration\\*.json" ] //
}
}

@ -0,0 +1,38 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
//
"Cache": {
"Prefix": "adminnet_", //
"CacheType": "Redis", // MemoryRedis
"Redis": {
"Configuration": "server=1.13.177.47:6379;password=redis@2023;db=5;", // Redis
"Prefix": "adminnet_", // Redis
"MaxMessageSize": "1048576", // 1024 * 1024
"AutoDetect": false // Redis使false
}
},
//
"Cluster": {
"Enabled": false, // Redis
"ServerId": "adminnet", //
"ServerIp": "", // IP
"SignalR": {
"RedisConfiguration": "127.0.0.1:6379,ssl=false,password=,defaultDatabase=5",
"ChannelPrefix": "signalrPrefix_"
},
"DataProtecteKey": "AdminNet:DataProtection-Keys",
"IsSentinel": false, //
"SentinelConfig": {
"DefaultDb": "4",
"EndPoints": [ //
// "10.10.0.124:26380"
],
"MainPrefix": "adminNet:",
"Password": "123456",
"SentinelPassword": "adminNet",
"ServiceName": "adminNet",
"SignalRChannelPrefix": "signalR:"
}
}
}

@ -0,0 +1,29 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
// Lazy.Captcha.Core (https://api.gitee.com/pojianbing/lazy-captcha/)
"CaptchaOptions": {
"CaptchaType": 10, // 01234567891011
"CodeLength": 1, // , CaptchaType , 2
"ExpirySeconds": 60, //
"IgnoreCase": true, //
"StoreageKeyPrefix": "", //
"ImageOption": {
"Animation": true, //
"FontSize": 36, //
"Width": 150, //
"Height": 50, //
"BubbleMinRadius": 5, //
"BubbleMaxRadius": 10, //
"BubbleCount": 3, //
"BubbleThickness": 1.0, // 沿
"InterferenceLineCount": 3, // 线
"FontFamily": "kaiti", // actionj,epilog,fresnel,headache,lexo,prefix,progbot,ransom,robot,scandal,kaiti
"FrameDelay": 300, // ,Animation=true, 300
"BackgroundColor": "#ffffff", // : rgb, rgba, rrggbb, or rrggbbaa format to match web syntax, #fff
"ForegroundColors": "", // BackgroundColor,使
"Quality": 100, // gif
"TextBold": true //
}
}
}

@ -0,0 +1,11 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
// -
"CodeGen": {
"EntityAssemblyNames": [ "Admin.NET.Core", "Admin.NET.Application" ], //
"BaseEntityNames": [ "EntityBaseId", "EntityBase", "EntityBaseDel", "EntityBaseOrg", "EntityBaseOrgDel", "EntityBaseTenant", "EntityBaseTenantDel", "EntityBaseTenantId", "EntityBaseTenantOrg", "EntityBaseTenantOrgDel" ], //
"FrontRootPath": "Web", //
"BackendApplicationNamespaces": [ "Admin.NET.Application", "Admin.NET.Application2" ] //
}
}

@ -0,0 +1,87 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
// SqlSugar PostgreSQL
// https://www.connectionstrings.com/
"DbConnection": {
"EnableConsoleSql": false, // SQL
"ConnectionConfigs": [
{
//"ConfigId": "1300000000001", // -
"DbType": "MySql", // MySqlSqlServerSqliteOraclePostgreSQLDmKdbndpOscarMySqlConnectorAccessOpenGaussQuestDBHGClickHouseGBaseOdbcCustom
"DbNickName": "系统库",
// "ConnectionString": "DataSource=./Admin.NET.db", // Sqlite
//"ConnectionString": "PORT=5432;DATABASE=xxx;HOST=localhost;PASSWORD=xxx;USER ID=xxx", // PostgreSQL
// "ConnectionString": "Server=localhost;Database=xxx;Uid=xxx;Pwd=xxx;SslMode=None;AllowLoadLocalInfile=true;AllowUserVariables=true;", // MySql,
"ConnectionString": "Server=1.13.177.47;Database=hwsaas-cloud;Uid=root;Pwd=Haiwei123456;SslMode=None;AllowLoadLocalInfile=true;AllowUserVariables=true;", // MySql,
//"ConnectionString": "User Id=xxx; Password=xxx; Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=ORCL)))", // Oracle
//"ConnectionString": "Server=localhost;Database=xxx;User Id=xxx;Password=xxx;Encrypt=True;TrustServerCertificate=True;", // SqlServer
//"SlaveConnectionConfigs": [ // /
// {
// "HitRate": 10,
// "ConnectionString": "DataSource=./Admin.NET1.db"
// },
// {
// "HitRate": 10,
// "ConnectionString": "DataSource=./Admin.NET2.db"
// }
//],
"DbSettings": {
"EnableInitDb": true, //
"EnableInitView": true, //
"EnableDiffLog": false, //
"EnableUnderLine": false, // 线
"EnableConnEncrypt": false // SM2
},
"TableSettings": {
"EnableInitTable": true, //
"EnableIncreTable": false // [IncreTable]
},
"SeedSettings": {
"EnableInitSeed": true, //
"EnableIncreSeed": false // [IncreSeed]
}
}
////
//{
// "ConfigId": "1300000000002", // -
// "DbNickName": "日志库",
// "DbType": "Sqlite",
// "ConnectionString": "DataSource=./Admin.NET.Log.db", //
// "DbSettings": {
// "EnableInitDb": true, //
// "EnableDiffLog": false, //
// "EnableUnderLine": false // 线
// },
// "TableSettings": {
// "EnableInitTable": true, //
// "EnableIncreTable": false // [IncreTable]
// },
// "SeedSettings": {
// "EnableInitSeed": false, //
// "EnableIncreSeed": false // [IncreSeed]
// }
//},
////
//{
// "ConfigId": "test", //
// "DbType": "Sqlite", //
// "ConnectionString": "DataSource=./Admin.NET.Test.db", //
// "DbSettings": {
// "EnableInitDb": true, //
// "EnableDiffLog": false, //
// "EnableUnderLine": false // 线
// },
// "TableSettings": {
// "EnableInitTable": true, //
// "EnableIncreTable": false // [IncreTable]
// },
// "SeedSettings": {
// "EnableInitSeed": true, //
// "EnableIncreSeed": false // [IncreSeed]
// }
//}
]
}
}

@ -0,0 +1,9 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"DeepSeekSettings": {
"SourceLang": "zh-cn",
"ApiUrl": "https://api.deepseek.com/v1/chat/completions",
"ApiKey": "你的 API KEY"
}
}

@ -0,0 +1,28 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"ElasticSearch:Logging": {
"Enabled": true, // ES
"AuthType": "None", // ES BasicApiKeyBase64ApiKeyNone
"User": "elastic", // Basic使Basic
"Password": "123456", // Basic使Basic
"ApiId": "", // 使ApiKey
"ApiKey": "", // 使ApiKey
"Base64ApiKey": "TmtrOEszNEJuQ0NyaWlydGtROFk6SG1RZ0w3YzBTc2lCanJTYlV3aXNzZw==", // 使Base64ApiKey
"Fingerprint": "37:08:6A:C6:06:CC:9A:43:CF:ED:25:A2:1C:A4:69:57:90:31:2C:06:CA:61:56:39:6A:9C:46:11:BD:22:51:DA", // ES使Https
"ServerUris": [ "http://192.168.3.90:9200" ], //
"DefaultIndex": "adminnet" //
},
"ElasticSearch:Business": {
"Enabled": false, // ES
"AuthType": "Basic", // ES BasicApiKeyBase64ApiKeyNone
"User": "admin", // Basic使Basic
"Password": "123456", // Basic使Basic
"ApiId": "", // 使ApiKey
"ApiKey": "", // 使ApiKey
"Base64ApiKey": "TmtrOEszNEJuQ0NyaWlydGtROFk6SG1RZ0w3YzBTc2lCanJTYlV3aXNzZw==", // 使Base64ApiKey
"Fingerprint": "37:08:6A:C6:06:CC:9A:43:CF:ED:25:A2:1C:A4:69:57:90:31:2C:06:CA:61:56:39:6A:9C:46:11:BD:22:51:DA", // ES使Https
"ServerUris": [ "http://192.168.1.100:9200" ], //
"DefaultIndex": "adminnet" //
}
}

@ -0,0 +1,15 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
//
"Email": {
"Host": "smtp.163.com", //
"Port": 465, // 46599425
"EnableSsl": true, // SSL
"DefaultFromEmail": "xxx@163.com", //
"DefaultToEmail": "xxx@qq.com", //
"UserName": "xxx@163.com", //
"Password": "", //
"DefaultFromName": "Admin.NET 通用权限开发平台" //
}
}

@ -0,0 +1,8 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
//
"Enum": {
"EntityAssemblyNames": [ "Admin." ] //
}
}

@ -0,0 +1,16 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"EventBus": {
// Redis
"EventSourceType": "Memory", // MemoryRedisRabbitMQKafka
"RabbitMQ": {
"UserName": "adminnet",
"Password": "adminnet++123456",
"HostName": "127.0.0.1",
"Port": 5672
},
"Kafka": {
}
}
}

@ -0,0 +1,17 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"JWTSettings": {
"ValidateIssuerSigningKey": true, // bool true
"IssuerSigningKey": "3c1cbc3f546eda35168c3aa3cb91780fbe703f0996c6d123ea96dc85c70bbc0a", // string 16
"ValidateIssuer": true, // bool true
"ValidIssuer": "Admin.NET", // string
"ValidateAudience": true, // bool true
"ValidAudience": "Admin.NET", // string
"ValidateLifetime": true, // bool truetrue
//"ExpiredTime": 20, // long 20 13
"ClockSkew": 5, // long 5
"Algorithm": "HS256", // string HS256
"RequireExpirationTime": true // false
}
}

@ -0,0 +1,107 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
// IP
"IpRateLimiting": {
// :5访
// False访5访
// True 5GetData访访PostData()5,5
"EnableEndpointRateLimiting": true,
// StackBlockedRequestsfalseAPI3
// APIAPI
"StackBlockedRequests": false,
// RealIpHeader使Kestrel使IP X-Real-IP使
"RealIpHeader": "X-Real-IP",
// ClientIdHeaderIDIDClientWhitelist
"ClientIdHeader": "X-ClientId",
// IP:Ipv4Ipv6
"IpWhitelist": [],
//
"EndpointWhitelist": [],
//
"ClientWhitelist": [],
"QuotaExceededResponse": {
"Content": "{{\"code\":429,\"type\":\"error\",\"message\":\"访问过于频繁,请稍后重试禁止违法行为否则110 👮\",\"result\":null,\"extras\":null}}",
"ContentType": "application/json",
"StatusCode": 429
},
//
"HttpStatusCode": 429,
// API,*
"GeneralRules": [
// 11000
{
"Endpoint": "*",
"Period": "1s",
"Limit": 1000
},
// 160000
{
"Endpoint": "*",
"Period": "1m",
"Limit": 60000
}
//// 13600000
//{
// "Endpoint": "*",
// "Period": "1h",
// "Limit": 3600000
//},
//// 186400000
//{
// "Endpoint": "*",
// "Period": "1d",
// "Limit": 86400000
//}
]
},
// IP
"IpRateLimitPolicies": {
"IpRules": [
{
"Ip": "0.0.0.0", // IP"::1/10"
"Rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 0 // 01
}
]
}
]
},
//
"ClientRateLimiting": {
"EnableEndpointRateLimiting": true,
"ClientIdHeader": "X-ClientId",
"EndpointWhitelist": [],
"ClientWhitelist": [],
"QuotaExceededResponse": {
"Content": "{{\"code\":429,\"type\":\"error\",\"message\":\"访问人数过多,请稍后重试!\",\"result\":null,\"extras\":null}}",
"ContentType": "application/json",
"StatusCode": 429
},
"HttpStatusCode": 429,
"GeneralRules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 2000
}
]
},
"ClientRateLimitPolicies": {
"ClientRules": [
{
"ClientId": "",
"Rules": [
{
"Endpoint": "*",
"Period": "1s",
"Limit": 2000
}
]
}
]
}
}

@ -0,0 +1,37 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"Microsoft.EntityFrameworkCore": "Information",
"AspNetCoreRateLimit": "None",
"System.Net.Http.HttpClient": "Warning"
},
"File": {
"Enabled": true, //
"FileName": "logs/{0:yyyyMMdd}_{1}.log", //
"Append": true, //
"MinimumLevel": "Error", //
"FileSizeLimitBytes": 10485760, // 10M=10*1024*1024
"MaxRollingFiles": 30 // 30
},
"Database": {
"Enabled": true, //
"MinimumLevel": "Information" //
},
"Monitor": {
"GlobalEnabled": true, //
"IncludeOfMethods": [], // GlobalEnabled=false
"ExcludeOfMethods": [], // GlobalEnabled=true
"BahLogLevel": "Information", // Oops.Oh Oops.Bah
"WithReturnValue": true, // true
"ReturnValueThreshold": 0, // 0
"JsonBehavior": "None", // JsonNone(OnlyJsonAll)
"JsonIndented": false, // Json
"UseUtcTimestamp": false, // UTCLOCAL
"ConsoleLog": true //
}
}
}

@ -0,0 +1,14 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"OAuth": {
"Weixin": {
"ClientId": "xxx",
"ClientSecret": "xxx"
},
"Gitee": {
"ClientId": "xxx",
"ClientSecret": "xxx"
}
}
}

@ -0,0 +1,60 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
//
"SMS": {
"VerifyCodeExpireSeconds": 60, // 60
//
"Aliyun": {
"AccessKeyId": "",
"AccessKeySecret": "",
"Templates": [
{
"Id": "0",
"SignName": "AdminNET 平台",
"TemplateCode": "SMS_xxx",
"Content": "您的验证码为:${code},请勿泄露于他人!"
},
{
"Id": "1",
"SignName": "AdminNET 平台",
"TemplateCode": "SMS_xxx",
"Content": "注册成功,感谢您的注册,请妥善保管您的账户信息"
}
]
},
//
"Tencentyun": {
"SdkAppId": "",
"AccessKeyId": "",
"AccessKeySecret": "",
"Templates": [
{
"Id": "0",
"SignName": "AdminNET 平台",
"TemplateCode": "",
"Content": ""
}
]
},
//
"Custom": {
"Enabled": false, //
"Method": "GET", // : GET POST
"ApiUrl": "https://api.xxxx.com/sms?u=xxxx&key=59e03f49c3dbb5033&m={mobile}&c={content}", // API: {mobile}, {content}, {code}
"ContentType": "application/x-www-form-urlencoded", // POSTContent-Type: application/json application/x-www-form-urlencoded
"PostData": "", // POSTJSON : {"mobile":"{mobile}","content":"{content}","apikey":"your_key"}Form : mobile={mobile}&content={content}&apikey=your_key
"SuccessFlag": "0", //
"Templates": [
{
"Id": "0",
"Content": "您的验证码为:{code},请勿泄露于他人!"
},
{
"Id": "1",
"Content": "注册成功,感谢您的注册,请妥善保管您的账户信息"
}
]
}
}
}

@ -0,0 +1,12 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"HwPortalSearch": {
"Engine": "mysql_fulltext",
"EnableLegacyFallback": true,
"ConnectionString": "",
"UseMainDbConnectionWhenEmpty": true,
"BatchSize": 200,
"TakeLimit": 500,
"AutoInitSchema": true
}
}

@ -0,0 +1,41 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"SpecificationDocumentSettings": {
"DocumentTitle": "Admin.NET 通用权限开发平台",
"GroupOpenApiInfos": [
{
"Group": "Default",
"Title": "Admin.NET 通用权限开发平台",
"Description": "让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。",
"Version": "1.0.0",
"Order": 1000
},
{
"Group": "All Groups",
"Title": "所有接口",
"Description": "让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。",
"Version": "1.0.0",
"Order": 0
}
],
"DefaultGroupName": "Default", //
"DocExpansionState": "List", // ListFullNone
"EnableAllGroups": true,
//"ServerDir": "xxx", // Servers
"HideServers": true,
"Servers": [
{
"Url": "http://ip/xxx",
"Description": "二级目录应用程序名"
}
],
"LoginInfo": {
"Enabled": true, // Swagger
"CheckUrl": "/api/swagger/checkUrl",
"SubmitUrl": "/api/swagger/submitUrl",
"EnableOnProduction": false //
},
"EnumToNumber": true //
}
}

@ -0,0 +1,33 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"Upload": {
"Path": "upload/{yyyy}/{MM}/{dd}", //
"MaxSize": 51200, // KB1024*50
"ContentType": [ "image/jpg", "image/png", "image/jpeg", "image/gif", "image/bmp", "text/plain", "text/xml", "application/pdf", "application/msword", "application/vnd.ms-excel", "application/vnd.ms-powerpoint", "application/vnd.openxmlformats-officedocument.presentationml.presentation", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "video/mp4", "application/wps-office.docx", "application/wps-office.xlsx", "application/wps-office.pptx", "application/vnd.android.package-archive" ],
"EnableMd5": false // MDF5-
},
"OSSProvider": {
"Enabled": false,
"Provider": "Minio", // OSS Invalid/Minio/Aliyun/QCloud/Qiniu/HuaweiCloud
"Endpoint": "xxx.xxx.xxx.xxx:8090", // /APIOSSAppId
"Region": "xxx.xxx.xxx.xxx", //
"AccessKey": "",
"SecretKey": "",
"IsEnableHttps": false, // HTTPS
"IsEnableCache": true, //
"Bucket": "admin.net",
"CustomHost": "" // HostHost使Endpoint
},
"SSHProvider": {
"Enabled": false,
"Host": "127.0.0.1",
"Port": 8222,
"Username": "sshuser",
"Password": "Password.1"
},
"MultiOSS": {
"Enabled": false, // OSS
"Description": "启用多OSS功能后系统将支持多个存储提供者可以通过BucketName或ProviderId指定使用哪个存储提供者"
}
}

@ -0,0 +1,32 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"Wechat": {
//
"WechatAppId": "",
"WechatAppSecret": "",
"WechatToken": "", // (Token)
"WechatEncodingAESKey": "", // (EncodingAESKey)
//
"WxOpenAppId": "",
"WxOpenAppSecret": "",
"WxToken": "", // (Token)
"WxEncodingAESKey": "", // (EncodingAESKey)
"QRImagePath": "" // eg: D:\\Web\\wwwroot\\upload\\QRImagewwwroot\\upload\\QRImage
},
//
"WechatPay": {
"AppId": "", // AppIdAppIdAppIdCorpId
"MerchantId": "", //
"MerchantV3Secret": "", // APIv3
"MerchantCertificateSerialNumber": "", //
"MerchantCertificatePrivateKey": "WxPayCert/apiclient_key.pem" // API(apiclient_key.pem)
},
//
"PayCallBack": {
"WechatPayUrl": "https://xxx/api/sysWechatPay/payCallBack", //
"WechatRefundUrl": "", // 退
"AlipayUrl": "", //
"AlipayRefundUrl": "" // 退
}
}

@ -0,0 +1,18 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Application;
/// <summary>
/// 业务应用相关常量
/// </summary>
public class ApplicationConst
{
/// <summary>
/// API分组名称
/// </summary>
public const string GroupName = "xxx业务应用";
}

@ -0,0 +1,67 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using SqlSugar;
namespace Admin.NET.Application;
/// <summary>
/// 用户表视图必须加IgnoreTable防止被生成为表
/// </summary>
[SugarTable(null, "用户表视图"), IgnoreTable]
public class TestViewSysUser : EntityBase, ISqlSugarView
{
/// <summary>
/// 账号
/// </summary>
[SugarColumn(ColumnDescription = "账号")]
public virtual string Account { get; set; }
/// <summary>
/// 真实姓名
/// </summary>
[SugarColumn(ColumnDescription = "真实姓名")]
public virtual string RealName { get; set; }
/// <summary>
/// 昵称
/// </summary>
[SugarColumn(ColumnDescription = "昵称")]
public string? NickName { get; set; }
/// <summary>
/// 机构名称
/// </summary>
[SugarColumn(ColumnDescription = "机构名称")]
public string? OrgName { get; set; }
/// <summary>
/// 职位名称
/// </summary>
[SugarColumn(ColumnDescription = "职位名称")]
public string? PosName { get; set; }
/// <summary>
/// 查询实例
/// </summary>
/// <param name="db"></param>
/// <returns></returns>
public string GetQueryableSqlString(SqlSugarScopeProvider db)
{
return db.Queryable<SysUser>()
.LeftJoin<SysOrg>((u, a) => u.OrgId == a.Id)
.LeftJoin<SysPos>((u, a, b) => u.PosId == b.Id)
.Select((u, a, b) => new TestViewSysUser
{
Id = u.Id,
Account = u.Account,
RealName = u.RealName,
NickName = u.NickName,
OrgName = a.Name,
PosName = b.Name,
}).ToMappedSqlString();
}
}

@ -0,0 +1,103 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Furion.EventBus;
namespace Admin.NET.Application;
/// <summary>
/// 系统用户操作事件订阅
/// </summary>
public class SysUserEventSubscriber : IEventSubscriber, ISingleton, IDisposable
{
public SysUserEventSubscriber()
{
}
/// <summary>
/// 增加系统用户
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
[EventSubscribe(SysUserEventTypeEnum.Add)]
public Task AddUser(EventHandlerExecutingContext context)
{
return Task.CompletedTask;
}
/// <summary>
/// 注册用户
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
[EventSubscribe(SysUserEventTypeEnum.Register)]
public Task RegisterUser(EventHandlerExecutingContext context)
{
return Task.CompletedTask;
}
/// <summary>
/// 更新系统用户
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
[EventSubscribe(SysUserEventTypeEnum.Update)]
public Task UpdateUser(EventHandlerExecutingContext context)
{
return Task.CompletedTask;
}
/// <summary>
/// 删除系统用户
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
[EventSubscribe(SysUserEventTypeEnum.Delete)]
public Task DeleteUser(EventHandlerExecutingContext context)
{
return Task.CompletedTask;
}
/// <summary>
/// 设置系统用户状态
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
[EventSubscribe(SysUserEventTypeEnum.SetStatus)]
public Task SetUserStatus(EventHandlerExecutingContext context)
{
return Task.CompletedTask;
}
/// <summary>
/// 授权用户角色
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
[EventSubscribe(SysUserEventTypeEnum.UpdateRole)]
public Task UpdateUserRole(EventHandlerExecutingContext context)
{
return Task.CompletedTask;
}
/// <summary>
/// 解除登录锁定
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
[EventSubscribe(SysUserEventTypeEnum.UnlockLogin)]
public Task UnlockUserLogin(EventHandlerExecutingContext context)
{
return Task.CompletedTask;
}
/// <summary>
/// 释放服务作用域
/// </summary>
public void Dispose()
{
}
}

@ -0,0 +1,15 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
global using Admin.NET.Core;
global using Furion;
global using Furion.DependencyInjection;
global using Furion.DynamicApiController;
global using Microsoft.AspNetCore.Authorization;
global using Microsoft.AspNetCore.Mvc;
global using Microsoft.Extensions.DependencyInjection;
global using System;
global using System.Threading.Tasks;

@ -0,0 +1,28 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Application;
/// <summary>
/// 示例开放接口
/// </summary>
[ApiDescriptionSettings("开放接口", Name = "Demo", Order = 100)]
[Authorize(AuthenticationSchemes = SignatureAuthenticationDefaults.AuthenticationScheme)]
public class DemoOpenApi : IDynamicApiController
{
private readonly UserManager _userManager;
public DemoOpenApi(UserManager userManager)
{
_userManager = userManager;
}
[HttpGet("helloWord")]
public Task<string> HelloWord()
{
return Task.FromResult($"Hello word. {_userManager.Account}");
}
}

@ -0,0 +1,22 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
namespace Admin.NET.Application;
[AppStartup(100)]
public class Startup : AppStartup
{
public void ConfigureServices(IServiceCollection services)
{
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
}
}

@ -0,0 +1,74 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0;net10.0</TargetFrameworks>
<NoWarn>1701;1702;1591;8632</NoWarn>
<DocumentationFile></DocumentationFile>
<ImplicitUsings>enable</ImplicitUsings>
<PreserveCompilationContext>true</PreserveCompilationContext>
<Nullable>disable</Nullable>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<Copyright>Admin.NET</Copyright>
<Description>Admin.NET 通用权限开发平台</Description>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AlibabaCloud.SDK.Dysmsapi20170525" Version="4.3.0" />
<PackageReference Include="AlipaySDKNet.Standard" Version="4.9.971" />
<PackageReference Include="AngleSharp" Version="1.4.0" />
<PackageReference Include="AspectCore.Extensions.Reflection" Version="2.4.0" />
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
<PackageReference Include="Elastic.Clients.Elasticsearch" Version="9.3.0" />
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.8.18" />
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.8.18" />
<PackageReference Include="Furion.Pure" Version="4.9.8.18" />
<PackageReference Include="Hardware.Info" Version="101.1.1.1" />
<PackageReference Include="Hashids.net" Version="1.7.0" />
<PackageReference Include="IPTools.China" Version="1.6.0" />
<PackageReference Include="IPTools.International" Version="1.6.0" />
<PackageReference Include="log4net" Version="3.3.0" />
<PackageReference Include="Lazy.Captcha.Core" Version="2.2.2" />
<PackageReference Include="Magicodes.IE.Excel" Version="2.8.0" />
<PackageReference Include="Magicodes.IE.Pdf" Version="2.8.0" />
<PackageReference Include="Magicodes.IE.Word" Version="2.8.0" />
<PackageReference Include="MailKit" Version="4.15.0" />
<PackageReference Include="MiniExcel" Version="1.42.0" />
<PackageReference Include="MiniWord" Version="0.9.2" />
<PackageReference Include="NewLife.Redis" Version="6.4.2026.201" />
<PackageReference Include="Novell.Directory.Ldap.NETStandard" Version="4.0.0" />
<PackageReference Include="OnceMi.AspNetCore.OSS" Version="1.2.0" />
<PackageReference Include="QRCoder" Version="1.7.0" />
<PackageReference Include="RabbitMQ.Client" Version="7.2.0" />
<PackageReference Include="SixLabors.ImageSharp.Web" Version="3.2.0" />
<PackageReference Include="SKIT.FlurlHttpClient.Wechat.Api" Version="3.14.0" />
<PackageReference Include="SKIT.FlurlHttpClient.Wechat.TenpayV3" Version="3.16.0" />
<PackageReference Include="SqlSugar.MongoDbCore" Version="5.1.4.277" />
<PackageReference Include="SqlSugarCore" Version="5.1.4.211" />
<PackageReference Include="SSH.NET" Version="2025.1.0" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.7.1" />
<PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1375" />
<PackageReference Include="UAParser" Version="3.1.47" />
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
<PackageReference Include="BouncyCastle.Cryptography" Version="2.6.2" Aliases="BouncyCastleV2" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
<PackageReference Include="AspNet.Security.OAuth.Gitee" Version="8.3.0" />
<PackageReference Include="AspNet.Security.OAuth.Weixin" Version="8.3.0" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="8.0.22" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="8.0.22" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="8.0.22" />
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.4.13" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net10.0' ">
<PackageReference Include="AspNet.Security.OAuth.Gitee" Version="10.0.0" />
<PackageReference Include="AspNet.Security.OAuth.Weixin" Version="10.0.0" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="10.0.3" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.NewtonsoftJson" Version="10.0.3" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="10.0.3" />
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.5.4" />
<PackageReference Include="XiHan.Framework.Utils" Version="2.2.0" />
</ItemGroup>
</Project>

@ -0,0 +1,92 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 通用接口参数验证特性类
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class CommonValidationAttribute : ValidationAttribute
{
private readonly Dictionary<string, string> _conditions;
private static readonly Dictionary<string, Delegate> CompiledConditions = new();
/// <summary>
/// </summary>
/// <param name="conditionPairs">条件对参数,长度必须为偶数<br/>
/// 奇数字符串参数:动态条件<br/>
/// 偶数字符串参数:提示消息
/// </param>
/// <example>
/// <code lang="C">
/// public class ModelInput {
///
///
/// public string A { get; set; }
///
///
/// [CommonValidation(
/// "A == 1 <value>&amp;&amp;</value> B == null", "当 A == 1时B不能为空",
/// "C == 2 <value>&amp;&amp;</value> B == null", "当 C == 2时B不能为空"
/// )]
/// public string B { get; set; }
/// }
/// </code>
/// </example>
public CommonValidationAttribute(params string[] conditionPairs)
{
if (conditionPairs.Length % 2 != 0) throw new ArgumentException("条件对必须以偶数个字符串的形式提供。");
var conditions = new Dictionary<string, string>();
for (int i = 0; i < conditionPairs.Length; i += 2)
conditions.Add(conditionPairs[i], conditionPairs[i + 1]);
_conditions = conditions;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
foreach (var (expr, errorMessage) in _conditions)
{
var conditionKey = $"{validationContext.ObjectType.FullName}.{expr}";
if (!CompiledConditions.TryGetValue(conditionKey, out var condition))
{
condition = CreateCondition(validationContext.ObjectType, expr);
CompiledConditions[conditionKey] = condition;
}
if ((bool)condition.DynamicInvoke(validationContext.ObjectInstance)!)
{
return new ValidationResult(errorMessage ?? $"[{validationContext.MemberName}]校验失败");
}
}
return ValidationResult.Success;
}
private Delegate CreateCondition(Type modelType, string expression)
{
try
{
// 创建参数表达式
var parameter = Expression.Parameter(typeof(object), "x");
// 构建 Lambda 表达式
var lambda = DynamicExpressionParser.ParseLambda(new[] { Expression.Parameter(modelType, "x") }, typeof(bool), expression);
// 创建新的 Lambda 表达式,接受 object 参数并调用编译后的表达式
var invokeExpression = Expression.Invoke(lambda, Expression.Convert(parameter, modelType));
var finalLambda = Expression.Lambda<Func<object, bool>>(invokeExpression, parameter);
return finalLambda.Compile();
}
catch (Exception ex)
{
throw new ArgumentException($"无法解析表达式 '{expression}': {ex.Message}", ex);
}
}
}

@ -0,0 +1,22 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 常量特性
/// </summary>
[SuppressSniffer]
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]
public class ConstAttribute : Attribute
{
public string Name { get; set; }
public ConstAttribute(string name)
{
Name = name;
}
}

@ -0,0 +1,21 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 自定义Json转换字段名
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class CustomJsonPropertyAttribute : Attribute
{
public string Name { get; }
public CustomJsonPropertyAttribute(string name)
{
Name = name;
}
}

@ -0,0 +1,22 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 自定义规范化结果特性
/// </summary>
[SuppressSniffer]
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]
public class CustomUnifyResultAttribute : Attribute
{
public string Name { get; set; }
public CustomUnifyResultAttribute(string name)
{
Name = name;
}
}

@ -0,0 +1,59 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 数据脱敏特性(支持自定义脱敏位置和脱敏字符)
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class DataMaskAttribute : Attribute
{
/// <summary>
/// 脱敏起始位置从0开始
/// </summary>
private int StartIndex { get; }
/// <summary>
/// 脱敏长度
/// </summary>
private int Length { get; }
/// <summary>
/// 脱敏字符(默认*
/// </summary>
private char MaskChar { get; set; } = '*';
/// <summary>
/// 是否保留原始长度默认true
/// </summary>
private bool KeepLength { get; set; } = true;
public DataMaskAttribute(int startIndex, int length)
{
if (startIndex < 0) throw new ArgumentOutOfRangeException(nameof(startIndex));
if (length <= 0) throw new ArgumentOutOfRangeException(nameof(length));
StartIndex = startIndex;
Length = length;
}
/// <summary>
/// 执行脱敏处理
/// </summary>
public string Mask(string input)
{
if (string.IsNullOrEmpty(input) || input.Length <= StartIndex)
return input;
var maskedLength = Math.Min(Length, input.Length - StartIndex);
var maskStr = new string(MaskChar, KeepLength ? maskedLength : Math.Min(4, maskedLength));
return input.Substring(0, StartIndex) + maskStr +
(StartIndex + maskedLength < input.Length ?
input.Substring(StartIndex + maskedLength) : "");
}
}

@ -0,0 +1,138 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 字典值合规性校验特性
/// </summary>
[SuppressSniffer]
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true, Inherited = true)]
public class DictAttribute : ValidationAttribute, ITransient
{
/// <summary>
/// 字典编码
/// </summary>
public string DictTypeCode { get; }
/// <summary>
/// 是否允许空字符串
/// </summary>
public bool AllowEmptyStrings { get; set; } = false;
/// <summary>
/// 允许空值,有值才验证,默认 false
/// </summary>
public bool AllowNullValue { get; set; } = false;
/// <summary>
/// 字典值合规性校验特性
/// </summary>
/// <param name="dictTypeCode"></param>
/// <param name="errorMessage"></param>
public DictAttribute(string dictTypeCode = "", string errorMessage = "字典值不合法!")
{
DictTypeCode = dictTypeCode;
ErrorMessage = errorMessage;
}
/// <summary>
/// 字典值合规性校验
/// </summary>
/// <param name="value"></param>
/// <param name="validationContext"></param>
/// <returns></returns>
protected override ValidationResult IsValid(object? value, ValidationContext validationContext)
{
// 判断是否允许空值
if (AllowNullValue && value == null) return ValidationResult.Success;
// 获取属性的类型
var property = validationContext.ObjectType.GetProperty(validationContext.MemberName!);
if (property == null) return new ValidationResult($"未知属性: {validationContext.MemberName}");
string importHeaderName = GetImporterHeaderName(property, validationContext.MemberName);
var propertyType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
// 先尝试从 ValidationContext 的依赖注入容器中拿服务,拿不到或类型不匹配时,再从全局的 App 容器中获取
if (validationContext.GetService(typeof(SysDictDataService)) is not SysDictDataService sysDictDataService)
sysDictDataService = App.GetRequiredService<SysDictDataService>();
// 获取字典值列表
var dictDataList = sysDictDataService.GetDataList(DictTypeCode).GetAwaiter().GetResult();
// 使用 HashSet 来提高查找效率
var dictHash = new HashSet<string>(dictDataList.Select(u => u.Value));
// 判断是否为集合类型
if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(List<>))
{
// 如果是空集合并且允许空值,则直接返回成功
if (value == null && AllowNullValue) return ValidationResult.Success;
// 处理集合为空的情况
var collection = value as IEnumerable;
if (collection == null) return ValidationResult.Success;
// 获取集合的元素类型
var elementType = propertyType.GetGenericArguments()[0];
var underlyingElementType = Nullable.GetUnderlyingType(elementType) ?? elementType;
// 如果元素类型是枚举,则逐个验证
if (underlyingElementType.IsEnum)
{
foreach (var item in collection)
{
if (item == null && AllowNullValue) continue;
if (!Enum.IsDefined(underlyingElementType, item!))
return new ValidationResult($"提示:{ErrorMessage}|枚举值【{item}】不是有效的【{underlyingElementType.Name}】枚举类型值!", [importHeaderName]);
}
return ValidationResult.Success;
}
foreach (var item in collection)
{
if (item == null && AllowNullValue) continue;
var itemString = item?.ToString();
if (!dictHash.Contains(itemString))
return new ValidationResult($"提示:{ErrorMessage}|字典【{DictTypeCode}】不包含【{itemString}】!", [importHeaderName]);
}
return ValidationResult.Success;
}
var valueAsString = value?.ToString();
// 是否忽略空字符串
if (AllowEmptyStrings && string.IsNullOrEmpty(valueAsString)) return ValidationResult.Success;
// 枚举类型验证
if (propertyType.IsEnum)
{
if (!Enum.IsDefined(propertyType, value!)) return new ValidationResult($"提示:{ErrorMessage}|枚举值【{value}】不是有效的【{propertyType.Name}】枚举类型值!", [importHeaderName]);
return ValidationResult.Success;
}
if (!dictHash.Contains(valueAsString))
return new ValidationResult($"提示:{ErrorMessage}|字典【{DictTypeCode}】不包含【{valueAsString}】!", [importHeaderName]);
return ValidationResult.Success;
}
/// <summary>
/// 获取本字段上 [ImporterHeader(Name = "xxx")] 里的Name如果没有则使用defaultName.
/// 用于在从excel导入数据时能让调用者知道是哪个字段验证失败而不是抛异常
/// </summary>
private static string GetImporterHeaderName(PropertyInfo property, string defaultName)
{
var importerHeader = property.GetCustomAttribute<ImporterHeaderAttribute>();
string importerHeaderName = importerHeader?.Name ?? defaultName;
return importerHeaderName;
}
}

@ -0,0 +1,53 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 枚举值合规性校验特性
/// </summary>
[SuppressSniffer]
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Enum | AttributeTargets.Field, AllowMultiple = true)]
public class EnumAttribute : ValidationAttribute, ITransient
{
/// <summary>
/// 枚举值合规性校验特性
/// </summary>
/// <param name="errorMessage"></param>
public EnumAttribute(string errorMessage = "枚举值不合法!")
{
ErrorMessage = errorMessage;
}
/// <summary>
/// 枚举值合规性校验
/// </summary>
/// <param name="value"></param>
/// <param name="validationContext"></param>
/// <returns></returns>
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// 获取属性的类型
var property = validationContext.ObjectType.GetProperty(validationContext.MemberName);
if (property == null)
return new ValidationResult($"未知属性: {validationContext.MemberName}");
var propertyType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
// 检查属性类型是否为枚举或可空枚举类型
if (!propertyType.IsEnum)
return new ValidationResult($"属性类型'{validationContext.MemberName}'不是有效的枚举类型!");
// 检查枚举值是否有效
if (value == null && Nullable.GetUnderlyingType(property.PropertyType) == null)
return new ValidationResult($"提示:{ErrorMessage}|枚举值不能为 null");
if (value != null && !Enum.IsDefined(propertyType, value))
return new ValidationResult($"提示:{ErrorMessage}|枚举值【{value}】不是有效的【{propertyType.Name}】枚举类型值!");
return ValidationResult.Success;
}
}

@ -0,0 +1,112 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Newtonsoft.Json;
using System.Security.Claims;
namespace Admin.NET.Core;
/// <summary>
/// 防止重复请求过滤器特性(此特性使用了分布式锁,需确保系统支持分布式锁)
/// </summary>
[SuppressSniffer]
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = true)]
public class IdempotentAttribute : Attribute, IAsyncActionFilter
{
/// <summary>
/// 请求间隔时间/秒
/// </summary>
public int IntervalTime { get; set; } = 5;
/// <summary>
/// 错误提示内容
/// </summary>
public string Message { get; set; } = "你操作频率过快,请稍后重试!";
/// <summary>
/// 缓存前缀: Key+请求路由+用户Id+请求参数
/// </summary>
public string CacheKey { get; set; } = CacheConst.KeyIdempotent;
/// <summary>
/// 是否直接抛出异常Ture是False返回上次请求结果
/// </summary>
public bool ThrowBah { get; set; }
/// <summary>
/// 锁前缀
/// </summary>
public string LockPrefix { get; set; } = "lock_";
public IdempotentAttribute()
{
}
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var httpContext = context.HttpContext;
var path = httpContext.Request.Path.Value.ToString();
var userId = httpContext.User?.FindFirstValue(ClaimConst.UserId);
var cacheExpireTime = TimeSpan.FromSeconds(IntervalTime);
var parameters = JsonConvert.SerializeObject(context.ActionArguments, Formatting.None, new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Include,
DefaultValueHandling = DefaultValueHandling.Include
});
var cacheKey = CacheKey + MD5Encryption.Encrypt($"{path}{userId}{parameters}");
var sysCacheService = httpContext.RequestServices.GetService<SysCacheService>();
try
{
// 分布式锁
using var distributedLock = sysCacheService.BeginCacheLock($"{LockPrefix}{cacheKey}") ?? throw Oops.Oh(Message);
var cacheValue = sysCacheService.Get<ResponseData>(cacheKey);
if (cacheValue != null)
{
if (ThrowBah) throw Oops.Oh(Message);
context.Result = new ObjectResult(cacheValue.Value);
return;
}
else
{
var resultContext = await next();
// 缓存请求结果,null值不缓存
if (resultContext.Result is ObjectResult { Value: { } } objectResult)
{
var typeName = objectResult.Value.GetType().Name;
var responseData = new ResponseData
{
Type = typeName,
Value = objectResult.Value
};
sysCacheService.Set(cacheKey, responseData, cacheExpireTime);
}
}
}
catch (Exception ex)
{
throw Oops.Oh($"{Message}-{ex}");
}
}
/// <summary>
/// 请求结果数据
/// </summary>
private class ResponseData
{
/// <summary>
/// 结果类型
/// </summary>
public string Type { get; set; }
/// <summary>
/// 请求结果
/// </summary>
public dynamic Value { get; set; }
}
}

@ -0,0 +1,16 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 忽略枚举类型转字典特性(标记在枚举类型)
/// </summary>
[SuppressSniffer]
[AttributeUsage(AttributeTargets.Enum, AllowMultiple = true, Inherited = true)]
public class IgnoreEnumToDictAttribute : Attribute
{
}

@ -0,0 +1,16 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 忽略表结构初始化特性(标记在实体)
/// </summary>
[SuppressSniffer]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class IgnoreTableAttribute : Attribute
{
}

@ -0,0 +1,16 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 忽略更新种子特性(标记在种子类)
/// </summary>
[SuppressSniffer]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class IgnoreUpdateSeedAttribute : Attribute
{
}

@ -0,0 +1,16 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 忽略更新种子列特性(标记在实体属性)
/// </summary>
[SuppressSniffer]
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public class IgnoreUpdateSeedColumnAttribute : Attribute
{
}

@ -0,0 +1,24 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 属性字典配置
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class ImportDictAttribute : Attribute
{
/// <summary>
/// 字典Code
/// </summary>
public string TypeCode { get; set; }
/// <summary>
/// 目标对象名称
/// </summary>
public string TargetPropName { get; set; }
}

@ -0,0 +1,16 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 增量种子特性
/// </summary>
[SuppressSniffer]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class IncreSeedAttribute : Attribute
{
}

@ -0,0 +1,16 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 增量表特性
/// </summary>
[SuppressSniffer]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class IncreTableAttribute : Attribute
{
}

@ -0,0 +1,16 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 日志表特性
/// </summary>
[SuppressSniffer]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class LogTableAttribute : Attribute
{
}

@ -0,0 +1,60 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Newtonsoft.Json;
namespace Admin.NET.Core;
/// <summary>
/// 字符串掩码
/// </summary>
[SuppressSniffer]
public class MaskNewtonsoftJsonConverter : JsonConverter<string>
{
public override string ReadJson(JsonReader reader, Type objectType, string existingValue, bool hasExistingValue, JsonSerializer serializer)
{
return reader.Value.ToString();
}
public override void WriteJson(JsonWriter writer, string value, JsonSerializer serializer)
{
writer.WriteValue(value?.ToString().Mask());
}
}
/// <summary>
/// 身份证掩码
/// </summary>
[SuppressSniffer]
public class MaskIdCardNewtonsoftJsonConverter : JsonConverter<string>
{
public override string ReadJson(JsonReader reader, Type objectType, string existingValue, bool hasExistingValue, JsonSerializer serializer)
{
return reader.Value.ToString();
}
public override void WriteJson(JsonWriter writer, string value, JsonSerializer serializer)
{
writer.WriteValue(value?.ToString().MaskIdCard());
}
}
/// <summary>
/// 邮箱掩码
/// </summary>
[SuppressSniffer]
public class MaskEmailNewtonsoftJsonConverter : JsonConverter<string>
{
public override string ReadJson(JsonReader reader, Type objectType, string existingValue, bool hasExistingValue, JsonSerializer serializer)
{
return reader.Value.ToString();
}
public override void WriteJson(JsonWriter writer, string value, JsonSerializer serializer)
{
writer.WriteValue(value?.ToString().MaskEmail());
}
}

@ -0,0 +1,61 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Admin.NET.Core;
/// <summary>
/// 字符串掩码
/// </summary>
[SuppressSniffer]
public class MaskSystemTextJsonConverter : JsonConverter<string>
{
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return reader.GetString();
}
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
{
writer.WriteStringValue(value?.ToString().Mask());
}
}
/// <summary>
/// 身份证掩码
/// </summary>
[SuppressSniffer]
public class MaskIdCardSystemTextJsonConverter : JsonConverter<string>
{
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return reader.GetString();
}
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
{
writer.WriteStringValue(value?.ToString().MaskIdCard());
}
}
/// <summary>
/// 邮箱掩码
/// </summary>
[SuppressSniffer]
public class MaskEmailSystemTextJsonConverter : JsonConverter<string>
{
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return reader.GetString();
}
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
{
writer.WriteStringValue(value?.ToString().MaskEmail());
}
}

@ -0,0 +1,39 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 最大值校验
/// </summary>
[SuppressSniffer]
public class MaxValueAttribute : ValidationAttribute
{
private double MaxValue { get; }
/// <summary>
/// 最大值
/// </summary>
/// <param name="value"></param>
public MaxValueAttribute(double value) => this.MaxValue = value;
/// <summary>
/// 最大值校验
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public override bool IsValid(object value)
{
return value == null || Convert.ToDouble(value) <= this.MaxValue;
}
/// <summary>
/// 错误信息
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public override string FormatErrorMessage(string name) => base.FormatErrorMessage(name);
}

@ -0,0 +1,39 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 最小值校验
/// </summary>
[SuppressSniffer]
public class MinValueAttribute : ValidationAttribute
{
private double MinValue { get; set; }
/// <summary>
/// 最小值
/// </summary>
/// <param name="value"></param>
public MinValueAttribute(double value) => this.MinValue = value;
/// <summary>
/// 最小值校验
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public override bool IsValid(object value)
{
return value == null || Convert.ToDouble(value) > this.MinValue;
}
/// <summary>
/// 错误信息
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public override string FormatErrorMessage(string name) => base.FormatErrorMessage(name);
}

@ -0,0 +1,28 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 校验集合不能为空
/// </summary>
[SuppressSniffer]
public class NotEmptyAttribute : ValidationAttribute
{
/// <summary>
/// 校验集合不能为空
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public override bool IsValid(object value) => (value as IEnumerable)?.GetEnumerator().MoveNext() ?? false;
/// <summary>
/// 错误信息
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public override string FormatErrorMessage(string name) => base.FormatErrorMessage(name);
}

@ -0,0 +1,16 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 所属机构数据权限
/// </summary>
[SuppressSniffer]
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public class OwnerOrgAttribute : Attribute
{
}

@ -0,0 +1,16 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 所属用户数据权限
/// </summary>
[SuppressSniffer]
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public class OwnerUserAttribute : Attribute
{
}

@ -0,0 +1,25 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 种子数据特性
/// </summary>
[SuppressSniffer]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class SeedDataAttribute : Attribute
{
/// <summary>
/// 排序(越大越后执行)
/// </summary>
public int Order { get; set; } = 0;
public SeedDataAttribute(int orderNo)
{
Order = orderNo;
}
}

@ -0,0 +1,16 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统表特性
/// </summary>
[SuppressSniffer]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class SysTableAttribute : Attribute
{
}

@ -0,0 +1,22 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 枚举拓展主题样式
/// </summary>
[SuppressSniffer]
[AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field)]
public class ThemeAttribute : Attribute
{
public string Theme { get; private set; }
public ThemeAttribute(string theme)
{
this.Theme = theme;
}
}

@ -0,0 +1,43 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Microsoft.Extensions.DependencyInjection.Extensions;
using NewLife.Caching.Services;
namespace Admin.NET.Core;
public static class CacheSetup
{
/// <summary>
/// 缓存注册新生命Redis组件
/// </summary>
/// <param name="services"></param>
public static void AddCache(this IServiceCollection services)
{
var cacheOptions = App.GetConfig<CacheOptions>("Cache", true);
if (cacheOptions.CacheType == CacheTypeEnum.Redis.ToString())
{
var redis = new FullRedis(new RedisOptions
{
Configuration = cacheOptions.Redis.Configuration,
Prefix = cacheOptions.Redis.Prefix
})
{
// 自动检测集群节点
AutoDetect = App.GetConfig<bool>("Cache:Redis:AutoDetect", true)
};
// 最大消息大小
if (cacheOptions.Redis.MaxMessageSize > 0)
redis.MaxMessageSize = cacheOptions.Redis.MaxMessageSize;
// 注入 Redis 缓存提供者
services.AddSingleton<ICacheProvider>(u => new RedisCacheProvider(u) { Cache = redis });
}
// 内存缓存兜底。在没有配置Redis时使用内存缓存逻辑代码无需修改
services.TryAddSingleton<ICacheProvider, CacheProvider>();
}
}

@ -0,0 +1,56 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// SqlSugar二级缓存
/// </summary>
public class SqlSugarCache : ICacheService
{
/// <summary>
/// 系统缓存服务
/// </summary>
private static readonly SysCacheService _cache = App.GetRequiredService<SysCacheService>();
public void Add<V>(string key, V value)
{
_cache.Set($"{CacheConst.SqlSugar}{key}", value);
}
public void Add<V>(string key, V value, int cacheDurationInSeconds)
{
_cache.Set($"{CacheConst.SqlSugar}{key}", value, TimeSpan.FromSeconds(cacheDurationInSeconds));
}
public bool ContainsKey<V>(string key)
{
return _cache.ExistKey($"{CacheConst.SqlSugar}{key}");
}
public V Get<V>(string key)
{
return _cache.Get<V>($"{CacheConst.SqlSugar}{key}");
}
public IEnumerable<string> GetAllKey<V>()
{
return _cache.GetKeysByPrefixKey(CacheConst.SqlSugar);
}
public V GetOrCreate<V>(string key, Func<V> create, int cacheDurationInSeconds = int.MaxValue)
{
return _cache.GetOrAdd<V>($"{CacheConst.SqlSugar}{key}", (cacheKey) =>
{
return create();
}, cacheDurationInSeconds);
}
public void Remove<V>(string key)
{
_cache.Remove(key); // SqlSugar调用Remove方法时key中已包含了CacheConst.SqlSugar前缀
}
}

@ -0,0 +1,39 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 支付宝支付常量
/// </summary>
[SuppressSniffer]
public class AlipayConst
{
/// <summary>
/// 单笔无密转账【业务场景】固定值
/// </summary>
public const string BizScene = "DIRECT_TRANSFER";
/// <summary>
/// 单笔无密转账【销售产品码】固定值
/// </summary>
public const string ProductCode = "TRANS_ACCOUNT_NO_PWD";
/// <summary>
/// 交易状态参数名
/// </summary>
public const string TradeStatus = "trade_status";
/// <summary>
/// 交易成功标识
/// </summary>
public const string TradeSuccess = "TRADE_SUCCESS";
/// <summary>
/// 授权类型
/// </summary>
public const string GrantType = "authorization_code";
}

@ -0,0 +1,128 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 缓存相关常量
/// </summary>
public class CacheConst
{
/// <summary>
/// 用户权限缓存(按钮集合)
/// </summary>
public const string KeyUserButton = "sys_user_button:";
/// <summary>
/// 用户机构缓存
/// </summary>
public const string KeyUserOrg = "sys_user_org:";
/// <summary>
/// 角色最大数据范围缓存
/// </summary>
public const string KeyRoleMaxDataScope = "sys_role_maxDataScope:";
/// <summary>
/// 在线用户缓存
/// </summary>
public const string KeyUserOnline = "sys_user_online:";
/// <summary>
/// 图形验证码缓存
/// </summary>
public const string KeyVerCode = "sys_verCode:";
/// <summary>
/// 手机验证码缓存
/// </summary>
public const string KeyPhoneVerCode = "sys_phoneVerCode:";
/// <summary>
/// 密码错误次数缓存
/// </summary>
public const string KeyPasswordErrorTimes = "sys_password_error_times:";
/// <summary>
/// 租户缓存
/// </summary>
public const string KeyTenant = "sys_tenant";
/// <summary>
/// 常量下拉框
/// </summary>
public const string KeyConst = "sys_const:";
/// <summary>
/// 所有缓存关键字集合
/// </summary>
public const string KeyAll = "sys_keys";
/// <summary>
/// SqlSugar二级缓存
/// </summary>
public const string SqlSugar = "sys_sqlSugar:";
/// <summary>
/// 开放接口身份缓存
/// </summary>
public const string KeyOpenAccess = "sys_open_access:";
/// <summary>
/// 开放接口身份随机数缓存
/// </summary>
public const string KeyOpenAccessNonce = "sys_open_access_nonce:";
/// <summary>
/// 登录黑名单
/// </summary>
public const string KeyBlacklist = "sys_blacklist:";
/// <summary>
/// 系统配置缓存
/// </summary>
public const string KeyConfig = "sys_config:";
/// <summary>
/// 系统租户配置缓存
/// </summary>
public const string KeyTenantConfig = "sys_tenant_config:";
/// <summary>
/// 系统用户配置缓存
/// </summary>
public const string KeyUserConfig = "sys_user_config:";
/// <summary>
/// 系统字典缓存
/// </summary>
public const string KeyDict = "sys_dict:";
/// <summary>
/// 系统租户字典缓存
/// </summary>
public const string KeyTenantDict = "sys_tenant_dict:";
/// <summary>
/// 重复请求(幂等)字典缓存
/// </summary>
public const string KeyIdempotent = "sys_idempotent:";
/// <summary>
/// Excel临时文件缓存
/// </summary>
public const string KeyExcelTemp = "sys_excel_temp:";
/// <summary>
/// 系统更新命令日志缓存
/// </summary>
public const string KeySysUpdateLog = "sys_update_log";
/// <summary>
/// 系统更新间隔标记缓存
/// </summary>
public const string KeySysUpdateInterval = "sys_update_interval";
}

@ -0,0 +1,73 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// Claim相关常量
/// </summary>
public class ClaimConst
{
/// <summary>
/// 用户Id
/// </summary>
public const string UserId = "UserId";
/// <summary>
/// 账号
/// </summary>
public const string Account = "Account";
/// <summary>
/// 真实姓名
/// </summary>
public const string RealName = "RealName";
/// <summary>
/// 昵称
/// </summary>
public const string NickName = "NickName";
/// <summary>
/// 账号类型
/// </summary>
public const string AccountType = "AccountType";
/// <summary>
/// 租户Id
/// </summary>
public const string TenantId = "TenantId";
/// <summary>
/// 组织机构Id
/// </summary>
public const string OrgId = "OrgId";
/// <summary>
/// 组织机构名称
/// </summary>
public const string OrgName = "OrgName";
/// <summary>
/// 组织机构类型
/// </summary>
public const string OrgType = "OrgType";
/// <summary>
/// 微信OpenId
/// </summary>
public const string OpenId = "OpenId";
/// <summary>
/// 登录模式PC、APP
/// </summary>
public const string LoginMode = "LoginMode";
/// <summary>
/// 语言代码
/// </summary>
public const string LangCode = "LangCode";
}

@ -0,0 +1,39 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 通用常量
/// </summary>
[Const("平台配置")]
public class CommonConst
{
/// <summary>
/// 日志分组名称
/// </summary>
public const string SysLogCategoryName = "System.Logging.LoggingMonitor";
/// <summary>
/// 事件-增加异常日志
/// </summary>
public const string AddExLog = "Add:ExLog";
/// <summary>
/// 事件-发送异常邮件
/// </summary>
public const string SendErrorMail = "Send:ErrorMail";
/// <summary>
/// 默认基本角色名称
/// </summary>
public const string DefaultBaseRoleName = "默认基本角色";
/// <summary>
/// 默认基本角色编码
/// </summary>
public const string DefaultBaseRoleCode = "default_base_role";
}

@ -0,0 +1,148 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 配置常量
/// </summary>
public class ConfigConst
{
/// <summary>
/// 演示环境
/// </summary>
public const string SysDemoEnv = "sys_demo";
/// <summary>
/// 默认密码
/// </summary>
public const string SysPassword = "sys_password";
/// <summary>
/// 密码最大错误次数
/// </summary>
public const string SysPasswordMaxErrorTimes = "sys_password_max_error_times";
/// <summary>
/// 日志保留天数
/// </summary>
public const string SysLogRetentionDays = "sys_log_retention_days";
/// <summary>
/// 记录操作日志
/// </summary>
public const string SysOpLog = "sys_oplog";
/// <summary>
/// 单设备登录
/// </summary>
public const string SysSingleLogin = "sys_single_login";
/// <summary>
/// 登入登出提醒
/// </summary>
public const string SysLoginOutReminder = "sys_login_out_reminder";
/// <summary>
/// 登陆时隐藏租户
/// </summary>
public const string SysHideTenantLogin = "sys_hide_tenant_login";
/// <summary>
/// 登录二次验证
/// </summary>
public const string SysSecondVer = "sys_second_ver";
/// <summary>
/// 图形验证码
/// </summary>
public const string SysCaptcha = "sys_captcha";
/// <summary>
/// Token过期时间
/// </summary>
public const string SysTokenExpire = "sys_token_expire";
/// <summary>
/// RefreshToken过期时间
/// </summary>
public const string SysRefreshTokenExpire = "sys_refresh_token_expire";
/// <summary>
/// 发送异常日志邮件
/// </summary>
public const string SysErrorMail = "sys_error_mail";
/// <summary>
/// 域登录验证
/// </summary>
public const string SysDomainLogin = "sys_domain_login";
// /// <summary>
// /// 租户域名隔离登录验证
// /// </summary>
// public const string SysTenantHostLogin = "sys_tenant_host_login";
/// <summary>
/// 数据校验日志
/// </summary>
public const string SysValidationLog = "sys_validation_log";
/// <summary>
/// 行政区域同步层级 1-省级,2-市级,3-区县级,4-街道级,5-村级
/// </summary>
public const string SysRegionSyncLevel = "sys_region_sync_level";
/// <summary>
/// Default 分组
/// </summary>
public const string SysDefaultGroup = "Default";
/// <summary>
/// 支付宝授权页面地址
/// </summary>
public const string AlipayAuthPageUrl = "alipay_auth_page_url_";
// /// <summary>
// /// 系统图标
// /// </summary>
// public const string SysWebLogo = "sys_web_logo";
//
// /// <summary>
// /// 系统主标题
// /// </summary>
// public const string SysWebTitle = "sys_web_title";
//
// /// <summary>
// /// 系统副标题
// /// </summary>
// public const string SysWebViceTitle = "sys_web_viceTitle";
//
// /// <summary>
// /// 系统描述
// /// </summary>
// public const string SysWebViceDesc = "sys_web_viceDesc";
//
// /// <summary>
// /// 水印内容
// /// </summary>
// public const string SysWebWatermark = "sys_web_watermark";
//
// /// <summary>
// /// 版权说明
// /// </summary>
// public const string SysWebCopyright = "sys_web_copyright";
//
// /// <summary>
// /// ICP备案号
// /// </summary>
// public const string SysWebIcp = "sys_web_icp";
//
// /// <summary>
// /// ICP地址
// /// </summary>
// public const string SysWebIcpUrl = "sys_web_icpUrl";
}

@ -0,0 +1,33 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// SqlSugar相关常量
/// </summary>
public class SqlSugarConst
{
/// <summary>
/// 默认主数据库标识(默认租户)
/// </summary>
public const string MainConfigId = "1300000000001";
/// <summary>
/// 默认日志数据库标识
/// </summary>
public const string LogConfigId = "1300000000002";
/// <summary>
/// 默认表主键
/// </summary>
public const string PrimaryKey = "Id";
/// <summary>
/// 默认租户Id
/// </summary>
public const long DefaultTenantId = 1300000000001;
}

@ -0,0 +1,47 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Elastic.Clients.Elasticsearch;
namespace Admin.NET.Core;
/// <summary>
/// ES客户端容器
/// </summary>
public class ElasticSearchClientContainer
{
private readonly Dictionary<EsClientTypeEnum, ElasticsearchClient> _clients;
/// <summary>
/// 初始化容器(通过字典注入所有客户端)
/// </summary>
public ElasticSearchClientContainer(Dictionary<EsClientTypeEnum, ElasticsearchClient> clients)
{
_clients = clients ?? throw new ArgumentNullException(nameof(clients));
}
/// <summary>
/// 日志专用客户端
/// </summary>
public ElasticsearchClient Logging => GetClient(EsClientTypeEnum.Logging);
/// <summary>
/// 业务数据同步客户端
/// </summary>
public ElasticsearchClient Business => GetClient(EsClientTypeEnum.Business);
/// <summary>
/// 根据类型获取客户端(内部校验,避免未注册的类型)
/// </summary>
private ElasticsearchClient GetClient(EsClientTypeEnum type)
{
if (_clients.TryGetValue(type, out var client))
{
return client;
}
throw new KeyNotFoundException($"未注册的ES客户端类型{type},请检查注册配置");
}
}

@ -0,0 +1,85 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Elastic.Clients.Elasticsearch;
using Elastic.Transport;
namespace Admin.NET.Core;
public class ElasticSearchClientFactory
{
/// <summary>
/// 创建 ES 客户端(通用方法)
/// </summary>
/// <typeparam name="TOptions">配置类型(支持通用或场景专用)</typeparam>
/// <param name="configPath">配置文件路径(如 "ElasticSearch:Logging"</param>
/// <returns>ES 客户端实例(或 null if 未启用)</returns>
public static ElasticsearchClient? CreateClient<TOptions>(string configPath) where TOptions : ElasticSearchOptions, new()
{
// 从配置文件读取当前场景的配置
var options = App.GetConfig<TOptions>(configPath);
if (options == null)
throw Oops.Oh($"未找到{configPath}配置项");
if (!options.Enabled)
return null;
// 验证服务地址
if (options.ServerUris == null || !options.ServerUris.Any())
throw new ArgumentException($"ES 配置 {configPath} 未设置 ServerUris");
// 构建连接池(支持集群)
var uris = options.ServerUris.Select(uri => new Uri(uri)).ToList();
var connectionPool = new StaticNodePool(uris);
var connectionSettings = new ElasticsearchClientSettings(connectionPool)
.DefaultIndex(options.DefaultIndex) // 设置默认索引
.DisableDirectStreaming() // 开启请求/响应日志,方便排查问题
.OnRequestCompleted(response =>
{
if (response.HttpStatusCode == 401)
{
Console.WriteLine("ES 请求被拒绝:未提供有效认证信息");
}
});
// 配置认证
ConfigureAuthentication(connectionSettings, options);
// 配置 HTTPS 证书指纹
if (!string.IsNullOrEmpty(options.Fingerprint))
connectionSettings.CertificateFingerprint(options.Fingerprint);
return new ElasticsearchClient(connectionSettings);
}
/// <summary>
/// 配置认证(通用逻辑)
/// </summary>
private static void ConfigureAuthentication(ElasticsearchClientSettings settings, ElasticSearchOptions options)
{
switch (options.AuthType)
{
case ElasticSearchAuthTypeEnum.Basic:
settings.Authentication(new BasicAuthentication(options.User, options.Password));
break;
case ElasticSearchAuthTypeEnum.ApiKey:
settings.Authentication(new ApiKey(options.ApiKey));
break;
case ElasticSearchAuthTypeEnum.Base64ApiKey:
settings.Authentication(new Base64ApiKey(options.Base64ApiKey));
break;
case ElasticSearchAuthTypeEnum.None:
// 无需认证
break;
default:
throw new ArgumentOutOfRangeException(nameof(options.AuthType));
}
}
}

@ -0,0 +1,41 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Elastic.Clients.Elasticsearch;
namespace Admin.NET.Core.ElasticSearch;
/// <summary>
/// ES服务注册
/// </summary>
public static class ElasticSearchSetup
{
/// <summary>
/// 注册所有ES客户端日志+业务)
/// </summary>
public static void AddElasticSearchClients(this IServiceCollection services)
{
// 1. 创建客户端字典(枚举→客户端实例)
var clients = new Dictionary<EsClientTypeEnum, ElasticsearchClient>();
// 2. 注册日志客户端
var loggingClient = ElasticSearchClientFactory.CreateClient<ElasticSearchOptions>(configPath: "ElasticSearch:Logging");
if (loggingClient != null)
{
clients[EsClientTypeEnum.Logging] = loggingClient;
}
// 3. 注册业务客户端
var businessClient = ElasticSearchClientFactory.CreateClient<ElasticSearchOptions>(configPath: "ElasticSearch:Business");
if (businessClient != null)
{
clients[EsClientTypeEnum.Business] = businessClient;
}
// 4. 将客户端容器注册为单例(全局唯一)
services.AddSingleton(new ElasticSearchClientContainer(clients));
}
}

@ -0,0 +1,203 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 框架实体基类Id
/// </summary>
public abstract class EntityBaseId
{
/// <summary>
/// 雪花Id
/// </summary>
[SugarColumn(ColumnName = "Id", ColumnDescription = "主键Id", IsPrimaryKey = true, IsIdentity = false)]
public virtual long Id { get; set; }
}
/// <summary>
/// 框架实体基类
/// </summary>
[SugarIndex("index_{table}_CT", nameof(CreateTime), OrderByType.Asc)]
public abstract class EntityBase : EntityBaseId
{
/// <summary>
/// 创建时间
/// </summary>
[SugarColumn(ColumnDescription = "创建时间", IsNullable = true, IsOnlyIgnoreUpdate = true)]
public virtual DateTime CreateTime { get; set; }
/// <summary>
/// 更新时间
/// </summary>
[SugarColumn(ColumnDescription = "更新时间")]
public virtual DateTime? UpdateTime { get; set; }
/// <summary>
/// 创建者Id
/// </summary>
[OwnerUser]
[SugarColumn(ColumnDescription = "创建者Id", IsOnlyIgnoreUpdate = true)]
public virtual long? CreateUserId { get; set; }
///// <summary>
///// 创建者
///// </summary>
//[Newtonsoft.Json.JsonIgnore]
//[System.Text.Json.Serialization.JsonIgnore]
//[Navigate(NavigateType.OneToOne, nameof(CreateUserId))]
//public virtual SysUser CreateUser { get; set; }
/// <summary>
/// 创建者姓名
/// </summary>
[SugarColumn(ColumnDescription = "创建者姓名", Length = 64, IsOnlyIgnoreUpdate = true)]
public virtual string? CreateUserName { get; set; }
/// <summary>
/// 修改者Id
/// </summary>
[SugarColumn(ColumnDescription = "修改者Id")]
public virtual long? UpdateUserId { get; set; }
///// <summary>
///// 修改者
///// </summary>
//[Newtonsoft.Json.JsonIgnore]
//[System.Text.Json.Serialization.JsonIgnore]
//[Navigate(NavigateType.OneToOne, nameof(UpdateUserId))]
//public virtual SysUser UpdateUser { get; set; }
/// <summary>
/// 修改者姓名
/// </summary>
[SugarColumn(ColumnDescription = "修改者姓名", Length = 64)]
public virtual string? UpdateUserName { get; set; }
}
/// <summary>
/// 框架实体基类(删除标志)
/// </summary>
[SugarIndex("index_{table}_D", nameof(IsDelete), OrderByType.Asc)]
[SugarIndex("index_{table}_DT", nameof(DeleteTime), OrderByType.Asc)]
public abstract class EntityBaseDel : EntityBase, IDeletedFilter
{
/// <summary>
/// 软删除
/// </summary>
[SugarColumn(ColumnDescription = "软删除")]
public virtual bool IsDelete { get; set; } = false;
/// <summary>
/// 软删除时间
/// </summary>
[SugarColumn(ColumnDescription = "软删除时间")]
public virtual DateTime? DeleteTime { get; set; }
}
/// <summary>
/// 机构实体基类(数据权限)
/// </summary>
public abstract class EntityBaseOrg : EntityBase, IOrgIdFilter
{
/// <summary>
/// 机构Id
/// </summary>
[SugarColumn(ColumnDescription = "机构Id", IsNullable = true)]
public virtual long OrgId { get; set; }
///// <summary>
///// 创建者部门Id
///// </summary>
//[SugarColumn(ColumnDescription = "创建者部门Id", IsOnlyIgnoreUpdate = true)]
//public virtual long? CreateOrgId { get; set; }
///// <summary>
///// 创建者部门
///// </summary>
//[Newtonsoft.Json.JsonIgnore]
//[System.Text.Json.Serialization.JsonIgnore]
//[Navigate(NavigateType.OneToOne, nameof(CreateOrgId))]
//public virtual SysOrg CreateOrg { get; set; }
///// <summary>
///// 创建者部门名称
///// </summary>
//[SugarColumn(ColumnDescription = "创建者部门名称", Length = 64, IsOnlyIgnoreUpdate = true)]
//public virtual string? CreateOrgName { get; set; }
}
/// <summary>
/// 机构实体基类(数据权限、删除标志)
/// </summary>
public abstract class EntityBaseOrgDel : EntityBaseDel, IOrgIdFilter
{
/// <summary>
/// 机构Id
/// </summary>
[SugarColumn(ColumnDescription = "机构Id", IsNullable = true)]
public virtual long OrgId { get; set; }
}
/// <summary>
/// 租户实体基类
/// </summary>
public abstract class EntityBaseTenant : EntityBase, ITenantIdFilter
{
/// <summary>
/// 租户Id
/// </summary>
[SugarColumn(ColumnDescription = "租户Id", IsOnlyIgnoreUpdate = true)]
public virtual long? TenantId { get; set; }
}
/// <summary>
/// 租户实体基类(删除标志)
/// </summary>
public abstract class EntityBaseTenantDel : EntityBaseDel, ITenantIdFilter
{
/// <summary>
/// 租户Id
/// </summary>
[SugarColumn(ColumnDescription = "租户Id", IsOnlyIgnoreUpdate = true)]
public virtual long? TenantId { get; set; }
}
/// <summary>
/// 租户实体基类Id
/// </summary>
public abstract class EntityBaseTenantId : EntityBaseId, ITenantIdFilter
{
/// <summary>
/// 租户Id
/// </summary>
[SugarColumn(ColumnDescription = "租户Id", IsOnlyIgnoreUpdate = true)]
public virtual long? TenantId { get; set; }
}
/// <summary>
/// 租户机构实体基类(数据权限)
/// </summary>
public abstract class EntityBaseTenantOrg : EntityBaseOrg, ITenantIdFilter
{
/// <summary>
/// 租户Id
/// </summary>
[SugarColumn(ColumnDescription = "租户Id", IsOnlyIgnoreUpdate = true)]
public virtual long? TenantId { get; set; }
}
/// <summary>
/// 租户机构实体基类(数据权限、删除标志)
/// </summary>
public abstract class EntityBaseTenantOrgDel : EntityBaseOrgDel, ITenantIdFilter
{
/// <summary>
/// 租户Id
/// </summary>
[SugarColumn(ColumnDescription = "租户Id", IsOnlyIgnoreUpdate = true)]
public virtual long? TenantId { get; set; }
}

@ -0,0 +1,40 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 假删除接口过滤器
/// </summary>
public interface IDeletedFilter
{
/// <summary>
/// 软删除
/// </summary>
bool IsDelete { get; set; }
}
/// <summary>
/// 租户Id接口过滤器
/// </summary>
public interface ITenantIdFilter
{
/// <summary>
/// 租户Id
/// </summary>
long? TenantId { get; set; }
}
/// <summary>
/// 机构Id接口过滤器
/// </summary>
public interface IOrgIdFilter
{
/// <summary>
/// 机构Id
/// </summary>
long OrgId { get; set; }
}

@ -0,0 +1,149 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 支付宝授权记录表
/// </summary>
[SugarTable(null, "支付宝授权记录表")]
[SysTable]
[SugarIndex("index_{table}_U", nameof(UserId), OrderByType.Asc)]
[SugarIndex("index_{table}_T", nameof(OpenId), OrderByType.Asc)]
public class SysAlipayAuthInfo : EntityBase
{
/// <summary>
/// 商户AppId
/// </summary>
[SugarColumn(ColumnDescription = "商户AppId", Length = 64)]
public string? AppId { get; set; }
/// <summary>
/// 开放ID
/// </summary>
[SugarColumn(ColumnDescription = "开放ID", Length = 64)]
public string? OpenId { get; set; }
/// <summary>
/// 用户ID
/// </summary>
[SugarColumn(ColumnDescription = "用户ID", Length = 64)]
public string? UserId { get; set; }
/// <summary>
/// 性别
/// </summary>
[SugarColumn(ColumnDescription = "性别", Length = 8)]
public GenderEnum Gender { get; set; }
/// <summary>
/// 年龄
/// </summary>
[SugarColumn(ColumnDescription = "年龄", Length = 16)]
public int Age { get; set; }
/// <summary>
/// 手机号
/// </summary>
[SugarColumn(ColumnDescription = "手机号", Length = 32)]
public string Mobile { get; set; }
/// <summary>
/// 显示名称
/// </summary>
[SugarColumn(ColumnDescription = "显示名称", Length = 128)]
public string DisplayName { get; set; }
/// <summary>
/// 昵称
/// </summary>
[SugarColumn(ColumnDescription = "昵称", Length = 64)]
public string NickName { get; set; }
/// <summary>
/// 用户名
/// </summary>
[SugarColumn(ColumnDescription = "用户名", Length = 64)]
public string UserName { get; set; }
/// <summary>
/// 头像
/// </summary>
[SugarColumn(ColumnDescription = "头像", Length = 512)]
public string? Avatar { get; set; }
/// <summary>
/// 邮箱
/// </summary>
[SugarColumn(ColumnDescription = "邮箱", Length = 128)]
public string? Email { get; set; }
/// <summary>
/// 用户民族
/// </summary>
[SugarColumn(ColumnDescription = "用户民族", Length = 32)]
public string? UserNation { get; set; }
/// <summary>
/// 淘宝ID
/// </summary>
[SugarColumn(ColumnDescription = "淘宝ID", Length = 64)]
public string? TaobaoId { get; set; }
/// <summary>
/// 电话
/// </summary>
[SugarColumn(ColumnDescription = "电话", Length = 32)]
public string? Phone { get; set; }
/// <summary>
/// 生日
/// </summary>
[SugarColumn(ColumnDescription = "生日", Length = 32)]
public string? PersonBirthday { get; set; }
/// <summary>
/// 职业
/// </summary>
[SugarColumn(ColumnDescription = "职业", Length = 64)]
public string? Profession { get; set; }
/// <summary>
/// 省份
/// </summary>
[SugarColumn(ColumnDescription = "省份", Length = 64)]
public string? Province { get; set; }
/// <summary>
/// 用户状态
/// </summary>
[SugarColumn(ColumnDescription = "用户状态", Length = 32)]
public string? UserStatus { get; set; }
/// <summary>
/// 学历
/// </summary>
[SugarColumn(ColumnDescription = "学历", Length = 32)]
public string? Degree { get; set; }
/// <summary>
/// 用户类型
/// </summary>
[SugarColumn(ColumnDescription = "用户类型", Length = 32)]
public string? UserType { get; set; }
/// <summary>
/// 邮编
/// </summary>
[SugarColumn(ColumnDescription = "邮编", Length = 16)]
public string? Zip { get; set; }
/// <summary>
/// 地址
/// </summary>
[SugarColumn(ColumnDescription = "地址", Length = 256)]
public string? Address { get; set; }
}

@ -0,0 +1,108 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 支付宝交易记录表
/// </summary>
[SugarTable(null, "支付宝交易记录表")]
[SysTable]
[SugarIndex("index_{table}_U", nameof(UserId), OrderByType.Asc)]
[SugarIndex("index_{table}_T", nameof(TradeNo), OrderByType.Asc)]
[SugarIndex("index_{table}_O", nameof(OutTradeNo), OrderByType.Asc)]
public class SysAlipayTransaction : EntityBase
{
/// <summary>
/// 用户Id
/// </summary>
[SugarColumn(ColumnDescription = "用户Id", Length = 64)]
public long UserId { get; set; }
/// <summary>
/// 交易号
/// </summary>
[SugarColumn(ColumnDescription = "交易号", Length = 64)]
public string? TradeNo { get; set; }
/// <summary>
/// 商户订单号
/// </summary>
[SugarColumn(ColumnDescription = "商户订单号", Length = 64)]
public string OutTradeNo { get; set; }
/// <summary>
/// 交易金额
/// </summary>
[SugarColumn(ColumnDescription = "交易金额", Length = 20)]
public decimal TotalAmount { get; set; }
/// <summary>
/// 交易状态
/// </summary>
[SugarColumn(ColumnDescription = "交易状态", Length = 32)]
public string TradeStatus { get; set; }
/// <summary>
/// 交易完成时间
/// </summary>
[SugarColumn(ColumnDescription = "交易完成时间")]
public DateTime? FinishTime { get; set; }
/// <summary>
/// 交易标题
/// </summary>
[SugarColumn(ColumnDescription = "交易标题", Length = 256)]
public string Subject { get; set; }
/// <summary>
/// 交易描述
/// </summary>
[SugarColumn(ColumnDescription = "交易描述", Length = 512)]
public string? Body { get; set; }
/// <summary>
/// 买家支付宝账号
/// </summary>
[SugarColumn(ColumnDescription = "买家支付宝账号", Length = 128)]
public string? BuyerLogonId { get; set; }
/// <summary>
/// 买家支付宝用户ID
/// </summary>
[SugarColumn(ColumnDescription = "买家支付宝用户ID", Length = 32)]
public string? BuyerUserId { get; set; }
/// <summary>
/// 卖家支付宝用户ID
/// </summary>
[SugarColumn(ColumnDescription = "卖家支付宝用户ID", Length = 32)]
public string? SellerUserId { get; set; }
/// <summary>
/// 商户AppId
/// </summary>
[SugarColumn(ColumnDescription = "商户AppId", Length = 64)]
public string? AppId { get; set; }
/// <summary>
/// 交易扩展信息
/// </summary>
[SugarColumn(ColumnDescription = "交易扩展信息", Length = 1024)]
public string? ExtendInfo { get; set; }
/// <summary>
/// 交易异常信息
/// </summary>
[SugarColumn(ColumnDescription = "交易扩展信息", Length = 1024)]
public string? ErrorInfo { get; set; }
/// <summary>
/// 交易备注
/// </summary>
[SugarColumn(ColumnDescription = "交易备注", Length = 512)]
public string? Remark { get; set; }
}

@ -0,0 +1,159 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 代码生成表
/// </summary>
[SugarTable(null, "代码生成表")]
[SysTable]
[SugarIndex("index_{table}_B", nameof(BusName), OrderByType.Asc)]
[SugarIndex("index_{table}_T", nameof(TableName), OrderByType.Asc)]
public partial class SysCodeGen : EntityBase
{
/// <summary>
/// 作者姓名
/// </summary>
[SugarColumn(ColumnDescription = "作者姓名", Length = 32)]
[MaxLength(32)]
public string? AuthorName { get; set; }
/// <summary>
/// 是否移除表前缀
/// </summary>
[SugarColumn(ColumnDescription = "是否移除表前缀", Length = 8)]
[MaxLength(8)]
public string? TablePrefix { get; set; }
/// <summary>
/// 生成方式
/// </summary>
[SugarColumn(ColumnDescription = "生成方式", Length = 32)]
[MaxLength(32)]
public string? GenerateType { get; set; }
/// <summary>
/// 库定位器名
/// </summary>
[SugarColumn(ColumnDescription = "库定位器名", Length = 64)]
[MaxLength(64)]
public string? ConfigId { get; set; }
/// <summary>
/// 库名
/// </summary>
[SugarColumn(IsIgnore = true)]
public string DbNickName
{
get
{
try
{
var dbOptions = App.GetConfig<DbConnectionOptions>("DbConnection", true);
var config = dbOptions.ConnectionConfigs.FirstOrDefault(m => m.ConfigId.ToString() == ConfigId);
return config.DbNickName;
}
catch (Exception)
{
return null;
}
}
}
/// <summary>
/// 数据库名(保留字段)
/// </summary>
[SugarColumn(ColumnDescription = "数据库库名", Length = 64)]
[MaxLength(64)]
public string? DbName { get; set; }
/// <summary>
/// 数据库类型
/// </summary>
[SugarColumn(ColumnDescription = "数据库类型", Length = 64)]
[MaxLength(64)]
public string? DbType { get; set; }
/// <summary>
/// 数据库链接
/// </summary>
[SugarColumn(ColumnDescription = "数据库链接", Length = 256)]
[MaxLength(256)]
public string? ConnectionString { get; set; }
/// <summary>
/// 数据库表名
/// </summary>
[SugarColumn(ColumnDescription = "数据库表名", Length = 128)]
[MaxLength(128)]
public string? TableName { get; set; }
/// <summary>
/// 命名空间
/// </summary>
[SugarColumn(ColumnDescription = "命名空间", Length = 128)]
[MaxLength(128)]
public string? NameSpace { get; set; }
/// <summary>
/// 业务名
/// </summary>
[SugarColumn(ColumnDescription = "业务名", Length = 128)]
[MaxLength(128)]
public string? BusName { get; set; }
/// <summary>
/// 表唯一字段配置
/// </summary>
[SugarColumn(ColumnDescription = "表唯一字段配置", Length = 512)]
[MaxLength(128)]
public string? TableUniqueConfig { get; set; }
/// <summary>
/// 是否生成菜单
/// </summary>
[SugarColumn(ColumnDescription = "是否生成菜单")]
public bool GenerateMenu { get; set; } = true;
/// <summary>
/// 菜单图标
/// </summary>
[SugarColumn(ColumnDescription = "菜单图标", Length = 32)]
public string? MenuIcon { get; set; } = "ele-Menu";
/// <summary>
/// 菜单编码
/// </summary>
[SugarColumn(ColumnDescription = "菜单编码")]
public long? MenuPid { get; set; }
/// <summary>
/// 页面目录
/// </summary>
[SugarColumn(ColumnDescription = "页面目录", Length = 32)]
public string? PagePath { get; set; }
/// <summary>
/// 支持打印类型
/// </summary>
[SugarColumn(ColumnDescription = "支持打印类型", Length = 32)]
[MaxLength(32)]
public string? PrintType { get; set; }
/// <summary>
/// 打印模版名称
/// </summary>
[SugarColumn(ColumnDescription = "打印模版名称", Length = 32)]
[MaxLength(32)]
public string? PrintName { get; set; }
/// <summary>
/// 表唯一字段列表
/// </summary>
[SugarColumn(IsIgnore = true)]
public virtual List<TableUniqueConfigItem> TableUniqueList => string.IsNullOrWhiteSpace(TableUniqueConfig) ? null : JSON.Deserialize<List<TableUniqueConfigItem>>(TableUniqueConfig);
}

@ -0,0 +1,207 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 代码生成字段配置表
/// </summary>
[SugarTable(null, "代码生成字段配置表")]
[SysTable]
public partial class SysCodeGenConfig : EntityBase
{
/// <summary>
/// 代码生成主表Id
/// </summary>
[SugarColumn(ColumnDescription = "主表Id")]
public long CodeGenId { get; set; }
/// <summary>
/// 数据库字段名
/// </summary>
[SugarColumn(ColumnDescription = "字段名称", Length = 128)]
[Required, MaxLength(128)]
public virtual string ColumnName { get; set; }
/// <summary>
/// 主键
/// </summary>
[SugarColumn(ColumnDescription = "主键", Length = 8)]
[MaxLength(8)]
public string? ColumnKey { get; set; }
/// <summary>
/// 实体属性名
/// </summary>
[SugarColumn(ColumnDescription = "属性名称", Length = 128)]
[Required, MaxLength(128)]
public virtual string PropertyName { get; set; }
/// <summary>
/// 字段数据长度
/// </summary>
[SugarColumn(ColumnDescription = "字段数据长度", DefaultValue = "0")]
public int ColumnLength { get; set; }
/// <summary>
/// 字段描述
/// </summary>
[SugarColumn(ColumnDescription = "字段描述", Length = 128)]
[MaxLength(128)]
public string? ColumnComment { get; set; }
/// <summary>
/// 数据库中类型(物理类型)
/// </summary>
[SugarColumn(ColumnDescription = "数据库中类型", Length = 64)]
[MaxLength(64)]
public string? DataType { get; set; }
/// <summary>
/// .NET数据类型
/// </summary>
[SugarColumn(ColumnDescription = "NET数据类型", Length = 64)]
[MaxLength(64)]
public string? NetType { get; set; }
/// <summary>
/// 字段数据默认值
/// </summary>
[SugarColumn(ColumnDescription = "默认值")]
public string? DefaultValue { get; set; }
/// <summary>
/// 作用类型(字典)
/// </summary>
[SugarColumn(ColumnDescription = "作用类型", Length = 64)]
[MaxLength(64)]
public string? EffectType { get; set; }
/// <summary>
/// 外键库标识
/// </summary>
[SugarColumn(ColumnDescription = "外键库标识", Length = 20)]
[MaxLength(20)]
public string? FkConfigId { get; set; }
/// <summary>
/// 外键实体名称
/// </summary>
[SugarColumn(ColumnDescription = "外键实体名称", Length = 64)]
[MaxLength(64)]
public string? FkEntityName { get; set; }
/// <summary>
/// 外键表名称
/// </summary>
[SugarColumn(ColumnDescription = "外键表名称", Length = 128)]
[MaxLength(128)]
public string? FkTableName { get; set; }
/// <summary>
/// 外键显示字段
/// </summary>
[SugarColumn(ColumnDescription = "外键显示字段", Length = 64)]
[MaxLength(64)]
public string? FkDisplayColumns { get; set; }
/// <summary>
/// 外键链接字段
/// </summary>
[SugarColumn(ColumnDescription = "外键链接字段", Length = 64)]
[MaxLength(64)]
public string? FkLinkColumnName { get; set; }
/// <summary>
/// 外键显示字段.NET类型
/// </summary>
[SugarColumn(ColumnDescription = "外键显示字段.NET类型", Length = 64)]
[MaxLength(64)]
public string? FkColumnNetType { get; set; }
/// <summary>
/// 父级字段
/// </summary>
[SugarColumn(ColumnDescription = "父级字段", Length = 128)]
[MaxLength(128)]
public string? PidColumn { get; set; }
/// <summary>
/// 字典编码
/// </summary>
[SugarColumn(ColumnDescription = "字典编码", Length = 64)]
[MaxLength(64)]
public string? DictTypeCode { get; set; }
/// <summary>
/// 查询方式
/// </summary>
[SugarColumn(ColumnDescription = "查询方式", Length = 16)]
[MaxLength(16)]
public string? QueryType { get; set; }
/// <summary>
/// 是否是查询条件
/// </summary>
[SugarColumn(ColumnDescription = "是否是查询条件", Length = 8)]
[MaxLength(8)]
public string? WhetherQuery { get; set; }
/// <summary>
/// 列表是否缩进(字典)
/// </summary>
[SugarColumn(ColumnDescription = "列表是否缩进", Length = 8)]
[MaxLength(8)]
public string? WhetherRetract { get; set; }
/// <summary>
/// 是否必填(字典)
/// </summary>
[SugarColumn(ColumnDescription = "是否必填", Length = 8)]
[MaxLength(8)]
public string? WhetherRequired { get; set; }
/// <summary>
/// 是否可排序(字典)
/// </summary>
[SugarColumn(ColumnDescription = "是否可排序", Length = 8)]
[MaxLength(8)]
public string? WhetherSortable { get; set; }
/// <summary>
/// 列表显示
/// </summary>
[SugarColumn(ColumnDescription = "列表显示", Length = 8)]
[MaxLength(8)]
public string? WhetherTable { get; set; }
/// <summary>
/// 增改
/// </summary>
[SugarColumn(ColumnDescription = "增改", Length = 8)]
[MaxLength(8)]
public string? WhetherAddUpdate { get; set; }
/// <summary>
/// 导入
/// </summary>
[SugarColumn(ColumnDescription = "导入", Length = 8)]
[MaxLength(8)]
public string? WhetherImport { get; set; }
/// <summary>
/// 是否通用字段
/// </summary>
[SugarColumn(ColumnDescription = "是否通用字段", Length = 8)]
[MaxLength(8)]
public string? WhetherCommon { get; set; }
/// <summary>
/// 排序
/// </summary>
[SugarColumn(ColumnDescription = "排序")]
public int OrderNo { get; set; } = 100;
}

@ -0,0 +1,65 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统配置参数表
/// </summary>
[SugarTable(null, "系统配置参数表")]
[SysTable]
[SugarIndex("index_{table}_N", nameof(Name), OrderByType.Asc)]
[SugarIndex("index_{table}_C", nameof(Code), OrderByType.Asc, IsUnique = true)]
public partial class SysConfig : EntityBase
{
/// <summary>
/// 名称
/// </summary>
[SugarColumn(ColumnDescription = "名称", Length = 64)]
[Required, MaxLength(64)]
public virtual string Name { get; set; }
/// <summary>
/// 编码
/// </summary>
[SugarColumn(ColumnDescription = "编码", Length = 64)]
[MaxLength(64)]
public string? Code { get; set; }
/// <summary>
/// 参数值
/// </summary>
[SugarColumn(ColumnDescription = "参数值", Length = 512)]
[MaxLength(512)]
[IgnoreUpdateSeedColumn]
public string? Value { get; set; }
/// <summary>
/// 是否是内置参数Y-是N-否)
/// </summary>
[SugarColumn(ColumnDescription = "是否是内置参数", DefaultValue = "1")]
public YesNoEnum SysFlag { get; set; } = YesNoEnum.Y;
/// <summary>
/// 分组编码
/// </summary>
[SugarColumn(ColumnDescription = "分组编码", Length = 64)]
[MaxLength(64)]
public string? GroupCode { get; set; }
/// <summary>
/// 排序
/// </summary>
[SugarColumn(ColumnDescription = "排序", DefaultValue = "100")]
public int OrderNo { get; set; } = 100;
/// <summary>
/// 备注
/// </summary>
[SugarColumn(ColumnDescription = "备注", Length = 256)]
[MaxLength(256)]
public string? Remark { get; set; }
}

@ -0,0 +1,105 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统字典值表
/// </summary>
[SugarTable(null, "系统字典值表")]
[SysTable]
[SugarIndex("index_{table}_TV", nameof(DictTypeId), OrderByType.Asc, nameof(Value), OrderByType.Asc, IsUnique = true)]
public partial class SysDictData : EntityBase
{
/// <summary>
/// 字典类型Id
/// </summary>
[SugarColumn(ColumnDescription = "字典类型Id")]
public long DictTypeId { get; set; }
/// <summary>
/// 字典类型
/// </summary>
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
[Navigate(NavigateType.OneToOne, nameof(DictTypeId))]
public SysDictType DictType { get; set; }
/// <summary>
/// 显示文本
/// </summary>
[SugarColumn(ColumnDescription = "显示文本", Length = 256)]
[Required, MaxLength(256)]
public virtual string Label { get; set; }
/// <summary>
/// 值
/// </summary>
[SugarColumn(ColumnDescription = "值", Length = 256)]
[Required, MaxLength(256)]
public virtual string Value { get; set; }
/// <summary>
/// 编码
/// </summary>
/// <remarks>
/// </remarks>
[SugarColumn(ColumnDescription = "编码", Length = 256)]
public virtual string? Code { get; set; }
/// <summary>
/// 名称
/// </summary>
[SugarColumn(ColumnDescription = "名称", Length = 256)]
[MaxLength(256)]
public virtual string? Name { get; set; }
/// <summary>
/// 显示样式-标签颜色
/// </summary>
[SugarColumn(ColumnDescription = "显示样式-标签颜色", Length = 16)]
[MaxLength(16)]
public string? TagType { get; set; }
/// <summary>
/// 显示样式-Style(控制显示样式)
/// </summary>
[SugarColumn(ColumnDescription = "显示样式-Style", Length = 512)]
[MaxLength(512)]
public string? StyleSetting { get; set; }
/// <summary>
/// 显示样式-Class(控制显示样式)
/// </summary>
[SugarColumn(ColumnDescription = "显示样式-Class", Length = 512)]
[MaxLength(512)]
public string? ClassSetting { get; set; }
/// <summary>
/// 排序
/// </summary>
[SugarColumn(ColumnDescription = "排序", DefaultValue = "100")]
public int OrderNo { get; set; } = 100;
/// <summary>
/// 备注
/// </summary>
[SugarColumn(ColumnDescription = "备注", Length = 2048)]
[MaxLength(2048)]
public string? Remark { get; set; }
/// <summary>
/// 拓展数据(保存业务功能的配置项)
/// </summary>
[SugarColumn(ColumnDescription = "拓展数据(保存业务功能的配置项)", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? ExtData { get; set; }
/// <summary>
/// 状态
/// </summary>
[SugarColumn(ColumnDescription = "状态", DefaultValue = "1")]
public StatusEnum Status { get; set; } = StatusEnum.Enable;
}

@ -0,0 +1,22 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统租户字典值表
/// </summary>
[SugarTable(null, "系统租户字典值表")]
[SysTable]
[SugarIndex("index_{table}_TV", nameof(DictTypeId), OrderByType.Asc, nameof(Value), OrderByType.Asc)]
public partial class SysDictDataTenant : SysDictData, ITenantIdFilter
{
/// <summary>
/// 租户Id
/// </summary>
[SugarColumn(ColumnDescription = "租户Id", IsOnlyIgnoreUpdate = true)]
public virtual long? TenantId { get; set; }
}

@ -0,0 +1,68 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统字典类型表
/// </summary>
[SugarTable(null, "系统字典类型表")]
[SysTable]
[SugarIndex("index_{table}_N", nameof(Name), OrderByType.Asc)]
[SugarIndex("index_{table}_C", nameof(Code), OrderByType.Asc)]
public partial class SysDictType : EntityBase
{
/// <summary>
/// 名称
/// </summary>
[SugarColumn(ColumnDescription = "名称", Length = 64)]
[Required, MaxLength(64)]
public virtual string Name { get; set; }
/// <summary>
/// 编码
/// </summary>
[SugarColumn(ColumnDescription = "编码", Length = 64)]
[Required, MaxLength(64)]
public virtual string Code { get; set; }
/// <summary>
/// 排序
/// </summary>
[SugarColumn(ColumnDescription = "排序", DefaultValue = "100")]
public int OrderNo { get; set; } = 100;
/// <summary>
/// 备注
/// </summary>
[SugarColumn(ColumnDescription = "备注", Length = 256)]
[MaxLength(256)]
public string? Remark { get; set; }
/// <summary>
/// 状态
/// </summary>
[SugarColumn(ColumnDescription = "状态", DefaultValue = "1")]
public StatusEnum Status { get; set; } = StatusEnum.Enable;
/// <summary>
/// 是否是内置字典Y-是N-否)
/// </summary>
[SugarColumn(ColumnDescription = "是否是内置字典", DefaultValue = "1")]
public virtual YesNoEnum SysFlag { get; set; } = YesNoEnum.Y;
/// <summary>
/// 是否是租户字典Y-是N-否)
/// </summary>
[SugarColumn(ColumnDescription = "是否是租户字典", DefaultValue = "2")]
public virtual YesNoEnum IsTenant { get; set; } = YesNoEnum.N;
/// <summary>
/// 字典值集合
/// </summary>
[Navigate(NavigateType.OneToMany, nameof(SysDictData.DictTypeId))]
public List<SysDictData> Children { get; set; }
}

@ -0,0 +1,104 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统文件表
/// </summary>
[SugarTable(null, "系统文件表")]
[SysTable]
[SugarIndex("index_{table}_F", nameof(FileName), OrderByType.Asc)]
public partial class SysFile : EntityBaseTenantOrg
{
/// <summary>
/// 提供者
/// </summary>
[SugarColumn(ColumnDescription = "提供者", Length = 128)]
[MaxLength(128)]
public string? Provider { get; set; }
/// <summary>
/// 仓储名称
/// </summary>
[SugarColumn(ColumnDescription = "仓储名称", Length = 128)]
[MaxLength(128)]
public string? BucketName { get; set; }
/// <summary>
/// 文件名称(源文件名)
/// </summary>
[SugarColumn(ColumnDescription = "文件名称", Length = 128)]
[MaxLength(128)]
public string? FileName { get; set; }
/// <summary>
/// 文件后缀
/// </summary>
[SugarColumn(ColumnDescription = "文件后缀", Length = 16)]
[MaxLength(16)]
public string? Suffix { get; set; }
/// <summary>
/// 存储路径
/// </summary>
[SugarColumn(ColumnDescription = "存储路径", Length = 512)]
[MaxLength(512)]
public string? FilePath { get; set; }
/// <summary>
/// 文件大小KB
/// </summary>
[SugarColumn(ColumnDescription = "文件大小KB")]
public long SizeKb { get; set; }
/// <summary>
/// 文件大小信息-计算后的
/// </summary>
[SugarColumn(ColumnDescription = "文件大小信息", Length = 64)]
[MaxLength(64)]
public string? SizeInfo { get; set; }
/// <summary>
/// 外链地址-OSS上传后生成外链地址方便前端预览
/// </summary>
[SugarColumn(ColumnDescription = "外链地址", Length = 512)]
[MaxLength(512)]
public string? Url { get; set; }
/// <summary>
/// 文件MD5
/// </summary>
[SugarColumn(ColumnDescription = "文件MD5", Length = 128)]
[MaxLength(128)]
public string? FileMd5 { get; set; }
/// <summary>
/// 文件类别
/// </summary>
[SugarColumn(ColumnDescription = "文件类别", Length = 128)]
[MaxLength(128)]
public virtual string? FileType { get; set; }
/// <summary>
/// 文件别名
/// </summary>
[SugarColumn(ColumnDescription = "文件别名", Length = 128)]
[MaxLength(128)]
public string? FileAlias { get; set; }
/// <summary>
/// 是否公开
/// </summary>
[SugarColumn(ColumnDescription = "是否公开")]
public virtual bool IsPublic { get; set; } = false;
/// <summary>
/// 业务数据Id
/// </summary>
[SugarColumn(ColumnDescription = "业务数据Id")]
public long? DataId { get; set; }
}

@ -0,0 +1,118 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
using Newtonsoft.Json;
namespace Admin.NET.Core;
/// <summary>
/// 系统文件存储提供者表
/// </summary>
[SugarTable(null, "系统文件存储提供者表")]
[SysTable]
[SugarIndex("index_{table}_BucketName", nameof(BucketName), OrderByType.Asc)]
[SugarIndex("index_{table}_IsEnable", nameof(IsEnable), OrderByType.Desc)]
[SugarIndex("index_{table}_IsDefault", nameof(IsDefault), OrderByType.Desc)]
public partial class SysFileProvider : EntityBaseTenant
{
/// <summary>
/// 存储提供者Minio QCloudAliyun 等等)
/// </summary>
[SugarColumn(ColumnDescription = "存储提供者", Length = 16)]
[Required, MaxLength(16)]
public virtual string Provider { get; set; }
/// <summary>
/// 存储桶名称
/// </summary>
[SugarColumn(ColumnDescription = "存储桶名称", Length = 32)]
[Required, MaxLength(32)]
public virtual string BucketName { get; set; }
/// <summary>
/// 访问密钥 (填入 阿里云Aliyun/Minio的 AccessKey腾讯云QCloud: 的 SecretId
/// </summary>
[SugarColumn(ColumnDescription = "访问密钥", Length = 128)]
[MaxLength(128)]
public virtual string? AccessKey { get; set; }
/// <summary>
/// 密钥
/// </summary>
[SugarColumn(ColumnDescription = "密钥", Length = 128)]
[MaxLength(128)]
public virtual string? SecretKey { get; set; }
/// <summary>
/// 地域
/// </summary>
[SugarColumn(ColumnDescription = "地域", Length = 64)]
[MaxLength(64)]
public virtual string? Region { get; set; }
/// <summary>
/// 端点地址(填入 阿里云Aliyun/Minio的 endpoint/Api address腾讯云QCloud: 的 AppId
/// </summary>
[SugarColumn(ColumnDescription = "端点地址", Length = 256)]
[MaxLength(256)]
public virtual string? Endpoint { get; set; }
/// <summary>
/// 是否启用HTTPS
/// </summary>
[SugarColumn(ColumnDescription = "是否启用HTTPS")]
public virtual bool? IsEnableHttps { get; set; } = true;
/// <summary>
/// 是否启用缓存
/// </summary>
[SugarColumn(ColumnDescription = "是否启用缓存")]
public virtual bool? IsEnableCache { get; set; } = true;
/// <summary>
/// 是否启用
/// </summary>
[SugarColumn(ColumnDescription = "是否启用")]
public virtual bool? IsEnable { get; set; } = true;
/// <summary>
/// 是否默认提供者
/// </summary>
[SugarColumn(ColumnDescription = "是否默认提供者")]
public virtual bool? IsDefault { get; set; } = false;
/// <summary>
/// 自定义域名
/// </summary>
[SugarColumn(ColumnDescription = "自定义域名", Length = 256)]
[MaxLength(256)]
public virtual string? SinceDomain { get; set; }
/// <summary>
/// 排序号
/// </summary>
[SugarColumn(ColumnDescription = "排序号")]
public virtual int? OrderNo { get; set; } = 100;
/// <summary>
/// 备注
/// </summary>
[SugarColumn(ColumnDescription = "备注", Length = 512)]
[MaxLength(512)]
public virtual string? Remark { get; set; }
/// <summary>
/// 获取显示名称
/// </summary>
[SugarColumn(IsIgnore = true)]
public virtual string DisplayName => $"{Provider}-{BucketName}";
/// <summary>
/// 获取配置键名
/// </summary>
[SugarColumn(IsIgnore = true)]
public virtual string ConfigKey => $"{Provider}_{BucketName}_{Id}";
}

@ -0,0 +1,41 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统作业集群表
/// </summary>
[SugarTable(null, "系统作业集群表")]
[SysTable]
public partial class SysJobCluster : EntityBaseId
{
/// <summary>
/// 作业集群Id
/// </summary>
[SugarColumn(ColumnDescription = "作业集群Id", Length = 64)]
[Required, MaxLength(64)]
public virtual string ClusterId { get; set; }
/// <summary>
/// 描述信息
/// </summary>
[SugarColumn(ColumnDescription = "描述信息", Length = 128)]
[MaxLength(128)]
public string? Description { get; set; }
/// <summary>
/// 状态
/// </summary>
[SugarColumn(ColumnDescription = "状态")]
public ClusterStatus Status { get; set; }
/// <summary>
/// 更新时间
/// </summary>
[SugarColumn(ColumnDescription = "更新时间")]
public DateTime? UpdatedTime { get; set; }
}

@ -0,0 +1,87 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统作业信息表
/// </summary>
[SugarTable(null, "系统作业信息表")]
[SysTable]
[SugarIndex("index_{table}_J", nameof(JobId), OrderByType.Asc)]
public partial class SysJobDetail : EntityBaseId
{
/// <summary>
/// 作业Id
/// </summary>
[SugarColumn(ColumnDescription = "作业Id", Length = 64)]
[Required, MaxLength(64)]
public virtual string JobId { get; set; }
/// <summary>
/// 组名称
/// </summary>
[SugarColumn(ColumnDescription = "组名称", Length = 128)]
[MaxLength(128)]
public string? GroupName { get; set; } = "default";
/// <summary>
/// 作业类型FullName
/// </summary>
[SugarColumn(ColumnDescription = "作业类型", Length = 128)]
[MaxLength(128)]
public string? JobType { get; set; }
/// <summary>
/// 程序集Name
/// </summary>
[SugarColumn(ColumnDescription = "程序集", Length = 128)]
[MaxLength(128)]
public string? AssemblyName { get; set; }
/// <summary>
/// 描述信息
/// </summary>
[SugarColumn(ColumnDescription = "描述信息", Length = 128)]
[MaxLength(128)]
public string? Description { get; set; }
/// <summary>
/// 是否并行执行
/// </summary>
[SugarColumn(ColumnDescription = "是否并行执行")]
public bool Concurrent { get; set; } = true;
/// <summary>
/// 是否扫描特性触发器
/// </summary>
[SugarColumn(ColumnDescription = "是否扫描特性触发器", ColumnName = "annotation")]
public bool IncludeAnnotation { get; set; } = false;
/// <summary>
/// 额外数据
/// </summary>
[SugarColumn(ColumnDescription = "额外数据", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? Properties { get; set; } = "{}";
/// <summary>
/// 更新时间
/// </summary>
[SugarColumn(ColumnDescription = "更新时间")]
public DateTime? UpdatedTime { get; set; }
/// <summary>
/// 作业创建类型
/// </summary>
[SugarColumn(ColumnDescription = "作业创建类型")]
public JobCreateTypeEnum CreateType { get; set; } = JobCreateTypeEnum.BuiltIn;
/// <summary>
/// 脚本代码
/// </summary>
[SugarColumn(ColumnDescription = "脚本代码", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? ScriptCode { get; set; }
}

@ -0,0 +1,147 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统作业触发器表
/// </summary>
[SugarTable(null, "系统作业触发器表")]
[SysTable]
public partial class SysJobTrigger : EntityBaseId
{
/// <summary>
/// 触发器Id
/// </summary>
[SugarColumn(ColumnDescription = "触发器Id", Length = 64)]
[Required, MaxLength(64)]
public virtual string TriggerId { get; set; }
/// <summary>
/// 作业Id
/// </summary>
[SugarColumn(ColumnDescription = "作业Id", Length = 64)]
[Required, MaxLength(64)]
public virtual string JobId { get; set; }
/// <summary>
/// 触发器类型FullName
/// </summary>
[SugarColumn(ColumnDescription = "触发器类型", Length = 128)]
[MaxLength(128)]
public string? TriggerType { get; set; }
/// <summary>
/// 程序集Name
/// </summary>
[SugarColumn(ColumnDescription = "程序集", Length = 128)]
[MaxLength(128)]
public string? AssemblyName { get; set; } = "Furion.Pure";
/// <summary>
/// 参数
/// </summary>
[SugarColumn(ColumnDescription = "参数", Length = 128)]
[MaxLength(128)]
public string? Args { get; set; }
/// <summary>
/// 描述信息
/// </summary>
[SugarColumn(ColumnDescription = "描述信息", Length = 128)]
[MaxLength(128)]
public string? Description { get; set; }
/// <summary>
/// 状态
/// </summary>
[SugarColumn(ColumnDescription = "状态")]
public TriggerStatus Status { get; set; } = TriggerStatus.Ready;
/// <summary>
/// 起始时间
/// </summary>
[SugarColumn(ColumnDescription = "起始时间")]
public DateTime? StartTime { get; set; }
/// <summary>
/// 结束时间
/// </summary>
[SugarColumn(ColumnDescription = "结束时间")]
public DateTime? EndTime { get; set; }
/// <summary>
/// 最近运行时间
/// </summary>
[SugarColumn(ColumnDescription = "最近运行时间")]
public DateTime? LastRunTime { get; set; }
/// <summary>
/// 下一次运行时间
/// </summary>
[SugarColumn(ColumnDescription = "下一次运行时间")]
public DateTime? NextRunTime { get; set; }
/// <summary>
/// 触发次数
/// </summary>
[SugarColumn(ColumnDescription = "触发次数")]
public long NumberOfRuns { get; set; }
/// <summary>
/// 最大触发次数0:不限制n:N次
/// </summary>
[SugarColumn(ColumnDescription = "最大触发次数")]
public long MaxNumberOfRuns { get; set; }
/// <summary>
/// 出错次数
/// </summary>
[SugarColumn(ColumnDescription = "出错次数")]
public long NumberOfErrors { get; set; }
/// <summary>
/// 最大出错次数0:不限制n:N次
/// </summary>
[SugarColumn(ColumnDescription = "最大出错次数")]
public long MaxNumberOfErrors { get; set; }
/// <summary>
/// 重试次数
/// </summary>
[SugarColumn(ColumnDescription = "重试次数")]
public int NumRetries { get; set; }
/// <summary>
/// 重试间隔时间ms
/// </summary>
[SugarColumn(ColumnDescription = "重试间隔时间(ms)")]
public int RetryTimeout { get; set; } = 1000;
/// <summary>
/// 是否立即启动
/// </summary>
[SugarColumn(ColumnDescription = "是否立即启动")]
public bool StartNow { get; set; } = true;
/// <summary>
/// 是否启动时执行一次
/// </summary>
[SugarColumn(ColumnDescription = "是否启动时执行一次")]
public bool RunOnStart { get; set; } = false;
/// <summary>
/// 是否在启动时重置最大触发次数等于一次的作业
/// </summary>
[SugarColumn(ColumnDescription = "是否重置触发次数")]
public bool ResetOnlyOnce { get; set; } = true;
/// <summary>
/// 更新时间
/// </summary>
[SugarColumn(ColumnDescription = "更新时间")]
public DateTime? UpdatedTime { get; set; }
}

@ -0,0 +1,72 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统作业触发器运行记录表
/// </summary>
[SugarTable(null, "系统作业触发器运行记录表")]
[SysTable]
public partial class SysJobTriggerRecord : EntityBaseId
{
/// <summary>
/// 作业Id
/// </summary>
[SugarColumn(ColumnDescription = "作业Id", Length = 64)]
[Required, MaxLength(64)]
public virtual string JobId { get; set; }
/// <summary>
/// 触发器Id
/// </summary>
[SugarColumn(ColumnDescription = "触发器Id", Length = 64)]
[Required, MaxLength(64)]
public virtual string TriggerId { get; set; }
/// <summary>
/// 当前运行次数
/// </summary>
[SugarColumn(ColumnDescription = "当前运行次数")]
public long NumberOfRuns { get; set; }
/// <summary>
/// 最近运行时间
/// </summary>
[SugarColumn(ColumnDescription = "最近运行时间")]
public DateTime? LastRunTime { get; set; }
/// <summary>
/// 下一次运行时间
/// </summary>
[SugarColumn(ColumnDescription = "下一次运行时间")]
public DateTime? NextRunTime { get; set; }
/// <summary>
/// 触发器状态
/// </summary>
[SugarColumn(ColumnDescription = "触发器状态")]
public TriggerStatus Status { get; set; } = TriggerStatus.Ready;
/// <summary>
/// 本次执行结果
/// </summary>
[SugarColumn(ColumnDescription = "本次执行结果", Length = 128)]
[MaxLength(128)]
public string? Result { get; set; }
/// <summary>
/// 本次执行耗时
/// </summary>
[SugarColumn(ColumnDescription = "本次执行耗时")]
public long ElapsedTime { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[SugarColumn(ColumnDescription = "创建时间")]
public DateTime? CreatedTime { get; set; }
}

@ -0,0 +1,86 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
[SugarTable(null, "语言配置")]
[SysTable]
[SugarIndex("index_{table}_N", nameof(Name), OrderByType.Asc)]
[SugarIndex("index_{table}_C", nameof(Code), OrderByType.Asc)]
public class SysLang : EntityBase
{
/// <summary>
/// 语言名称
/// </summary>
[SugarColumn(ColumnDescription = "语言名称")]
public string Name { get; set; }
/// <summary>
/// 语言代码(如 zh-CN
/// </summary>
[SugarColumn(ColumnDescription = "语言代码")]
public string Code { get; set; }
/// <summary>
/// ISO 语言代码
/// </summary>
[SugarColumn(ColumnDescription = "ISO 语言代码")]
public string IsoCode { get; set; }
/// <summary>
/// URL 语言代码
/// </summary>
[SugarColumn(ColumnDescription = "URL 语言代码")]
public string UrlCode { get; set; }
/// <summary>
/// 书写方向1=从左到右2=从右到左)
/// </summary>
[SugarColumn(ColumnDescription = "书写方向", DefaultValue = "1")]
public DirectionEnum Direction { get; set; } = DirectionEnum.Ltr;
/// <summary>
/// 日期格式(如 YYYY-MM-DD
/// </summary>
[SugarColumn(ColumnDescription = "日期格式")]
public string DateFormat { get; set; }
/// <summary>
/// 时间格式(如 HH:MM:SS
/// </summary>
[SugarColumn(ColumnDescription = "时间格式")]
public string TimeFormat { get; set; }
/// <summary>
/// 每周起始日(如 0=星期日1=星期一)
/// </summary>
[SugarColumn(ColumnDescription = "每周起始日", DefaultValue = "7")]
public WeekEnum WeekStart { get; set; } = WeekEnum.Sunday;
/// <summary>
/// 分组符号(如 ,
/// </summary>
[SugarColumn(ColumnDescription = "分组符号")]
public string Grouping { get; set; }
/// <summary>
/// 小数点符号
/// </summary>
[SugarColumn(ColumnDescription = "小数点符号")]
public string DecimalPoint { get; set; }
/// <summary>
/// 千分位分隔符
/// </summary>
[SugarColumn(ColumnDescription = "千分位分隔符")]
public string? ThousandsSep { get; set; }
/// <summary>
/// 是否启用
/// </summary>
[SugarColumn(ColumnDescription = "是否启用")]
public bool Active { get; set; }
}

@ -0,0 +1,44 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
[SugarTable(null, "翻译表")]
[SysTable]
[SugarIndex("index_{table}_N", nameof(EntityName), OrderByType.Asc)]
[SugarIndex("index_{table}_F", nameof(FieldName), OrderByType.Asc)]
public class SysLangText : EntityBase
{
/// <summary>
/// 所属实体名
/// </summary>
[SugarColumn(ColumnDescription = "所属实体名")]
public string EntityName { get; set; }
/// <summary>
/// 所属实体ID
/// </summary>
[SugarColumn(ColumnDescription = "所属实体ID")]
public long EntityId { get; set; }
/// <summary>
/// 字段名
/// </summary>
[SugarColumn(ColumnDescription = "字段名")]
public string FieldName { get; set; }
/// <summary>
/// 语言代码
/// </summary>
[SugarColumn(ColumnDescription = "语言代码")]
public string LangCode { get; set; }
/// <summary>
/// 多语言内容
/// </summary>
[SugarColumn(ColumnDescription = "翻译内容")]
public string Content { get; set; }
}

@ -0,0 +1,89 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统域登录信息配置表
/// </summary>
[SugarTable(null, "系统域登录信息配置表")]
[SysTable]
public class SysLdap : EntityBaseTenantDel
{
/// <summary>
/// 主机
/// </summary>
[SugarColumn(ColumnDescription = "主机", Length = 128)]
[Required]
public virtual string Host { get; set; }
/// <summary>
/// 端口
/// </summary>
[SugarColumn(ColumnDescription = "端口")]
public virtual int Port { get; set; }
/// <summary>
/// 用户搜索基准
/// </summary>
[SugarColumn(ColumnDescription = "用户搜索基准", Length = 128)]
[Required]
public virtual string BaseDn { get; set; }
/// <summary>
/// 绑定DN(有管理权限制的用户)
/// </summary>
[SugarColumn(ColumnDescription = "绑定DN", Length = 128)]
[Required]
public virtual string BindDn { get; set; }
/// <summary>
/// 绑定密码(有管理权限制的用户密码)
/// </summary>
[SugarColumn(ColumnDescription = "绑定密码", Length = 512)]
[Required]
public virtual string BindPass { get; set; }
/// <summary>
/// 用户过滤规则
/// </summary>
[SugarColumn(ColumnDescription = "用户过滤规则", Length = 128)]
[Required]
public virtual string AuthFilter { get; set; } = "sAMAccountName=%s";
/// <summary>
/// Ldap版本
/// </summary>
[SugarColumn(ColumnDescription = "Ldap版本")]
public int Version { get; set; }
/// <summary>
/// 绑定域账号字段属性值
/// </summary>
[SugarColumn(ColumnDescription = "绑定域账号字段属性值", Length = 32)]
[Required]
public virtual string BindAttrAccount { get; set; } = "sAMAccountName";
/// <summary>
/// 绑定用户EmployeeId属性值
/// </summary>
[SugarColumn(ColumnDescription = "绑定用户EmployeeId属性值", Length = 32)]
[Required]
public virtual string BindAttrEmployeeId { get; set; } = "EmployeeId";
/// <summary>
/// 绑定Code属性值
/// </summary>
[SugarColumn(ColumnDescription = "绑定对象Code属性值", Length = 64)]
[Required]
public virtual string BindAttrCode { get; set; } = "objectGUID";
/// <summary>
/// 状态
/// </summary>
[SugarColumn(ColumnDescription = "状态")]
public StatusEnum Status { get; set; } = StatusEnum.Enable;
}

@ -0,0 +1,52 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统差异日志表
/// </summary>
[SugarTable(null, "系统差异日志表")]
[SysTable]
[LogTable]
public partial class SysLogDiff : EntityBaseTenant
{
/// <summary>
/// 差异数据
/// </summary>
[SugarColumn(ColumnDescription = "差异数据", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? DiffData { get; set; }
/// <summary>
/// Sql
/// </summary>
[SugarColumn(ColumnDescription = "Sql", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? Sql { get; set; }
/// <summary>
/// 参数 手动传入的参数
/// </summary>
[SugarColumn(ColumnDescription = "参数", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? Parameters { get; set; }
/// <summary>
/// 业务对象
/// </summary>
[SugarColumn(ColumnDescription = "业务对象", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? BusinessData { get; set; }
/// <summary>
/// 差异操作
/// </summary>
[SugarColumn(ColumnDescription = "差异操作", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? DiffType { get; set; }
/// <summary>
/// 耗时
/// </summary>
[SugarColumn(ColumnDescription = "耗时")]
public long? Elapsed { get; set; }
}

@ -0,0 +1,72 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统异常日志表
/// </summary>
[SugarTable(null, "系统异常日志表")]
[SysTable]
[LogTable]
public partial class SysLogEx : SysLogVis
{
/// <summary>
/// 请求方式
/// </summary>
[SugarColumn(ColumnDescription = "请求方式", Length = 32)]
[MaxLength(32)]
public string? HttpMethod { get; set; }
/// <summary>
/// 请求地址
/// </summary>
[SugarColumn(ColumnDescription = "请求地址", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? RequestUrl { get; set; }
/// <summary>
/// 请求参数
/// </summary>
[SugarColumn(ColumnDescription = "请求参数", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? RequestParam { get; set; }
/// <summary>
/// 返回结果
/// </summary>
[SugarColumn(ColumnDescription = "返回结果", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? ReturnResult { get; set; }
/// <summary>
/// 事件Id
/// </summary>
[SugarColumn(ColumnDescription = "事件Id")]
public int? EventId { get; set; }
/// <summary>
/// 线程Id
/// </summary>
[SugarColumn(ColumnDescription = "线程Id")]
public int? ThreadId { get; set; }
/// <summary>
/// 请求跟踪Id
/// </summary>
[SugarColumn(ColumnDescription = "请求跟踪Id", Length = 128)]
[MaxLength(128)]
public string? TraceId { get; set; }
/// <summary>
/// 异常信息
/// </summary>
[SugarColumn(ColumnDescription = "异常信息", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? Exception { get; set; }
/// <summary>
/// 日志消息Json
/// </summary>
[SugarColumn(ColumnDescription = "日志消息Json", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? Message { get; set; }
}

@ -0,0 +1,72 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统操作日志表
/// </summary>
[SugarTable(null, "系统操作日志表")]
[SysTable]
[LogTable]
public partial class SysLogOp : SysLogVis
{
/// <summary>
/// 请求方式
/// </summary>
[SugarColumn(ColumnDescription = "请求方式", Length = 32)]
[MaxLength(32)]
public string? HttpMethod { get; set; }
/// <summary>
/// 请求地址
/// </summary>
[SugarColumn(ColumnDescription = "请求地址", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? RequestUrl { get; set; }
/// <summary>
/// 请求参数
/// </summary>
[SugarColumn(ColumnDescription = "请求参数", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? RequestParam { get; set; }
/// <summary>
/// 返回结果
/// </summary>
[SugarColumn(ColumnDescription = "返回结果", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? ReturnResult { get; set; }
/// <summary>
/// 事件Id
/// </summary>
[SugarColumn(ColumnDescription = "事件Id")]
public int? EventId { get; set; }
/// <summary>
/// 线程Id
/// </summary>
[SugarColumn(ColumnDescription = "线程Id")]
public int? ThreadId { get; set; }
/// <summary>
/// 请求跟踪Id
/// </summary>
[SugarColumn(ColumnDescription = "请求跟踪Id", Length = 128)]
[MaxLength(128)]
public string? TraceId { get; set; }
/// <summary>
/// 异常信息
/// </summary>
[SugarColumn(ColumnDescription = "异常信息", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? Exception { get; set; }
/// <summary>
/// 日志消息Json
/// </summary>
[SugarColumn(ColumnDescription = "日志消息Json", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? Message { get; set; }
}

@ -0,0 +1,116 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统访问日志表
/// </summary>
[SugarTable(null, "系统访问日志表")]
[SysTable]
[LogTable]
public partial class SysLogVis : EntityBaseTenant
{
/// <summary>
/// 模块名称
/// </summary>
[SugarColumn(ColumnDescription = "模块名称", Length = 256)]
[MaxLength(256)]
public string? ControllerName { get; set; }
/// <summary>
/// 方法名称
///</summary>
[SugarColumn(ColumnDescription = "方法名称", Length = 256)]
[MaxLength(256)]
public string? ActionName { get; set; }
/// <summary>
/// 显示名称
///</summary>
[SugarColumn(ColumnDescription = "显示名称", Length = 256)]
[MaxLength(256)]
public string? DisplayTitle { get; set; }
/// <summary>
/// 执行状态
/// </summary>
[SugarColumn(ColumnDescription = "执行状态", Length = 32)]
[MaxLength(32)]
public string? Status { get; set; }
/// <summary>
/// IP地址
/// </summary>
[SugarColumn(ColumnDescription = "IP地址", Length = 256)]
[MaxLength(256)]
public string? RemoteIp { get; set; }
/// <summary>
/// 登录地点
/// </summary>
[SugarColumn(ColumnDescription = "登录地点", Length = 128)]
[MaxLength(128)]
public string? Location { get; set; }
/// <summary>
/// 经度
/// </summary>
[SugarColumn(ColumnDescription = "经度")]
public decimal? Longitude { get; set; }
/// <summary>
/// 维度
/// </summary>
[SugarColumn(ColumnDescription = "维度")]
public decimal? Latitude { get; set; }
/// <summary>
/// 浏览器
/// </summary>
[SugarColumn(ColumnDescription = "浏览器", Length = 1024)]
[MaxLength(1024)]
public string? Browser { get; set; }
/// <summary>
/// 操作系统
/// </summary>
[SugarColumn(ColumnDescription = "操作系统", Length = 256)]
[MaxLength(256)]
public string? Os { get; set; }
/// <summary>
/// 操作用时
/// </summary>
[SugarColumn(ColumnDescription = "操作用时")]
public long? Elapsed { get; set; }
/// <summary>
/// 日志时间
/// </summary>
[SugarColumn(ColumnDescription = "日志时间")]
public DateTime? LogDateTime { get; set; }
/// <summary>
/// 日志级别
/// </summary>
[SugarColumn(ColumnDescription = "日志级别")]
public LogLevel? LogLevel { get; set; }
/// <summary>
/// 账号
/// </summary>
[SugarColumn(ColumnDescription = "账号", Length = 32)]
[MaxLength(32)]
public string? Account { get; set; }
/// <summary>
/// 真实姓名
/// </summary>
[SugarColumn(ColumnDescription = "真实姓名", Length = 32)]
[MaxLength(32)]
public string? RealName { get; set; }
}

@ -0,0 +1,134 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统菜单表
/// </summary>
[SugarTable(null, "系统菜单表")]
[SysTable]
[SugarIndex("index_{table}_T", nameof(Title), OrderByType.Asc)]
[SugarIndex("index_{table}_T2", nameof(Type), OrderByType.Asc)]
public partial class SysMenu : EntityBase
{
/// <summary>
/// 父Id
/// </summary>
[SugarColumn(ColumnDescription = "父Id")]
public long Pid { get; set; }
/// <summary>
/// 菜单类型1目录 2菜单 3按钮
/// </summary>
[SugarColumn(ColumnDescription = "菜单类型")]
public MenuTypeEnum Type { get; set; }
/// <summary>
/// 路由名称
/// </summary>
[SugarColumn(ColumnDescription = "路由名称", Length = 64)]
[MaxLength(64)]
public string? Name { get; set; }
/// <summary>
/// 路由地址
/// </summary>
[SugarColumn(ColumnDescription = "路由地址", Length = 128)]
[MaxLength(128)]
public string? Path { get; set; }
/// <summary>
/// 组件路径
/// </summary>
[SugarColumn(ColumnDescription = "组件路径", Length = 128)]
[MaxLength(128)]
public string? Component { get; set; }
/// <summary>
/// 重定向
/// </summary>
[SugarColumn(ColumnDescription = "重定向", Length = 128)]
[MaxLength(128)]
public string? Redirect { get; set; }
/// <summary>
/// 权限标识
/// </summary>
[SugarColumn(ColumnDescription = "权限标识", Length = 128)]
[MaxLength(128)]
public string? Permission { get; set; }
/// <summary>
/// 菜单名称
/// </summary>
[SugarColumn(ColumnDescription = "菜单名称", Length = 64)]
[Required, MaxLength(64)]
public virtual string Title { get; set; }
/// <summary>
/// 图标
/// </summary>
[SugarColumn(ColumnDescription = "图标", Length = 128)]
[MaxLength(128)]
public string? Icon { get; set; } = "ele-Menu";
/// <summary>
/// 是否内嵌
/// </summary>
[SugarColumn(ColumnDescription = "是否内嵌")]
public bool IsIframe { get; set; }
/// <summary>
/// 外链链接
/// </summary>
[SugarColumn(ColumnDescription = "外链链接", Length = 256)]
[MaxLength(256)]
public string? OutLink { get; set; }
/// <summary>
/// 是否隐藏
/// </summary>
[SugarColumn(ColumnDescription = "是否隐藏")]
public bool IsHide { get; set; }
/// <summary>
/// 是否缓存
/// </summary>
[SugarColumn(ColumnDescription = "是否缓存")]
public bool IsKeepAlive { get; set; } = true;
/// <summary>
/// 是否固定
/// </summary>
[SugarColumn(ColumnDescription = "是否固定")]
public bool IsAffix { get; set; }
/// <summary>
/// 排序
/// </summary>
[SugarColumn(ColumnDescription = "排序")]
public int OrderNo { get; set; } = 100;
/// <summary>
/// 状态
/// </summary>
[SugarColumn(ColumnDescription = "状态")]
public StatusEnum Status { get; set; } = StatusEnum.Enable;
/// <summary>
/// 备注
/// </summary>
[SugarColumn(ColumnDescription = "备注", Length = 256)]
[MaxLength(256)]
public string? Remark { get; set; }
/// <summary>
/// 菜单子项
/// </summary>
[SugarColumn(IsIgnore = true)]
public List<SysMenu> Children { get; set; } = new();
}

@ -0,0 +1,82 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统通知公告表
/// </summary>
[SugarTable(null, "系统通知公告表")]
[SysTable]
[SugarIndex("index_{table}_T", nameof(Type), OrderByType.Asc)]
public partial class SysNotice : EntityBase
{
/// <summary>
/// 标题
/// </summary>
[SugarColumn(ColumnDescription = "标题", Length = 32)]
[Required, MaxLength(32)]
[SensitiveDetection('*')]
public virtual string Title { get; set; }
/// <summary>
/// 内容
/// </summary>
[SugarColumn(ColumnDescription = "内容", ColumnDataType = StaticConfig.CodeFirst_BigString)]
[Required]
[SensitiveDetection('*')]
public virtual string Content { get; set; }
/// <summary>
/// 类型1通知 2公告
/// </summary>
[SugarColumn(ColumnDescription = "类型1通知 2公告")]
public NoticeTypeEnum Type { get; set; }
/// <summary>
/// 发布人Id
/// </summary>
[SugarColumn(ColumnDescription = "发布人Id")]
public long PublicUserId { get; set; }
/// <summary>
/// 发布人姓名
/// </summary>
[SugarColumn(ColumnDescription = "发布人姓名", Length = 32)]
[MaxLength(32)]
public string? PublicUserName { get; set; }
/// <summary>
/// 发布机构Id
/// </summary>
[SugarColumn(ColumnDescription = "发布机构Id")]
public long PublicOrgId { get; set; }
/// <summary>
/// 发布机构名称
/// </summary>
[SugarColumn(ColumnDescription = "发布机构名称", Length = 64)]
[MaxLength(64)]
public string? PublicOrgName { get; set; }
/// <summary>
/// 发布时间
/// </summary>
[SugarColumn(ColumnDescription = "发布时间")]
public DateTime? PublicTime { get; set; }
/// <summary>
/// 撤回时间
/// </summary>
[SugarColumn(ColumnDescription = "撤回时间")]
public DateTime? CancelTime { get; set; }
/// <summary>
/// 状态0草稿 1发布 2撤回 3删除
/// </summary>
[SugarColumn(ColumnDescription = "状态0草稿 1发布 2撤回 3删除")]
public NoticeStatusEnum Status { get; set; }
}

@ -0,0 +1,45 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统通知公告用户表
/// </summary>
[SugarTable(null, "系统通知公告用户表")]
[SysTable]
public partial class SysNoticeUser : EntityBaseId
{
/// <summary>
/// 通知公告Id
/// </summary>
[SugarColumn(ColumnDescription = "通知公告Id")]
public long NoticeId { get; set; }
/// <summary>
/// 通知公告
/// </summary>
[Navigate(NavigateType.OneToOne, nameof(NoticeId))]
public SysNotice SysNotice { get; set; }
/// <summary>
/// 用户Id
/// </summary>
[SugarColumn(ColumnDescription = "用户Id")]
public long UserId { get; set; }
/// <summary>
/// 阅读时间
/// </summary>
[SugarColumn(ColumnDescription = "阅读时间")]
public DateTime? ReadTime { get; set; }
/// <summary>
/// 状态0未读 1已读
/// </summary>
[SugarColumn(ColumnDescription = "状态0未读 1已读")]
public NoticeUserStatusEnum ReadStatus { get; set; } = NoticeUserStatusEnum.UNREAD;
}

@ -0,0 +1,68 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统在线用户表
/// </summary>
[SugarTable(null, "系统在线用户表")]
[SysTable]
public partial class SysOnlineUser : EntityBaseTenantId
{
/// <summary>
/// 连接Id
/// </summary>
[SugarColumn(ColumnDescription = "连接Id")]
public string? ConnectionId { get; set; }
/// <summary>
/// 用户Id
/// </summary>
[SugarColumn(ColumnDescription = "用户Id")]
public long UserId { get; set; }
/// <summary>
/// 账号
/// </summary>
[SugarColumn(ColumnDescription = "账号", Length = 32)]
[Required, MaxLength(32)]
public virtual string UserName { get; set; }
/// <summary>
/// 真实姓名
/// </summary>
[SugarColumn(ColumnDescription = "真实姓名", Length = 32)]
[MaxLength(32)]
public string? RealName { get; set; }
/// <summary>
/// 连接时间
/// </summary>
[SugarColumn(ColumnDescription = "连接时间")]
public DateTime? Time { get; set; }
/// <summary>
/// 连接IP
/// </summary>
[SugarColumn(ColumnDescription = "连接IP", Length = 256)]
[MaxLength(256)]
public string? Ip { get; set; }
/// <summary>
/// 浏览器
/// </summary>
[SugarColumn(ColumnDescription = "浏览器", Length = 128)]
[MaxLength(128)]
public string? Browser { get; set; }
/// <summary>
/// 操作系统
/// </summary>
[SugarColumn(ColumnDescription = "操作系统", Length = 128)]
[MaxLength(128)]
public string? Os { get; set; }
}

@ -0,0 +1,56 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 开放接口身份表
/// </summary>
[SugarTable(null, "开放接口身份表")]
[SysTable]
[SugarIndex("index_{table}_A", nameof(AccessKey), OrderByType.Asc)]
public partial class SysOpenAccess : EntityBase
{
/// <summary>
/// 身份标识
/// </summary>
[SugarColumn(ColumnDescription = "身份标识", Length = 128)]
[Required, MaxLength(128)]
public virtual string AccessKey { get; set; }
/// <summary>
/// 密钥
/// </summary>
[SugarColumn(ColumnDescription = "密钥", Length = 256)]
[Required, MaxLength(256)]
public virtual string AccessSecret { get; set; }
/// <summary>
/// 绑定租户Id
/// </summary>
[SugarColumn(ColumnDescription = "绑定租户Id")]
public long BindTenantId { get; set; }
/// <summary>
/// 绑定租户
/// </summary>
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
[Navigate(NavigateType.OneToOne, nameof(BindTenantId))]
public SysTenant BindTenant { get; set; }
/// <summary>
/// 绑定用户Id
/// </summary>
[SugarColumn(ColumnDescription = "绑定用户Id")]
public virtual long BindUserId { get; set; }
/// <summary>
/// 绑定用户
/// </summary>
[Navigate(NavigateType.OneToOne, nameof(BindUserId))]
public SysUser BindUser { get; set; }
}

@ -0,0 +1,96 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统机构表
/// </summary>
[SugarTable(null, "系统机构表")]
[SysTable]
[SugarIndex("index_{table}_N", nameof(Name), OrderByType.Asc)]
[SugarIndex("index_{table}_C", nameof(Code), OrderByType.Asc)]
[SugarIndex("index_{table}_T", nameof(Type), OrderByType.Asc)]
public partial class SysOrg : EntityBaseTenant
{
/// <summary>
/// 父Id
/// </summary>
[SugarColumn(ColumnDescription = "父Id")]
public long Pid { get; set; }
/// <summary>
/// 名称
/// </summary>
[SugarColumn(ColumnDescription = "名称", Length = 64)]
[Required, MaxLength(64)]
public virtual string Name { get; set; }
/// <summary>
/// 编码
/// </summary>
[SugarColumn(ColumnDescription = "编码", Length = 64)]
[MaxLength(64)]
public string? Code { get; set; }
/// <summary>
/// 级别
/// </summary>
[SugarColumn(ColumnDescription = "级别")]
public int? Level { get; set; }
/// <summary>
/// 机构类型-数据字典
/// </summary>
[SugarColumn(ColumnDescription = "机构类型", Length = 64)]
[MaxLength(64)]
public virtual string? Type { get; set; }
/// <summary>
/// 负责人Id
/// </summary>
[SugarColumn(ColumnDescription = "负责人Id", IsNullable = true)]
public long? DirectorId { get; set; }
/// <summary>
/// 负责人
/// </summary>
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
[Navigate(NavigateType.OneToOne, nameof(DirectorId))]
public SysUser Director { get; set; }
/// <summary>
/// 排序
/// </summary>
[SugarColumn(ColumnDescription = "排序")]
public int OrderNo { get; set; } = 100;
/// <summary>
/// 状态
/// </summary>
[SugarColumn(ColumnDescription = "状态")]
public StatusEnum Status { get; set; } = StatusEnum.Enable;
/// <summary>
/// 备注
/// </summary>
[SugarColumn(ColumnDescription = "备注", Length = 128)]
[MaxLength(128)]
public string? Remark { get; set; }
/// <summary>
/// 机构子项
/// </summary>
[SugarColumn(IsIgnore = true)]
public List<SysOrg> Children { get; set; }
/// <summary>
/// 是否禁止选中
/// </summary>
[SugarColumn(IsIgnore = true)]
public bool Disabled { get; set; }
}

@ -0,0 +1,56 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统动态插件表
/// </summary>
[SugarTable(null, "系统动态插件表")]
[SysTable]
[SugarIndex("index_{table}_N", nameof(Name), OrderByType.Asc)]
public partial class SysPlugin : EntityBaseTenant
{
/// <summary>
/// 名称
/// </summary>
[SugarColumn(ColumnDescription = "名称", Length = 64)]
[Required, MaxLength(64)]
public virtual string Name { get; set; }
/// <summary>
/// C#代码
/// </summary>
[SugarColumn(ColumnDescription = "C#代码", ColumnDataType = StaticConfig.CodeFirst_BigString)]
[Required]
public virtual string CsharpCode { get; set; }
/// <summary>
/// 程序集名称
/// </summary>
[SugarColumn(ColumnDescription = "程序集名称", Length = 512)]
[MaxLength(512)]
public string? AssemblyName { get; set; }
/// <summary>
/// 排序
/// </summary>
[SugarColumn(ColumnDescription = "排序")]
public int OrderNo { get; set; } = 100;
/// <summary>
/// 状态
/// </summary>
[SugarColumn(ColumnDescription = "状态")]
public StatusEnum Status { get; set; } = StatusEnum.Enable;
/// <summary>
/// 备注
/// </summary>
[SugarColumn(ColumnDescription = "备注", Length = 128)]
[MaxLength(128)]
public string? Remark { get; set; }
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save