From 17782ad6121ce3bebbf88d28ac7dacf6c8c697fd Mon Sep 17 00:00:00 2001 From: fajiao <1519100073@qq.com> Date: Fri, 30 Sep 2022 14:39:16 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cis.Application/Cis.Application.csproj | 4 +- Cis.Application/Cis.Application.xml | 252 ++++++++++- Cis.Application/GlobalUsings.cs | 16 +- Cis.Application/applicationsettings.json | 31 -- Cis.Core/Cis.Core.csproj | 12 + Cis.Core/Cis.Core.xml | 475 +++++++++++++++++++- Cis.Core/DbContext.cs | 22 - Cis.Web.Core/Cis.Web.Core.xml | 20 + Cis.Web.Core/Startup.cs | 127 ++++-- Cis.Web.Entry/Cis.Web.Entry.csproj | 4 + Cis.Web.Entry/Controllers/HomeController.cs | 24 +- Cis.Web.Entry/Views/Home/Index.cshtml | 8 +- Cis.Web.Entry/Views/Shared/_Layout.cshtml | 2 +- Cis.Web.Entry/appsettings.Development.json | 16 +- Cis.Web.Entry/appsettings.json | 25 +- Cis.Web.Entry/wwwroot/images/logo.png | Bin 6255 -> 0 bytes 16 files changed, 876 insertions(+), 162 deletions(-) delete mode 100644 Cis.Application/applicationsettings.json delete mode 100644 Cis.Core/DbContext.cs delete mode 100644 Cis.Web.Entry/wwwroot/images/logo.png diff --git a/Cis.Application/Cis.Application.csproj b/Cis.Application/Cis.Application.csproj index 307222f..dcda911 100644 --- a/Cis.Application/Cis.Application.csproj +++ b/Cis.Application/Cis.Application.csproj @@ -8,12 +8,12 @@ - + - + PreserveNewest diff --git a/Cis.Application/Cis.Application.xml b/Cis.Application/Cis.Application.xml index df7075f..4107b98 100644 --- a/Cis.Application/Cis.Application.xml +++ b/Cis.Application/Cis.Application.xml @@ -4,16 +4,258 @@ Cis.Application - + - 系统服务接口 + Cb -> Camera base - + - 获取系统描述 + Api 分组名 + + + + + Api 分组排序 + + + + + 数据库名 + + + + + CbCamera 表名 + + + + + CbCamera 表描述 + + + + + 系统字典类型表 + + + + + 名称 + + + + + ip 地址 + + + + + 端口 + + + + + 账号 + + + + + 密码 + + + + + 相机服务 + + + + + Cm -> Camera mark + + + + + Api 分组名 + + + + + Api 分组排序 + + + + + 数据库名 + + + + + CmMarkGroup 表名 + + + + + CmMarkGroup 表描述 + + + + + 标记分组表 + + + + + 名称 + + + + + 排序 + + + + + 备注 + + + + + 标记分组服务 + + + + + 配置应用所需服务,在该方法中可以添加应用所需要的功能或服务 + + + + + + 配置应用请求处理管道 + + + + + + + Sys -> System + + + + + Api 分组名 + + + + + Api 分组排序 + + + + + 数据库名 + + + + + SysDictType 表名 + + + + + SysDictType 表描述 + + + + + SysDataType 表名 + + + + + SysDataType 表描述 + + + + + 系统字典值表 + + + + + 字典类型Id + + + + + 字典类型 + + + + + 值 + + + + + 编码 + + + + + 排序 + + + + + 备注 + + + + + 状态 + + + + + 系统字典类型表 + + + + + 名称 + + + + + 编码 + + + + + 排序 + + + + + 备注 + + + + + 状态 + + + + + 系统字典值服务 + + + + + 系统字典类型服务 - diff --git a/Cis.Application/GlobalUsings.cs b/Cis.Application/GlobalUsings.cs index 1f0aacd..a7568c4 100644 --- a/Cis.Application/GlobalUsings.cs +++ b/Cis.Application/GlobalUsings.cs @@ -1,15 +1,7 @@ -global using Furion; -global using Furion.DataEncryption; -global using Furion.DataValidation; +global using Cis.Core; +global using Furion; global using Furion.DependencyInjection; global using Furion.DynamicApiController; -global using Furion.Extensions; -global using Furion.FriendlyException; -global using Furion.Logging; -global using Mapster; -global using Microsoft.AspNetCore.Authorization; -global using Microsoft.AspNetCore.Http; global using Microsoft.AspNetCore.Mvc; -global using Microsoft.CodeAnalysis; -global using System.ComponentModel.DataAnnotations; -global using SqlSugar; \ No newline at end of file +global using SqlSugar; +global using System.ComponentModel.DataAnnotations; \ No newline at end of file diff --git a/Cis.Application/applicationsettings.json b/Cis.Application/applicationsettings.json deleted file mode 100644 index 331a6c6..0000000 --- a/Cis.Application/applicationsettings.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json", - "SpecificationDocumentSettings": { - "DocumentTitle": "Furion | 规范化接口", - "GroupOpenApiInfos": [ - { - "Group": "Default", - "Title": "规范化接口演示", - "Description": "让 .NET 开发更简单,更通用,更流行。", - "Version": "1.0.0", - "TermsOfService": "https://furion.icu", - "Contact": { - "Name": "百小僧", - "Url": "https://gitee.com/monksoul", - "Email": "monksoul@outlook.com" - }, - "License": { - "Name": "Apache-2.0", - "Url": "https://gitee.com/dotnetchina/Furion/blob/rc1/LICENSE" - } - } - ] - }, - "CorsAccessorSettings": { - "WithExposedHeaders": [ - "access-token", - "x-access-token", - "environment" - ] - } -} \ No newline at end of file diff --git a/Cis.Core/Cis.Core.csproj b/Cis.Core/Cis.Core.csproj index 2f2311d..6530dd8 100644 --- a/Cis.Core/Cis.Core.csproj +++ b/Cis.Core/Cis.Core.csproj @@ -8,13 +8,25 @@ + + + + + + PreserveNewest + + + + + + diff --git a/Cis.Core/Cis.Core.xml b/Cis.Core/Cis.Core.xml index f4bb90e..310f220 100644 --- a/Cis.Core/Cis.Core.xml +++ b/Cis.Core/Cis.Core.xml @@ -4,14 +4,481 @@ Cis.Core - + - 数据库上下文对象 + 非实体表特性 - + - SqlSugar 数据库实例 + 缓存注册(新生命Redis组件) + + + + + + SqlSugar二级缓存(必须是内存缓存) + + + + + 默认数据库标识 + + + + + 默认表主键 + + + + + 框架实体基类Id + + + + + 雪花Id + + + + + 框架实体基类 + + + + + 创建时间 + + + + + 更新时间 + + + + + 创建者Id + + + + + 修改者Id + + + + + 软删除 + + + + + 业务数据实体基类(数据权限) + + + + + 创建者部门Id + + + + + 当前页 + + + + + 页码容量 + + + + + 排序字段 + + + + + 排序方向 + + + + + 总记录数 + + + + + 页码数 + + + + + 缓存类型枚举 + + + + + 内存缓存 + + + + + Redis缓存 + + + + + 通用状态枚举 + + + + + 停用 + + + + + 启用 + + + + + 对象拓展 + + + + + 判断类型是否实现某个泛型 + + 类型 + 泛型类型 + bool + + + + 将字典转化为QueryString格式 + + + + + + + + 将字符串URL编码 + + + + + + + List转DataTable + + + + + + + + 对象序列化成Json字符串 + + + + + + + Json字符串反序列化成对象 + + + + + + + + 字串反序列化成linq对象 + + 字串 + + + + + 排除SqlSugar忽略的列 + + + + + + + 缓存配置选项 + + + + + 缓存类型 + + + + + Redis连接字符串 + + + + + 数据库配置选项 + + + + + 数据库集合 + + + + + 启用库表初始化 + + + + + 雪花Id配置选项 + + + + + 机器码 + + + + + 自定义实体过滤器接口 + + + + + 实体过滤器 + + + + + + 实体种子数据接口 + + + + + + 种子数据 + + + + + + 分页泛型集合 + + + + + + 页码 + + + + + 页容量 + + + + + 总条数 + + + + + 总页数 + + + + + 当前页集合 + + + + + 是否有上一页 + + + + + 是否有下一页 + + + + + 分页拓展类 + + + + + 分页拓展 + + + + + + + + + 分页拓展 + + + + + + + + + SqlSugar仓储类 + + + + + + Sqlsugar 上下文初始化 + + + + + + 初始化数据库结构 + + + + + SqlSugar 事务和工作单元 + + + + + SqlSugar 对象 + + + + + 构造函数 + + + + + + 开启工作单元处理 + + + + + + + + 提交工作单元处理 + + + + + + + + 回滚工作单元处理 + + + + + + + + 执行完毕(无论成功失败) + + + + + + + + 全局规范化结果 + + + + + 异常返回值 + + + + + + + + 成功返回值 + + + + + + + + 验证失败返回值 + + + + + + + + 特定状态码返回值 + + + + + + + + + 返回 RESTful 风格结果集 + + + + + + + + + + 全局返回结果 + + + + + + 状态码 + + + + + 类型success、warning、error + + + + + 错误信息 + + + + + 数据 + + + + + 附加数据 + + + + + 时间戳 diff --git a/Cis.Core/DbContext.cs b/Cis.Core/DbContext.cs deleted file mode 100644 index 365d73a..0000000 --- a/Cis.Core/DbContext.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Furion; -using SqlSugar; -using System.Collections.Generic; - -namespace Cis.Core; - -/// -/// 数据库上下文对象 -/// -public static class DbContext -{ - /// - /// SqlSugar 数据库实例 - /// - public static readonly SqlSugarScope Instance = new( - // 读取 appsettings.json 中的 ConnectionConfigs 配置节点 - App.GetConfig>("ConnectionConfigs") - , db => - { - // 这里配置全局事件,比如拦截执行 SQL - }); -} diff --git a/Cis.Web.Core/Cis.Web.Core.xml b/Cis.Web.Core/Cis.Web.Core.xml index dff0058..a046e5a 100644 --- a/Cis.Web.Core/Cis.Web.Core.xml +++ b/Cis.Web.Core/Cis.Web.Core.xml @@ -4,5 +4,25 @@ Cis.Web.Core + + + 注册项目配置选项 + + + + + + + 配置应用所需服务,在该方法中可以添加应用所需要的功能或服务 + + + + + + 配置应用请求处理管道 + + + + diff --git a/Cis.Web.Core/Startup.cs b/Cis.Web.Core/Startup.cs index 5083893..6f1206e 100644 --- a/Cis.Web.Core/Startup.cs +++ b/Cis.Web.Core/Startup.cs @@ -1,51 +1,94 @@ -using Furion; +using Cis.Core; +using Furion; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using Yitter.IdGenerator; namespace Cis.Web.Core; public class Startup : AppStartup { - public void ConfigureServices(IServiceCollection services) - { - services.AddJwt(); - - services.AddCorsAccessor(); - - services.AddControllersWithViews() - .AddInjectWithUnifyResult(); - } - - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else - { - app.UseExceptionHandler("/Home/Error"); - app.UseHsts(); - } - app.UseHttpsRedirection(); - app.UseStaticFiles(); - - app.UseRouting(); - - app.UseCorsAccessor(); - - app.UseAuthentication(); - app.UseAuthorization(); - - app.UseInject(); - - app.UseEndpoints(endpoints => - { - endpoints.MapControllerRoute( - name: "default", - pattern: "{controller=Home}/{action=Index}/{id?}"); - }); - } -} + /// + /// 配置应用所需服务,在该方法中可以添加应用所需要的功能或服务 + /// + /// + public void ConfigureServices(IServiceCollection services) + { + // 配置选项 + services.AddProjectOptions(); + // 缓存注册 + services.AddCache(); + // SqlSugar + services.AddSqlSugar(); + // JWT + services.AddJwt(); + // 允许跨域 + services.AddCorsAccessor(); + // 远程请求 + services.AddRemoteRequest(); + // 任务调度 + services.AddTaskScheduler(); + // 日志监听 + services.AddMonitorLogging(); + + services.AddControllersWithViews() + .AddNewtonsoftJson(options => + { + options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); // 首字母小写(驼峰样式) + options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; // 时间格式化 + options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; // 忽略循环引用 + options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; // 忽略空值 + }) + .AddInjectWithUnifyResult(); + + // 配置雪花Id算法机器码 + YitIdHelper.SetIdGenerator(new IdGeneratorOptions + { + WorkerId = App.GetOptions().WorkerId + }); + } + + /// + /// 配置应用请求处理管道 + /// + /// + /// + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + app.UseForwardedHeaders(); + } + else + { + app.UseExceptionHandler("/Home/Error"); + app.UseForwardedHeaders(); + app.UseHsts(); + } + + // 启用HTTPS + app.UseHttpsRedirection(); + app.UseStaticFiles(); + + app.UseRouting(); + + app.UseCorsAccessor(); + + app.UseAuthentication(); + app.UseAuthorization(); + + app.UseInject(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllerRoute( + name: "default", + pattern: "{controller=Home}/{action=Index}/{id?}"); + }); + } +} \ No newline at end of file diff --git a/Cis.Web.Entry/Cis.Web.Entry.csproj b/Cis.Web.Entry/Cis.Web.Entry.csproj index 6392984..2ddaf1d 100644 --- a/Cis.Web.Entry/Cis.Web.Entry.csproj +++ b/Cis.Web.Entry/Cis.Web.Entry.csproj @@ -10,4 +10,8 @@ + + + + diff --git a/Cis.Web.Entry/Controllers/HomeController.cs b/Cis.Web.Entry/Controllers/HomeController.cs index 23ddfb4..3a64469 100644 --- a/Cis.Web.Entry/Controllers/HomeController.cs +++ b/Cis.Web.Entry/Controllers/HomeController.cs @@ -1,5 +1,4 @@ -using Cis.Application; -using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Cis.Web.Entry.Controllers; @@ -7,17 +6,14 @@ namespace Cis.Web.Entry.Controllers; [AllowAnonymous] public class HomeController : Controller { - private readonly ISystemService _systemService; + public HomeController() + { + } - public HomeController(ISystemService systemService) - { - _systemService = systemService; - } + public IActionResult Index() + { + ViewBag.Description = "Hello, dotnet."; - public IActionResult Index() - { - ViewBag.Description = _systemService.GetDescription(); - - return View(); - } -} + return View(); + } +} \ No newline at end of file diff --git a/Cis.Web.Entry/Views/Home/Index.cshtml b/Cis.Web.Entry/Views/Home/Index.cshtml index d6e2832..94b7eff 100644 --- a/Cis.Web.Entry/Views/Home/Index.cshtml +++ b/Cis.Web.Entry/Views/Home/Index.cshtml @@ -3,10 +3,8 @@ }
- -
-

star fork GitHub stars GitHub forks GitHub license nuget

-

@ViewBag.Description

-

API 接口      源码地址

+

+ API 接口 +

\ No newline at end of file diff --git a/Cis.Web.Entry/Views/Shared/_Layout.cshtml b/Cis.Web.Entry/Views/Shared/_Layout.cshtml index f5f94a0..c481862 100644 --- a/Cis.Web.Entry/Views/Shared/_Layout.cshtml +++ b/Cis.Web.Entry/Views/Shared/_Layout.cshtml @@ -3,7 +3,7 @@ - @ViewData["Title"] - Furion + @ViewData["Title"] @RenderBody() diff --git a/Cis.Web.Entry/appsettings.Development.json b/Cis.Web.Entry/appsettings.Development.json index 5f187ae..d319cc7 100644 --- a/Cis.Web.Entry/appsettings.Development.json +++ b/Cis.Web.Entry/appsettings.Development.json @@ -1,10 +1,10 @@ { - "$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json", - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning", - "Microsoft.EntityFrameworkCore": "Information" - } - } + "$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json", + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "Microsoft.EntityFrameworkCore": "Information" + } + } } \ No newline at end of file diff --git a/Cis.Web.Entry/appsettings.json b/Cis.Web.Entry/appsettings.json index 8b4498e..7a5b741 100644 --- a/Cis.Web.Entry/appsettings.json +++ b/Cis.Web.Entry/appsettings.json @@ -1,18 +1,11 @@ { - "$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json", - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft.AspNetCore": "Warning", - "Microsoft.EntityFrameworkCore": "Information" - } - }, - "AllowedHosts": "*", - "ConnectionConfigs": [ - { - "ConnectionString": "Data Source=./Furion.db", - "DbType": "Sqlite", - "IsAutoCloseConnection": true - } - ] + "$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json", + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning", + "Microsoft.EntityFrameworkCore": "Information" + } + }, + "AllowedHosts": "*" } \ No newline at end of file diff --git a/Cis.Web.Entry/wwwroot/images/logo.png b/Cis.Web.Entry/wwwroot/images/logo.png deleted file mode 100644 index 166b80180fb7e665c6617c39393aa57dd204046a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6255 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