Compare commits
58 Commits
Author | SHA1 | Date |
---|---|---|
|
e2ccb07b51 | |
|
fa160cac83 | |
|
4c60372f04 | |
|
f726fa20d8 | |
|
4caab82c40 | |
|
3024bb1d62 | |
|
a8f1fab64c | |
|
d00c73d658 | |
|
06ca3270a7 | |
|
fccb6f16c2 | |
|
b66fda778e | |
|
3f6c7439bc | |
|
2f28877a30 | |
|
84a41b1a9c | |
|
f64b4e47c3 | |
|
52be00103c | |
|
873d7bbd01 | |
|
dc2f90e66b | |
|
ff35047431 | |
|
cb8b1c5de9 | |
|
97bc99e853 | |
|
1f0cd62488 | |
|
2a91923955 | |
|
e36444b9b8 | |
|
8931360620 | |
|
5ff1390e60 | |
|
dafd320b05 | |
|
eeb3fece21 | |
|
f646ae4b4b | |
|
f26ea7288b | |
|
6d135ba074 | |
|
ae37631d03 | |
|
9574d7e0b6 | |
|
0d0a314ef9 | |
|
713e57c424 | |
|
04f8d9e15d | |
|
cc23f8b00b | |
|
03d1345262 | |
|
4084e01c31 | |
|
548cc42d60 | |
|
61c853229a | |
|
5ed583a006 | |
|
aa79da6910 | |
|
250ba4a01a | |
|
0a217e7b50 | |
|
4e17fa54c1 | |
|
d6e19c291b | |
|
01391809a4 | |
|
cb1ef1db08 | |
|
b5e1badf07 | |
|
2ddef0d1b5 | |
|
578f73a23a | |
|
e37939e82b | |
|
4c6b9b567a | |
|
f171251921 | |
|
47db444117 | |
|
e2ed876d9b | |
|
8439531c54 |
|
@ -1,4 +1,3 @@
|
|||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
|
@ -289,3 +288,4 @@ __pycache__/
|
|||
*.odx.cs
|
||||
*.xsd.cs
|
||||
/LF[Ll]ow_Bin/
|
||||
LFlow-dev.db
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LFlow.Base;
|
||||
/// <summary>
|
||||
|
@ -6,10 +6,25 @@ namespace LFlow.Base;
|
|||
/// </summary>
|
||||
public class App
|
||||
{
|
||||
public static IServiceCollection? services;
|
||||
/// <summary>
|
||||
/// 服务集合
|
||||
/// </summary>
|
||||
internal static IServiceCollection? services;
|
||||
/// <summary>
|
||||
/// 服务提供者
|
||||
/// </summary>
|
||||
private static IServiceProvider? ServiceProvider => services?.BuildServiceProvider();
|
||||
/// <summary>
|
||||
/// 获取服务
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static T? GetService<T>()
|
||||
{
|
||||
return ServiceProvider!.GetService<T>();
|
||||
}
|
||||
/// <summary>
|
||||
/// 子服务程序集
|
||||
/// </summary>
|
||||
public static List<Assembly> SubServiceAssembly = [];
|
||||
}
|
||||
|
|
|
@ -0,0 +1,516 @@
|
|||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>LFlow.Base</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="T:LFlow.Base.App">
|
||||
<summary>
|
||||
程序对象
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:LFlow.Base.App.services">
|
||||
<summary>
|
||||
服务集合
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:LFlow.Base.App.ServiceProvider">
|
||||
<summary>
|
||||
服务提供者
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.App.GetService``1">
|
||||
<summary>
|
||||
获取服务
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="F:LFlow.Base.App.SubServiceAssembly">
|
||||
<summary>
|
||||
子服务程序集
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:LFlow.Base.Default.DefaultCurdRepo`2">
|
||||
<summary>
|
||||
默认的增删改查仓储
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<typeparam name="K"></typeparam>
|
||||
</member>
|
||||
<member name="F:LFlow.Base.Default.DefaultCurdRepo`2._client">
|
||||
<summary>
|
||||
数据库连接客户端
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Default.DefaultCurdRepo`2.#ctor(SqlSugar.ISqlSugarClient)">
|
||||
<summary>
|
||||
构造函数
|
||||
</summary>
|
||||
<param name="client"></param>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Default.DefaultCurdRepo`2.DeleteById(`1)">
|
||||
<summary>
|
||||
根据ID删除对象
|
||||
</summary>
|
||||
<param name="id"></param>
|
||||
<returns></returns>
|
||||
<exception cref="T:System.Exception"></exception>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Default.DefaultCurdRepo`2.Get(`1)">
|
||||
<summary>
|
||||
根据ID获取对象
|
||||
</summary>
|
||||
<param name="id"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Default.DefaultCurdRepo`2.GetAll(System.Int32,System.Int32,System.Int32@)">
|
||||
<summary>
|
||||
批量查询(分页)
|
||||
</summary>
|
||||
<param name="pageIndex"></param>
|
||||
<param name="pageSize"></param>
|
||||
<param name="pageTotal"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Default.DefaultCurdRepo`2.SaveOrUpdate(`0,System.Boolean)">
|
||||
<summary>
|
||||
报错或是更新对象
|
||||
</summary>
|
||||
<param name="entity"></param>
|
||||
<param name="isUpdate"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Default.DefaultCurdRepo`2.Search(`0)">
|
||||
<summary>
|
||||
搜索
|
||||
</summary>
|
||||
<param name="whereObj"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Default.DefaultCurdRepo`2.WhereSearchId(`0)">
|
||||
<summary>
|
||||
查找ID
|
||||
</summary>
|
||||
<param name="whereObj"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:LFlow.Base.Interfaces.BaseController">
|
||||
<summary>
|
||||
基础控制器
|
||||
</summary>
|
||||
<example> Route("api/[controller]/[action]") ApiController </example>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Interfaces.BaseController.Success``1(``0)">
|
||||
<summary>
|
||||
成功返回
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="data"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Interfaces.BaseController.Success``1(``0,System.Int32,System.Int32,System.Int32)">
|
||||
<summary>
|
||||
成功返回(分页)
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="data"></param>
|
||||
<param name="totalCount"></param>
|
||||
<param name="pageIndex"></param>
|
||||
<param name="pageSize"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Interfaces.BaseController.Fail``1(``0,System.String,System.Int32)">
|
||||
<summary>
|
||||
失败返回
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="data"></param>
|
||||
<param name="errorMsg"></param>
|
||||
<param name="errCode"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Interfaces.BaseController.PagedFail``1(``0,System.String,System.Int32)">
|
||||
<summary>
|
||||
失败返回(分页)
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="data"></param>
|
||||
<param name="errorMsg"></param>
|
||||
<param name="errCode"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:LFlow.Base.Interfaces.IController">
|
||||
<summary>
|
||||
控制器接口
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:LFlow.Base.Interfaces.IDataModel">
|
||||
<summary>
|
||||
数据模型接口 Repo层用
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:LFlow.Base.Interfaces.IDataModel.ID">
|
||||
<summary>
|
||||
ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:LFlow.Base.Interfaces.IModel">
|
||||
<summary>
|
||||
模型顶层接口 Service层用
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:LFlow.Base.Interfaces.IModule">
|
||||
<summary>
|
||||
模块接口
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Interfaces.IModule.ConfigureModule(Microsoft.Extensions.DependencyInjection.IServiceCollection)">
|
||||
<summary>
|
||||
配置模块
|
||||
</summary>
|
||||
<param name="services"></param>
|
||||
</member>
|
||||
<member name="T:LFlow.Base.Interfaces.IRepo`2">
|
||||
<summary>
|
||||
通用的仓库对象接口
|
||||
</summary>
|
||||
<typeparam name="T">数据模型</typeparam>
|
||||
<typeparam name="K">主键</typeparam>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Interfaces.IRepo`2.Get(`1)">
|
||||
<summary>
|
||||
获取单个对象
|
||||
</summary>
|
||||
<param name="id"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Interfaces.IRepo`2.DeleteById(`1)">
|
||||
<summary>
|
||||
删除单个对象
|
||||
</summary>
|
||||
<param name="id"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Interfaces.IRepo`2.SaveOrUpdate(`0,System.Boolean)">
|
||||
<summary>
|
||||
保存与更新
|
||||
</summary>
|
||||
<param name="entity"></param>
|
||||
<param name="isUpdate"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Interfaces.IRepo`2.GetAll(System.Int32,System.Int32,System.Int32@)">
|
||||
<summary>
|
||||
获取所有对象列表(默认分页)
|
||||
</summary>
|
||||
<param name="pageIndex"></param>
|
||||
<param name="pageSize"></param>
|
||||
<param name="pageTotal"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Interfaces.IRepo`2.Search(`0)">
|
||||
<summary>
|
||||
根据条件搜索对象列表
|
||||
</summary>
|
||||
<param name="whereObj"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Interfaces.IRepo`2.WhereSearchId(`0)">
|
||||
<summary>
|
||||
根据条件搜索主键列表
|
||||
</summary>
|
||||
<param name="whereObj"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:LFlow.Base.Interfaces.IService">
|
||||
<summary>
|
||||
服务接口
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:LFlow.Base.Program">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Program.Main(System.String[])">
|
||||
<summary>
|
||||
入口
|
||||
</summary>
|
||||
<param name="args"></param>
|
||||
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Program.ConfigureSqlSugar(Microsoft.Extensions.DependencyInjection.IServiceCollection)">
|
||||
<summary>
|
||||
配置SqlSugar
|
||||
</summary>
|
||||
<param name="services"></param>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Program.LoadSubService(Microsoft.Extensions.DependencyInjection.IServiceCollection)">
|
||||
<summary>
|
||||
从子文件夹中加载DLL
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Program.ConfigDllLoader">
|
||||
<summary>
|
||||
配置DLL加载器
|
||||
接管DLL加载过程,处理依赖问题,从当前路径和Service文件夹中加载DLL
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:LFlow.Base.Utils.ApiExplorerGroupPerVersionConvention">
|
||||
<summary>
|
||||
控制器模型约定
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.ApiExplorerGroupPerVersionConvention.Apply(Microsoft.AspNetCore.Mvc.ApplicationModels.ControllerModel)">
|
||||
<summary>
|
||||
配置
|
||||
</summary>
|
||||
<param name="controller"></param>
|
||||
</member>
|
||||
<member name="T:LFlow.Base.Utils.ApiResult`1">
|
||||
<summary>
|
||||
返回结果包装
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
</member>
|
||||
<member name="P:LFlow.Base.Utils.ApiResult`1.Data">
|
||||
<summary>
|
||||
数据
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.ApiResult`1.#ctor">
|
||||
<summary>
|
||||
构造函数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.ApiResult`1.#ctor(System.Boolean,System.String,System.Int32,`0)">
|
||||
<summary>
|
||||
构造函数
|
||||
</summary>
|
||||
<param name="success"></param>
|
||||
<param name="message"></param>
|
||||
<param name="code"></param>
|
||||
<param name="data"></param>
|
||||
</member>
|
||||
<member name="P:LFlow.Base.Utils.ApiResult`1.Success">
|
||||
<summary>
|
||||
是否成功
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:LFlow.Base.Utils.ApiResult`1.Message">
|
||||
<summary>
|
||||
消息
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:LFlow.Base.Utils.ApiResult`1.Code">
|
||||
<summary>
|
||||
状态码
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.ApiResult`1.SuccessResult(`0,System.String,System.Int32)">
|
||||
<summary>
|
||||
成功返回
|
||||
</summary>
|
||||
<param name="data"></param>
|
||||
<param name="message"></param>
|
||||
<param name="code"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.ApiResult`1.FailResult(System.String,System.Int32)">
|
||||
<summary>
|
||||
失败返回
|
||||
</summary>
|
||||
<param name="message"></param>
|
||||
<param name="code"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.BucketManager.IsExistStr(System.String)">
|
||||
<summary>
|
||||
1、判断bucket是否存在
|
||||
</summary>
|
||||
<param name="bucketName"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.BucketManager.Create(System.String)">
|
||||
<summary>
|
||||
2、创建一个bucket
|
||||
</summary>
|
||||
<param name="bucketName"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.BucketManager.Delete(System.String)">
|
||||
<summary>
|
||||
3、移除一个bucket
|
||||
</summary>
|
||||
<param name="bucketName"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.BucketManager.GetList">
|
||||
<summary>
|
||||
4、获取已有的bucket列表
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:LFlow.Base.Utils.CodeFirst">
|
||||
<summary>
|
||||
CodeFirst
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:LFlow.Base.Utils.CodeFirst._types">
|
||||
<summary>
|
||||
类型集合
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.CodeFirst.AddType(System.Type)">
|
||||
<summary>
|
||||
添加类型
|
||||
</summary>
|
||||
<param name="type"></param>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.CodeFirst.InitTable">
|
||||
<summary>
|
||||
初始化表
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.CodeFirst.InitDBSeed">
|
||||
<summary>
|
||||
初始化数据库种子
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:LFlow.Base.Utils.Mapper">
|
||||
<summary>
|
||||
映射器
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.Mapper.Map``1(System.Object)">
|
||||
<summary>
|
||||
将一个对象映射到另一个对象
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="source"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.Mapper.MapTo``1(LFlow.Base.Interfaces.IDataModel)">
|
||||
<summary>
|
||||
将一个数据模型映射到另一个对象
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="model"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.MinIOService.GetBuckets">
|
||||
<summary>
|
||||
获取桶列表
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.MinIOService.DownLoad">
|
||||
<summary>
|
||||
下载接口
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:LFlow.Base.Utils.ObjectToWhereExp">
|
||||
<summary>
|
||||
对象转换为where条件
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.ObjectToWhereExp.ToWhereExp(LFlow.Base.Interfaces.IModel)">
|
||||
<summary>
|
||||
将IModel对象转换为where条件
|
||||
</summary>
|
||||
<param name="model"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:LFlow.Base.Utils.PagedApiResult`1">
|
||||
<summary>
|
||||
返回结果包装 (分页)
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
</member>
|
||||
<member name="P:LFlow.Base.Utils.PagedApiResult`1.Data">
|
||||
<summary>
|
||||
数据
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:LFlow.Base.Utils.PagedApiResult`1.TotalCount">
|
||||
<summary>
|
||||
总行数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:LFlow.Base.Utils.PagedApiResult`1.PageIndex">
|
||||
<summary>
|
||||
当前页
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:LFlow.Base.Utils.PagedApiResult`1.PageSize">
|
||||
<summary>
|
||||
每页行数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.PagedApiResult`1.#ctor">
|
||||
<summary>
|
||||
构造函数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.PagedApiResult`1.#ctor(System.Boolean,System.String,System.Int32,`0,System.Int32,System.Int32,System.Int32)">
|
||||
<summary>
|
||||
构造函数
|
||||
</summary>
|
||||
<param name="success"></param>
|
||||
<param name="message"></param>
|
||||
<param name="code"></param>
|
||||
<param name="data"></param>
|
||||
<param name="totalCount"></param>
|
||||
<param name="pageIndex"></param>
|
||||
<param name="pageSize"></param>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.PagedApiResult`1.SuccessResult(`0,System.Int32,System.Int32,System.Int32,System.String,System.Int32)">
|
||||
<summary>
|
||||
成功返回
|
||||
</summary>
|
||||
<param name="data"></param>
|
||||
<param name="totalCount"></param>
|
||||
<param name="pageIndex"></param>
|
||||
<param name="pageSize"></param>
|
||||
<param name="message"></param>
|
||||
<param name="code"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.PagedApiResult`1.FailResult(System.String,System.Int32)">
|
||||
<summary>
|
||||
失败返回
|
||||
</summary>
|
||||
<param name="message"></param>
|
||||
<param name="errCode"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:LFlow.Base.Utils.RegisterModule">
|
||||
<summary>
|
||||
注册模块
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.RegisterModule.RegisterAllModel(System.Collections.Generic.List{System.Type},Microsoft.Extensions.DependencyInjection.IServiceCollection)">
|
||||
<summary>
|
||||
注册所有模型
|
||||
</summary>
|
||||
<param name="types"></param>
|
||||
<param name="services"></param>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.RegisterModule.RegisterAllService(System.Collections.Generic.List{System.Type},Microsoft.Extensions.DependencyInjection.IServiceCollection)">
|
||||
<summary>
|
||||
注册所有服务
|
||||
</summary>
|
||||
<param name="types"></param>
|
||||
<param name="services"></param>
|
||||
</member>
|
||||
<member name="M:LFlow.Base.Utils.RegisterModule.RegisterAllRepo(System.Collections.Generic.List{System.Type},Microsoft.Extensions.DependencyInjection.IServiceCollection)">
|
||||
<summary>
|
||||
注册所有数据仓库
|
||||
</summary>
|
||||
<param name="types"></param>
|
||||
<param name="services"></param>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
|
@ -10,7 +10,14 @@ namespace LFlow.Base.Default;
|
|||
/// <typeparam name="K"></typeparam>
|
||||
public abstract class DefaultCurdRepo<T, K> : IRepo<T, K> where T : class, IDataModel, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据库连接客户端
|
||||
/// </summary>
|
||||
private readonly ISqlSugarClient _client;
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="client"></param>
|
||||
public DefaultCurdRepo(ISqlSugarClient client)
|
||||
{
|
||||
_client = client;
|
||||
|
@ -85,8 +92,8 @@ public abstract class DefaultCurdRepo<T, K> : IRepo<T, K> where T : class, IData
|
|||
/// </summary>
|
||||
/// <param name="whereObj"></param>
|
||||
/// <returns></returns>
|
||||
public virtual List<K> WhereSearchId(T whereObj)
|
||||
public virtual List<string> WhereSearchId(T whereObj)
|
||||
{
|
||||
return _client.Queryable<T>().Where(whereObj.ToWhereExp()).Select(x => (K)Convert.ChangeType(x.ID, typeof(K))).ToList();
|
||||
return _client.Queryable<T>().Where(whereObj.ToWhereExp()).Select(x => x.ID).ToList();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using LFlow.Base.Utils;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace LFlow.Base.Interfaces;
|
||||
|
@ -10,5 +11,51 @@ namespace LFlow.Base.Interfaces;
|
|||
[ApiController]
|
||||
public abstract class BaseController : ControllerBase, IController
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 成功返回
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual ApiResult<T> Success<T>(T? data) where T : class, new()
|
||||
{
|
||||
return ApiResult<T>.SuccessResult(data);
|
||||
}
|
||||
/// <summary>
|
||||
/// 成功返回(分页)
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="totalCount"></param>
|
||||
/// <param name="pageIndex"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual PagedApiResult<T> Success<T>(T? data, int totalCount, int pageIndex, int pageSize) where T : class, new()
|
||||
{
|
||||
return PagedApiResult<T>.SuccessResult(data, totalCount, pageIndex, pageSize);
|
||||
}
|
||||
/// <summary>
|
||||
/// 失败返回
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="errorMsg"></param>
|
||||
/// <param name="errCode"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual ApiResult<T> Fail<T>(T? data, string errorMsg, int errCode) where T : class, new()
|
||||
{
|
||||
return ApiResult<T>.FailResult(errorMsg, errCode);
|
||||
}
|
||||
/// <summary>
|
||||
/// 失败返回(分页)
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="errorMsg"></param>
|
||||
/// <param name="errCode"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual PagedApiResult<T>? PagedFail<T>(T? data, string errorMsg, int errCode) where T : class, new()
|
||||
{
|
||||
return PagedApiResult<T>.FailResult(errorMsg, errCode);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,5 +6,9 @@ namespace LFlow.Base.Interfaces;
|
|||
/// </summary>
|
||||
public interface IModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置模块
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
void ConfigureModule(IServiceCollection services);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ public interface IRepo<T, K> where T : IDataModel
|
|||
/// 保存与更新
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="isUpdate"></param>
|
||||
/// <returns></returns>
|
||||
T SaveOrUpdate(T entity, bool isUpdate);
|
||||
/// <summary>
|
||||
|
@ -30,6 +31,7 @@ public interface IRepo<T, K> where T : IDataModel
|
|||
/// </summary>
|
||||
/// <param name="pageIndex"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="pageTotal"></param>
|
||||
/// <returns></returns>
|
||||
List<T> GetAll(int pageIndex, int pageSize, ref int pageTotal);
|
||||
|
||||
|
@ -44,6 +46,6 @@ public interface IRepo<T, K> where T : IDataModel
|
|||
/// </summary>
|
||||
/// <param name="whereObj"></param>
|
||||
/// <returns></returns>
|
||||
List<K> WhereSearchId(T whereObj);
|
||||
List<string> WhereSearchId(T whereObj);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,17 +1,8 @@
|
|||
using LFlow.Base.Utils;
|
||||
|
||||
namespace LFlow.Base.Interfaces;
|
||||
/// <summary>
|
||||
/// ·þÎñ½Ó¿Ú
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public interface IService<T> where T : class, IModel, new()
|
||||
/// 服务接口
|
||||
/// </summary>
|
||||
public interface IService//<T> where T : class, IModel, new()
|
||||
{
|
||||
T GetById(string id);
|
||||
List<T> Search(T whereObj);
|
||||
|
||||
int DeleteById(string id);
|
||||
T Save(T entity, bool isUpdate);
|
||||
|
||||
PagedApiResult<List<T>> GetAll(int pageIndex, int pageSize);
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -8,19 +8,34 @@
|
|||
<OutputPath>../LFlow_Bin/</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<DocumentationFile>Base.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
|
||||
<PackageReference Include="Serilog" Version="4.0.2" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
|
||||
<PackageReference Include="Mapster" Version="7.4.1-pre01" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.0-rc.2.24473.5" />
|
||||
<PackageReference Include="Minio" Version="6.0.3" />
|
||||
<PackageReference Include="Serilog" Version="4.1.1-dev-02318" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
|
||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="8.0.0" />
|
||||
<PackageReference Include="Serilog.Extensions.Logging" Version="8.0.1-dev-10398" />
|
||||
<PackageReference Include="Serilog.Settings.Configuration" Version="8.0.4" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||
<PackageReference Include="SQLite" Version="3.13.0" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.169" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.8.1" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.8.1" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.171-preview03" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.9.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.9.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="wwwroot\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LFlow.Cache\LFlow.Cache.csproj" />
|
||||
<ProjectReference Include="..\LFlow.InternalEventBus\LFlow.InternalEventBus.csproj" />
|
||||
<ProjectReference Include="..\LFlow.Middleware\LFlow.Middleware.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,16 +1,35 @@
|
|||
using System.Reflection;
|
||||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Base.Utils;
|
||||
using LFlow.Cache;
|
||||
using LFlow.InternalEventBus;
|
||||
using Minio;
|
||||
using LFlow.Middleware;
|
||||
using LFlow.Middleware.Register;
|
||||
using Serilog;
|
||||
using Serilog.Events;
|
||||
using SqlSugar;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using System.Runtime;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace LFlow.Base;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class Program
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 入口
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
///
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
|
||||
// 先用Serilog的BootstrapLogger
|
||||
Log.Logger = new LoggerConfiguration()
|
||||
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
|
||||
|
@ -18,6 +37,7 @@ public static class Program
|
|||
.WriteTo.Console()
|
||||
.CreateBootstrapLogger();
|
||||
|
||||
ConfigDllLoader();
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
// 添加到Service中
|
||||
builder.Services.AddSerilog((services, lc) => lc
|
||||
|
@ -26,21 +46,49 @@ public static class Program
|
|||
.Enrich.FromLogContext()
|
||||
// .WriteTo.Console()
|
||||
);
|
||||
builder.Services.AddLogging(loggingBuilder =>
|
||||
{
|
||||
loggingBuilder.AddSerilog(Log.Logger, dispose: true);
|
||||
});
|
||||
builder.Services.AddResponseCompression();
|
||||
builder.Services.AddResponseCaching();
|
||||
|
||||
|
||||
Log.Logger.Information("LoadSubService");
|
||||
builder.Services.LoadSubService();
|
||||
|
||||
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
builder.Services.AddHttpContextAccessor();
|
||||
builder.Services.AddResponseCompression();
|
||||
|
||||
Log.Logger.Information("ConfigureSqlSugar");
|
||||
|
||||
builder.Services.ConfigureSqlSugar();
|
||||
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddControllers(c =>
|
||||
{
|
||||
c.Conventions.Add(new ApiExplorerGroupPerVersionConvention());
|
||||
});
|
||||
|
||||
//注入IMinIo
|
||||
builder.Services.AddSingleton<IMinioClient>
|
||||
(s =>
|
||||
{
|
||||
var config = builder.Configuration.GetSection("MinIoConfig");
|
||||
IMinioClient client = new MinioClient()
|
||||
.WithEndpoint(config.GetSection("endPoint").Value)
|
||||
.WithCredentials(config.GetSection("AccessKey").Value, config.GetSection("SecretKey").Value)
|
||||
.WithSSL(false)
|
||||
.Build();
|
||||
return client;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
builder.Services.AddSwaggerGen(u =>
|
||||
{
|
||||
|
||||
u.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo
|
||||
{
|
||||
Version = "Ver.1",
|
||||
|
@ -52,15 +100,45 @@ public static class Program
|
|||
Email = "noemail@ling.chat"
|
||||
}
|
||||
});
|
||||
u.IncludeXmlComments("Base.xml", true);
|
||||
// 获取自定义的xml目录
|
||||
var xmlPath = Path.Combine(System.AppContext.BaseDirectory, "Services");
|
||||
DirectoryInfo dir = new(xmlPath);
|
||||
// 获取目录下的所有xml文件,并设置为swagger文档包含文件
|
||||
dir.GetFiles("*.xml").ToList().ForEach(f =>
|
||||
{
|
||||
u.IncludeXmlComments(f.FullName, true);
|
||||
|
||||
u.SwaggerDoc(Path.GetFileNameWithoutExtension(f.Name), new Microsoft.OpenApi.Models.OpenApiInfo
|
||||
{
|
||||
Version = "Ver.1",
|
||||
Title = Path.GetFileNameWithoutExtension(f.Name),
|
||||
Description = "LFlow api test and document",
|
||||
});
|
||||
});
|
||||
});
|
||||
// 使用Serilog,此处为了修复 `The logger is already frozen` 的问题,重新配置Serilog
|
||||
builder.Host.UseSerilog((context, services, config) =>
|
||||
|
||||
|
||||
// 配置跨域策略
|
||||
builder.Services.AddCors(options =>
|
||||
{
|
||||
config.ReadFrom.Configuration(context.Configuration)
|
||||
.ReadFrom.Services(services)
|
||||
.Enrich.FromLogContext();
|
||||
// .WriteTo.Console();
|
||||
}, true);
|
||||
options.AddPolicy("AllowAny", builder =>
|
||||
{
|
||||
builder.AllowAnyOrigin()
|
||||
.AllowAnyMethod()
|
||||
.AllowAnyHeader();
|
||||
});
|
||||
});
|
||||
builder.Host.UseSerilog(Log.Logger);
|
||||
// 注册中间件
|
||||
builder.Services.RegisterMiddlewares(App.SubServiceAssembly);
|
||||
|
||||
// 注册内部事件总线
|
||||
builder.Services.AddInternalEventBus(App.SubServiceAssembly);
|
||||
// 注册自身缓存器
|
||||
builder.Services.AddSelfCache();
|
||||
|
||||
|
||||
// init App.service
|
||||
App.services = builder.Services;
|
||||
var app = builder.Build();
|
||||
|
@ -70,13 +148,26 @@ public static class Program
|
|||
options.GetLevel = (httpContext, elapsed, ex) => LogEventLevel.Information;
|
||||
});
|
||||
app.MapControllers();
|
||||
// app.MapGet("/", () => "Hello World!");
|
||||
// 添加根目录映射
|
||||
app.MapGet("/", async context =>
|
||||
{
|
||||
context.Response.ContentType = "text/html";
|
||||
await context.Response.SendFileAsync(Path.Combine(app.Environment.WebRootPath, "index.html"));
|
||||
});
|
||||
// if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI(u =>
|
||||
{
|
||||
u.DocumentTitle = "LFlow";
|
||||
var xmlPath = Path.Combine(System.AppContext.BaseDirectory, "Services");
|
||||
DirectoryInfo dir = new(xmlPath);
|
||||
// 获取目录下的所有xml文件,并设置为swagger文档包含文件
|
||||
dir.GetFiles("*.xml").ToList().ForEach(f =>
|
||||
{
|
||||
var progName = Path.GetFileNameWithoutExtension(f.Name);
|
||||
u.SwaggerEndpoint($"/swagger/{progName}/swagger.json", progName);
|
||||
});
|
||||
});
|
||||
}
|
||||
// 在启动后调用Sqlsugar进行CodeFirst
|
||||
|
@ -85,10 +176,28 @@ public static class Program
|
|||
{
|
||||
Log.Logger.Information("ApplicationStarted");
|
||||
CodeFirst.InitTable();
|
||||
InternalEventBus.InternalEventBus.Publish("Init", "ApplicationStarted");
|
||||
});
|
||||
// 启用自定义中间件
|
||||
app.UseLFlowMiddleware();
|
||||
// 启用内部事件总线
|
||||
app.UseInternalEventBus();
|
||||
// 启用缓存
|
||||
app.UseResponseCaching();
|
||||
// 启用压缩
|
||||
app.UseResponseCompression();
|
||||
// 启用静态文件支持
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseCors("AllowAny");
|
||||
app.Run();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 配置SqlSugar
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
public static void ConfigureSqlSugar(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<ISqlSugarClient>(s =>
|
||||
|
@ -98,6 +207,7 @@ public static class Program
|
|||
DbType = SqlSugar.DbType.Sqlite,
|
||||
ConnectionString = "DataSource=LFlow-dev.db",
|
||||
IsAutoCloseConnection = true,
|
||||
InitKeyType = InitKeyType.Attribute //从实体特性中读取主键自增列信息
|
||||
},
|
||||
db =>
|
||||
{
|
||||
|
@ -106,9 +216,10 @@ public static class Program
|
|||
{
|
||||
//获取作IOC作用域对象
|
||||
var appServive = s.GetService<IHttpContextAccessor>();
|
||||
var log = s.GetService<Serilog.ILogger>();
|
||||
// var obj = appServive?.HttpContext?.RequestServices.GetService<Log>();
|
||||
// Console.WriteLine("AOP" + obj.GetHashCode());
|
||||
Console.WriteLine($"{appServive?.HttpContext?.Request.Path}:{sql}\r\n{pars}");
|
||||
log?.Debug($"{appServive?.HttpContext?.Request.Path}:{sql}\r\n{pars}");
|
||||
};
|
||||
});
|
||||
sqlSugar.DbMaintenance.CreateDatabase();
|
||||
|
@ -121,6 +232,7 @@ public static class Program
|
|||
/// </summary>
|
||||
public static void LoadSubService(this IServiceCollection services)
|
||||
{
|
||||
//TODO: 从配置文件中读取加载路径
|
||||
var path = Path.Combine(AppContext.BaseDirectory, "Services");
|
||||
// Console.WriteLine(path);
|
||||
var files = Directory.GetFiles(path, "*.dll");
|
||||
|
@ -128,40 +240,91 @@ public static class Program
|
|||
{
|
||||
foreach (var file in files)
|
||||
{
|
||||
Log.Logger.Information($"Load file -> {file}...");
|
||||
var assembly = Assembly.LoadFile(file);
|
||||
var types = assembly.GetTypes();
|
||||
// bool isUseController = false;
|
||||
foreach (var type in types)
|
||||
try
|
||||
{
|
||||
// Console.WriteLine(type);
|
||||
if (type.IsClass && !type.IsAbstract)
|
||||
bool isModule = false;
|
||||
Log.Logger.Information($"Load file -> {file}...");
|
||||
var assembly = Assembly.LoadFile(file);
|
||||
var types = assembly.GetTypes();
|
||||
// bool isUseController = false;
|
||||
foreach (var type in types)
|
||||
{
|
||||
var interfaces = type.GetInterfaces();
|
||||
if (interfaces.Contains(typeof(IModule)))
|
||||
// Console.WriteLine(type);
|
||||
if (type.IsClass && !type.IsAbstract)
|
||||
{
|
||||
Log.Logger.Information($"\tFound IModule -> {type.FullName}");
|
||||
var module = Activator.CreateInstance(type) as IModule;
|
||||
module?.ConfigureModule(services);
|
||||
var interfaces = type.GetInterfaces();
|
||||
if (interfaces.Contains(typeof(IModule)))
|
||||
{
|
||||
Log.Logger.Information($"\tFound IModule -> {type.FullName}");
|
||||
var module = Activator.CreateInstance(type) as IModule;
|
||||
module?.ConfigureModule(services);
|
||||
isModule = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (isUseController)
|
||||
// {
|
||||
// Log.Logger.Information($"\tAdd Controllers for {assembly.FullName}");
|
||||
// // 添加Controller
|
||||
// services.AddControllers().AddApplicationPart(assembly);
|
||||
// }
|
||||
if (isModule)
|
||||
{
|
||||
App.SubServiceAssembly.Add(assembly);
|
||||
}
|
||||
Log.Logger.Information("done.\r\n");
|
||||
}
|
||||
// if (isUseController)
|
||||
// {
|
||||
// Log.Logger.Information($"\tAdd Controllers for {assembly.FullName}");
|
||||
// // 添加Controller
|
||||
// services.AddControllers().AddApplicationPart(assembly);
|
||||
// }
|
||||
Log.Logger.Information("done.\r\n");
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Logger.Error(ex, $"Load file -> {file} error.");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.ToString());
|
||||
throw;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置DLL加载器
|
||||
/// 接管DLL加载过程,处理依赖问题,从当前路径和Service文件夹中加载DLL
|
||||
/// </summary>
|
||||
public static void ConfigDllLoader()
|
||||
{
|
||||
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
|
||||
{
|
||||
var assemblyName = new AssemblyName(args.Name);
|
||||
|
||||
}
|
||||
// 判断是否已经被加载 避免重复加载
|
||||
var loadedAssembly = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.FirstOrDefault(a => a.FullName == assemblyName.FullName);
|
||||
if (loadedAssembly != null)
|
||||
{
|
||||
Log.Logger?.Information($"Assembly {assemblyName.Name} has been loaded.");
|
||||
return loadedAssembly;
|
||||
}
|
||||
|
||||
// 从当前路径下加载
|
||||
var path = Path.Combine(AppContext.BaseDirectory, $"{assemblyName.Name}.dll");
|
||||
if (File.Exists(path))
|
||||
{
|
||||
Log.Logger?.Information($"Assembly {assemblyName.Name} has been loaded for {path}.");
|
||||
return Assembly.LoadFile(path);
|
||||
}
|
||||
|
||||
// 从Service文件夹中加载
|
||||
path = Path.Combine(AppContext.BaseDirectory, "Service", $"{assemblyName.Name}.dll");
|
||||
if (File.Exists(path))
|
||||
{
|
||||
Log.Logger?.Information($"Assembly {assemblyName.Name} has been loaded for {path}.");
|
||||
return Assembly.LoadFile(path);
|
||||
}
|
||||
Log.Logger?.Error($"Assembly {assemblyName.Name} not found.");
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||
using Serilog;
|
||||
|
||||
namespace LFlow.Base.Utils
|
||||
{
|
||||
/// <summary>
|
||||
/// 控制器模型约定
|
||||
/// </summary>
|
||||
public class ApiExplorerGroupPerVersionConvention : IControllerModelConvention
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置
|
||||
/// </summary>
|
||||
/// <param name="controller"></param>
|
||||
public void Apply(ControllerModel controller)
|
||||
{
|
||||
foreach (var action in controller.Actions)
|
||||
{
|
||||
action.ApiExplorer.GroupName = controller.ControllerName;
|
||||
action.ApiExplorer.IsVisible = true;
|
||||
Log.Logger.Information($"ApiExplorerGroup added -> {controller.ControllerName} / {action.ActionName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,29 +7,73 @@
|
|||
[Serializable]
|
||||
public class ApiResult<T> where T : class, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据
|
||||
/// </summary>
|
||||
public T? Data
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public ApiResult()
|
||||
{
|
||||
}
|
||||
|
||||
public ApiResult(bool success, string message, T data)
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="success"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="data"></param>
|
||||
public ApiResult(bool success, string message, int code, T? data)
|
||||
{
|
||||
Success = success;
|
||||
Message = message;
|
||||
Code = code;
|
||||
Data = data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否成功
|
||||
/// </summary>
|
||||
public bool Success
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 消息
|
||||
/// </summary>
|
||||
public string? Message
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
/// <summary>
|
||||
/// 状态码
|
||||
/// </summary>
|
||||
public int? Code
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
/// <summary>
|
||||
/// 成功返回
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="code"></param>
|
||||
/// <returns></returns>
|
||||
public static ApiResult<T> SuccessResult(T? data, string message = "操作成功", int code = 200)
|
||||
{
|
||||
return new ApiResult<T>(true, message, code, data);
|
||||
}
|
||||
/// <summary>
|
||||
/// 失败返回
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="code"></param>
|
||||
/// <returns></returns>
|
||||
public static ApiResult<T> FailResult(string message = "操作失败", int code = 500)
|
||||
{
|
||||
return new ApiResult<T>(false, message, code, default);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
using Minio.DataModel.Args;
|
||||
using Minio.DataModel.Result;
|
||||
using Minio.Exceptions;
|
||||
using Minio;
|
||||
|
||||
|
||||
|
||||
namespace LFlow.Base.Utils
|
||||
{
|
||||
public class BucketManager
|
||||
{
|
||||
public static IMinioClient minioClient;
|
||||
|
||||
public BucketManager(IMinioClient IminioClient) {
|
||||
|
||||
minioClient= IminioClient;
|
||||
}
|
||||
/// <summary>
|
||||
/// 1、判断bucket是否存在
|
||||
/// </summary>
|
||||
/// <param name="bucketName"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task<string> IsExistStr(string bucketName)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
BucketExistsArgs args = new BucketExistsArgs().WithBucket(bucketName);
|
||||
|
||||
bool found = await minioClient.BucketExistsAsync(args).ConfigureAwait(false);
|
||||
|
||||
Console.WriteLine("found。。。。。。", found);
|
||||
|
||||
if (found)
|
||||
{
|
||||
Console.WriteLine($"{bucketName}桶已存在");
|
||||
return $"{bucketName}桶已存在";
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"{bucketName}桶不存在");
|
||||
return $"{bucketName}桶不存在";
|
||||
}
|
||||
}
|
||||
catch (MinioException e)
|
||||
{
|
||||
Console.WriteLine("[Bucket] Exception: {0}", e);
|
||||
return "出错啦!!!";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 2、创建一个bucket
|
||||
/// </summary>
|
||||
/// <param name="bucketName"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task<string> Create(string? bucketName)
|
||||
{
|
||||
try
|
||||
{
|
||||
BucketExistsArgs args = new BucketExistsArgs().WithBucket(bucketName);
|
||||
|
||||
bool found = await minioClient.BucketExistsAsync(args).ConfigureAwait(false);
|
||||
|
||||
if (found)
|
||||
{
|
||||
return $"{bucketName}桶已存在";
|
||||
}
|
||||
else
|
||||
{
|
||||
MakeBucketArgs makeBucketArgs = new MakeBucketArgs().WithBucket(bucketName);
|
||||
await minioClient.MakeBucketAsync(makeBucketArgs).ConfigureAwait(false);
|
||||
|
||||
return $"{bucketName}桶已成功创建";
|
||||
}
|
||||
}
|
||||
catch (MinioException e)
|
||||
{
|
||||
Console.WriteLine("[Bucket] Exception: {0}", e);
|
||||
return "出错啦!!!";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 3、移除一个bucket
|
||||
/// </summary>
|
||||
/// <param name="bucketName"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task<string> Delete(string? bucketName)
|
||||
{
|
||||
try
|
||||
{
|
||||
BucketExistsArgs args = new BucketExistsArgs().WithBucket(bucketName);
|
||||
|
||||
bool found = await minioClient.BucketExistsAsync(args).ConfigureAwait(false);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
return $"{bucketName}桶不存在";
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveBucketArgs removeBucketArgs = new RemoveBucketArgs().WithBucket(bucketName);
|
||||
|
||||
await minioClient.RemoveBucketAsync(removeBucketArgs);
|
||||
|
||||
return $"{bucketName}桶删除成功";
|
||||
}
|
||||
}
|
||||
catch (MinioException e)
|
||||
{
|
||||
Console.WriteLine("[Bucket] Exception: {0}", e);
|
||||
return "出错啦!!!";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 4、获取已有的bucket列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static async Task<ListAllMyBucketsResult?> GetList()
|
||||
{
|
||||
try
|
||||
{
|
||||
return await minioClient.ListBucketsAsync();
|
||||
}
|
||||
catch (MinioException e)
|
||||
{
|
||||
Console.WriteLine("Error occurred: " + e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,19 +1,28 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net;
|
||||
using Serilog;
|
||||
using SqlSugar;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace LFlow.Base.Utils;
|
||||
|
||||
/// <summary>
|
||||
/// CodeFirst
|
||||
/// </summary>
|
||||
public static class CodeFirst
|
||||
{
|
||||
// 线程安全的类型列表
|
||||
private static readonly ConcurrentBag<Type> _types = new();
|
||||
|
||||
/// <summary>
|
||||
/// 类型集合
|
||||
/// </summary>
|
||||
private static readonly ConcurrentBag<Type> _types = [];
|
||||
/// <summary>
|
||||
/// 添加类型
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
public static void AddType(Type type)
|
||||
{
|
||||
_types.Add(type);
|
||||
}
|
||||
/// <summary>
|
||||
/// 初始化表
|
||||
/// </summary>
|
||||
internal static void InitTable()
|
||||
{
|
||||
var logger = App.GetService<Serilog.ILogger>()!;
|
||||
|
@ -25,6 +34,9 @@ public static class CodeFirst
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化数据库种子
|
||||
/// </summary>
|
||||
internal static void InitDBSeed()
|
||||
{
|
||||
//TODO: Seed data
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
using System;
|
||||
using LFlow.Base.Interfaces;
|
||||
using Mapster;
|
||||
|
||||
namespace LFlow.Base.Utils;
|
||||
|
||||
public class Mapper
|
||||
/// <summary>
|
||||
/// 映射器
|
||||
/// </summary>
|
||||
public static class Mapper
|
||||
{
|
||||
/// <summary>
|
||||
/// 将一个对象映射到另一个对象
|
||||
|
@ -19,4 +21,18 @@ public class Mapper
|
|||
}
|
||||
return source.Adapt<T>();
|
||||
}
|
||||
/// <summary>
|
||||
/// 将一个数据模型映射到另一个对象
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
public static T? MapTo<T>(this IDataModel model)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
return model.Adapt<T>();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
using Microsoft.VisualBasic.FileIO;
|
||||
using Minio;
|
||||
using Minio.DataModel;
|
||||
using Minio.DataModel.Args;
|
||||
using Minio.Exceptions;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
namespace LFlow.Base.Utils
|
||||
{
|
||||
public class MinIOService
|
||||
{
|
||||
private readonly IMinioClient minioClient;
|
||||
private readonly BucketManager bucketManager;
|
||||
private static string bucketName = "testbucket";
|
||||
|
||||
public MinIOService(IMinioClient _minioClient)
|
||||
{
|
||||
minioClient = _minioClient;
|
||||
bucketManager = new BucketManager(_minioClient);
|
||||
}
|
||||
|
||||
|
||||
public async Task<string> Upload(IFormFile file)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
//logger.LogInformation("文件开始上传");
|
||||
string uploadsPath = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "uploads");
|
||||
if (!Directory.Exists(uploadsPath))
|
||||
{
|
||||
Directory.CreateDirectory(uploadsPath);
|
||||
}
|
||||
string fileName = file.FileName;
|
||||
// string filePath = Path.Combine(uploadsPath, fileName);
|
||||
// string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
|
||||
// string fileExtension = Path.GetExtension(fileName);
|
||||
// string newFileName = null;
|
||||
// int counter = 1;
|
||||
// while (File.Exists(filePath))
|
||||
// {
|
||||
// //重新命名文件
|
||||
// string Name = $"{fileNameWithoutExtension}_{counter}{fileExtension}";
|
||||
// filePath = Path.Combine(uploadsPath, Name);
|
||||
// newFileName = Path.GetFileNameWithoutExtension(filePath);
|
||||
// counter++;
|
||||
// }
|
||||
// if (newFileName == null)
|
||||
// {
|
||||
// newFileName = Path.GetFileNameWithoutExtension(fileName);
|
||||
// }
|
||||
// using (var stream = new FileStream(filePath, FileMode.Create))
|
||||
// {
|
||||
// file.CopyTo(stream);
|
||||
// }
|
||||
|
||||
//AddFileInfo(filePath, Path.GetFileNameWithoutExtension(fileName), newFileName);
|
||||
var beArgs = new BucketExistsArgs()
|
||||
.WithBucket(bucketName);
|
||||
|
||||
bool found = await minioClient.BucketExistsAsync(beArgs);
|
||||
if (!found)
|
||||
{
|
||||
var mbArgs = new MakeBucketArgs()
|
||||
.WithBucket(bucketName);
|
||||
await minioClient.MakeBucketAsync(mbArgs).ConfigureAwait(false);
|
||||
}
|
||||
// 设置上传文件的对象名
|
||||
var objectName = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName);
|
||||
var putObjectArgs = new PutObjectArgs()
|
||||
.WithBucket(bucketName)
|
||||
.WithObject(objectName)
|
||||
// .WithFileName(filePath)
|
||||
.WithStreamData(file.OpenReadStream())
|
||||
.WithObjectSize(file.Length)
|
||||
.WithContentType(file.ContentType);
|
||||
var response = await minioClient.PutObjectAsync(putObjectArgs);
|
||||
|
||||
Console.WriteLine($"文件 '{fileName}' 上传到 bucket '{bucketName}' 中,文件名为 '{objectName}'。");
|
||||
return objectName;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 处理异常
|
||||
throw new ApplicationException("文件上传失败", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取桶列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<string>> GetBuckets()
|
||||
{
|
||||
var list = await minioClient.ListBucketsAsync().ConfigureAwait(false);
|
||||
var buckets = list.Buckets.Select(b => b.Name).ToList();
|
||||
return buckets;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 下载接口
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task DownLoad()
|
||||
{
|
||||
try
|
||||
{
|
||||
StatObjectArgs statObjectArgs = new StatObjectArgs()
|
||||
.WithBucket(bucketName)
|
||||
.WithObject("替换你上传到minio服务器中生成的objectName");
|
||||
await minioClient.StatObjectAsync(statObjectArgs);
|
||||
|
||||
GetObjectArgs getObjectArgs = new GetObjectArgs()
|
||||
.WithBucket(bucketName)
|
||||
.WithObject("替换你上传到minio服务器中生成的objectName")
|
||||
.WithFile("D:\\photo.jpg"); //替换你实际的文件输出路径
|
||||
await minioClient.GetObjectAsync(getObjectArgs);
|
||||
}
|
||||
catch (MinioException e)
|
||||
{
|
||||
Console.Out.WriteLine("Error occurred:" + e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 后缀名枚举
|
||||
/// </summary>
|
||||
/// <param name="fileExtension"></param>
|
||||
/// <returns></returns>
|
||||
//public string DetermineFileType(string fileExtension)
|
||||
//{
|
||||
// HashSet<string> supportedImageExtensions = new HashSet<string>
|
||||
// {
|
||||
// ".jpg",".jpeg", ".png",".gif",".bmp",".tiff",".tif",".svg",".webp", ".ico"
|
||||
// };
|
||||
|
||||
// HashSet<string> supportedVideoExtensions = new HashSet<string>
|
||||
// {
|
||||
// ".mp4",".avi",".mkv",".mov",".wmv",".flv",".webm"
|
||||
// };
|
||||
|
||||
// HashSet<string> supportedDocumentExtensions = new HashSet<string>
|
||||
// {
|
||||
// ".doc",".docx",".pdf",".txt",".ppt",".pptx",".xls",".xlsx",
|
||||
// };
|
||||
// if (supportedDocumentExtensions.Contains(fileExtension.ToLower()))
|
||||
// {
|
||||
// return FileType.document.ToString();
|
||||
// }
|
||||
// else if (supportedImageExtensions.Contains(fileExtension.ToLower()))
|
||||
// {
|
||||
// return FileType.image.ToString();
|
||||
// }
|
||||
// else if (supportedVideoExtensions.Contains(fileExtension.ToLower()))
|
||||
// {
|
||||
// return FileType.video.ToString();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return FileType.other.ToString();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
|
||||
namespace LFlow.Base.Utils;
|
||||
|
||||
/// <summary>
|
||||
/// 对象转换为where条件
|
||||
/// </summary>
|
||||
public static class ObjectToWhereExp
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -24,7 +26,7 @@ public static class ObjectToWhereExp
|
|||
}
|
||||
else if (property.PropertyType == typeof(DateTime) && value is DateTime dateTime)
|
||||
{
|
||||
if (dateTime != default(DateTime))
|
||||
if (dateTime != default)
|
||||
{
|
||||
whereExp += $" and {property.Name} like '%{value}%'";
|
||||
}
|
||||
|
|
|
@ -7,37 +7,83 @@
|
|||
[Serializable]
|
||||
public class PagedApiResult<T> : ApiResult<T> where T : class, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据
|
||||
/// </summary>
|
||||
public new T? Data
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
/// <summary>
|
||||
/// 总行数
|
||||
/// </summary>
|
||||
public int TotalCount
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前页
|
||||
/// </summary>
|
||||
public int PageIndex
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 每页行数
|
||||
/// </summary>
|
||||
public int PageSize
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
public PagedApiResult()
|
||||
{
|
||||
}
|
||||
|
||||
public PagedApiResult(bool success, string message, T data, int totalCount, int pageIndex, int pageSize)
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="success"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="totalCount"></param>
|
||||
/// <param name="pageIndex"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
public PagedApiResult(bool success, string message, int code, T? data, int totalCount, int pageIndex, int pageSize)
|
||||
{
|
||||
Success = success;
|
||||
Message = message;
|
||||
Code = code;
|
||||
Data = data;
|
||||
TotalCount = totalCount;
|
||||
PageIndex = pageIndex;
|
||||
PageSize = pageSize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 成功返回
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="totalCount"></param>
|
||||
/// <param name="pageIndex"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="code"></param>
|
||||
/// <returns></returns>
|
||||
public static PagedApiResult<T> SuccessResult(T? data, int totalCount, int pageIndex, int pageSize, string message = "操作成功", int code = 200)
|
||||
{
|
||||
return new PagedApiResult<T>(true, message, code, data, totalCount, pageIndex, pageSize);
|
||||
}
|
||||
/// <summary>
|
||||
/// 失败返回
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="errCode"></param>
|
||||
/// <returns></returns>
|
||||
public static new PagedApiResult<T>? FailResult(string message = "操作失败", int errCode = 500)
|
||||
{
|
||||
return new PagedApiResult<T>(false, message, errCode, null, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
namespace LFlow.Base.Utils;
|
||||
|
||||
/// <summary>
|
||||
/// 注册模块
|
||||
/// </summary>
|
||||
public static class RegisterModule
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -1,21 +1,28 @@
|
|||
{
|
||||
"Serilog": {
|
||||
"MinimumLevel": {
|
||||
"Default": "Debug",
|
||||
"Override": {
|
||||
"Microsoft.AspNetCore.Mvc": "Debug",
|
||||
"Microsoft.AspNetCore.Routing": "Debug",
|
||||
"Microsoft.AspNetCore.Hosting": "Debug"
|
||||
}
|
||||
"Urls": "http://*:8088;http://*:3453",
|
||||
"Serilog": {
|
||||
"MinimumLevel": {
|
||||
"Default": "Information",
|
||||
"Override": {
|
||||
"Microsoft.AspNetCore.Mvc": "Debug",
|
||||
"Microsoft.AspNetCore.Routing": "Debug",
|
||||
"Microsoft.AspNetCore.Hosting": "Debug"
|
||||
}
|
||||
},
|
||||
"WriteTo": [
|
||||
{
|
||||
"Name": "Console"
|
||||
}
|
||||
]
|
||||
},
|
||||
"WriteTo": [
|
||||
{
|
||||
"Name": "Console"
|
||||
}
|
||||
]
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "Data Source=192.168.3.85;Initial Catalog=PluginAdmin-dev;User Id=sa;Password=Sa1234;Encrypt=True;TrustServerCertificate=True"
|
||||
}
|
||||
"MinIoConfig": {
|
||||
"EndPoint": "192.168.3.85:9000",
|
||||
"AccessKey": "minioadmin",
|
||||
"SecretKey": "minioadmin",
|
||||
"UseSSL": true
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "Data Source=192.168.3.85;Initial Catalog=PluginAdmin-dev;User Id=sa;Password=Sa1234;Encrypt=True;TrustServerCertificate=True"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
using LFlow.Cache.Interface;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
|
||||
namespace LFlow.Cache.Cacher
|
||||
{
|
||||
/// <summary>
|
||||
/// 自身的单实例缓存
|
||||
/// </summary>
|
||||
public class SelfSingleCache : ISelfCache
|
||||
{
|
||||
protected MemoryCache _cache = new(new MemoryCacheOptions()
|
||||
{
|
||||
ExpirationScanFrequency = new TimeSpan(0, 0, 10)
|
||||
});
|
||||
|
||||
public MemoryCache CacheProvider => _cache;
|
||||
|
||||
|
||||
public Task ClearAsync()
|
||||
{
|
||||
CacheProvider.Clear();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task<T?> GetAsync<T>(string key)
|
||||
{
|
||||
return Task.FromResult(CacheProvider.Get<T>(key));
|
||||
}
|
||||
|
||||
public Task<object?> GetAsync(string key)
|
||||
{
|
||||
return Task.FromResult(CacheProvider.Get(key));
|
||||
}
|
||||
|
||||
public Task RemoveAsync(string key)
|
||||
{
|
||||
if (CacheProvider.TryGetValue(key, out _))
|
||||
CacheProvider.Remove(key);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task SetAsync<T>(string key, T data)
|
||||
{
|
||||
CacheProvider.Set(key, data);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task SetAsync<T>(string key, T data, TimeSpan expiredTime)
|
||||
{
|
||||
CacheProvider.Set(key, data, expiredTime);
|
||||
return Task.CompletedTask;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
using Microsoft.Extensions.Caching.Memory;
|
||||
|
||||
namespace LFlow.Cache.Interface
|
||||
{
|
||||
/// <summary>
|
||||
/// 自身缓存接口
|
||||
/// 后续扩展,可分为内部缓存和外部缓存
|
||||
/// ISelfCache 只作为内部缓存接口
|
||||
/// 内外部缓存的区别在于,内部缓存是程序自身的缓存,外部缓存则可共享给其他系统,并暴露在外
|
||||
/// </summary>
|
||||
public interface ISelfCache
|
||||
{
|
||||
/// <summary>
|
||||
/// 缓存提供者,目前只支持MemoryCache,后续可扩展为使用接口,然后实现不同的缓存提供者
|
||||
/// </summary>
|
||||
protected MemoryCache CacheProvider { get; }
|
||||
/// <summary>
|
||||
/// 获取
|
||||
/// </summary>
|
||||
/// <typeparam name="T">类型</typeparam>
|
||||
/// <param name="key">键</param>
|
||||
/// <returns></returns>
|
||||
Task<T?> GetAsync<T>(string key);
|
||||
/// <summary>
|
||||
/// 获取
|
||||
/// </summary>
|
||||
/// <param name="key">键</param>
|
||||
/// <returns></returns>
|
||||
Task<object?> GetAsync(string key);
|
||||
/// <summary>
|
||||
/// 存入一个值
|
||||
/// </summary>
|
||||
/// <typeparam name="T">数据类型</typeparam>
|
||||
/// <param name="key">键</param>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
Task SetAsync<T>(string key, T data);
|
||||
/// <summary>
|
||||
/// 存入一个值
|
||||
/// </summary>
|
||||
/// <typeparam name="T">数据类型</typeparam>
|
||||
/// <param name="key">键</param>
|
||||
/// <param name="data">数据</param>
|
||||
/// <param name="expiredTime">过期时间</param>
|
||||
/// <returns></returns>
|
||||
Task SetAsync<T>(string key, T data, TimeSpan expiredTime);
|
||||
/// <summary>
|
||||
/// 移除一个键与他的值
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
Task RemoveAsync(string key);
|
||||
/// <summary>
|
||||
/// 清空缓存
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task ClearAsync();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputPath>../LFlow_Bin/</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<UseCommonOutputDirectory>true</UseCommonOutputDirectory>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.0-rc.2.24473.5" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,16 @@
|
|||
using LFlow.Cache.Cacher;
|
||||
using LFlow.Cache.Interface;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace LFlow.Cache
|
||||
{
|
||||
public static class MemoryCacheExtensions
|
||||
{
|
||||
public static void AddSelfCache(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<ISelfCache, SelfSingleCache>();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
namespace LFlow.InternalEventBus.Interface
|
||||
{
|
||||
public interface IInternalEventSubscriber
|
||||
{
|
||||
int Priority { get; }
|
||||
string EventName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 事件处理,返回是否处理成功
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> Handle(object data);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
using LFlow.InternalEventBus.Interface;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace LFlow.InternalEventBus
|
||||
{
|
||||
public class InternalEventBus
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, List<IInternalEventSubscriber>> _eventSubscriberDict = new();
|
||||
/// <summary>
|
||||
/// 注册事件
|
||||
/// </summary>
|
||||
/// <param name="eventName"></param>
|
||||
/// <param name="subscriber"></param>
|
||||
public static void Register(string eventName, IInternalEventSubscriber subscriber)
|
||||
{
|
||||
if (!_eventSubscriberDict.ContainsKey(eventName))
|
||||
{
|
||||
_eventSubscriberDict.TryAdd(eventName, []);
|
||||
}
|
||||
_eventSubscriberDict[eventName].Add(subscriber);
|
||||
}
|
||||
/// <summary>
|
||||
/// 取消注册事件
|
||||
/// </summary>
|
||||
/// <param name="eventName"></param>
|
||||
/// <param name="subscriber"></param>
|
||||
public static void UnRegister(string eventName, IInternalEventSubscriber subscriber)
|
||||
{
|
||||
if (_eventSubscriberDict.ContainsKey(eventName))
|
||||
{
|
||||
_eventSubscriberDict[eventName].Remove(subscriber);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 发布事件
|
||||
/// </summary>
|
||||
/// <param name="eventName"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public static async void Publish(string eventName, object data)
|
||||
{
|
||||
if (_eventSubscriberDict.ContainsKey(eventName))
|
||||
{
|
||||
foreach (var subscriber in _eventSubscriberDict[eventName].OrderBy(i => i.Priority))
|
||||
{
|
||||
var isContinue = await subscriber.Handle(data);
|
||||
if (!isContinue)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 发布事件
|
||||
/// </summary>
|
||||
/// <param name="eventName"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task PublishAsync(string eventName, object data)
|
||||
{
|
||||
await Task.Factory.StartNew(() => Publish(eventName, data));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
using LFlow.InternalEventBus.Interface;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LFlow.InternalEventBus
|
||||
{
|
||||
|
||||
public static class InternalEventBusExtensions
|
||||
{
|
||||
private static readonly ConcurrentDictionary<Type, IInternalEventSubscriber> _eventSubscribers = new();
|
||||
private static readonly ConcurrentBag<Type> _eventSubscriberTypes = [];
|
||||
/// <summary>
|
||||
/// 添加事件订阅服务
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="assemblies"></param>
|
||||
public static void AddInternalEventBus(this IServiceCollection services, List<Assembly> assemblies)
|
||||
{
|
||||
assemblies?.ForEach(assembly =>
|
||||
{
|
||||
var types = assembly.GetTypes().ToList();
|
||||
foreach (var type in types)
|
||||
{
|
||||
if (type.GetInterface(nameof(IInternalEventSubscriber)) != null)
|
||||
{
|
||||
services.AddSingleton(type);
|
||||
_eventSubscriberTypes.Add(type);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
/// <summary>
|
||||
/// 构建事件对象列表
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
private static void BuildInternalEventBusServiceProvider(this IApplicationBuilder app)
|
||||
{
|
||||
var serviceProvider = app.ApplicationServices;
|
||||
_eventSubscriberTypes.ToList().ForEach(type =>
|
||||
{
|
||||
if (serviceProvider.GetService(type) is IInternalEventSubscriber subscriber)
|
||||
_eventSubscribers.TryAdd(type, subscriber);
|
||||
});
|
||||
}
|
||||
/// <summary>
|
||||
/// 启用内部事件
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
public static void UseInternalEventBus(this IApplicationBuilder app)
|
||||
{
|
||||
// build serviceProvider and eventSubscribers
|
||||
app.BuildInternalEventBusServiceProvider();
|
||||
// sort by priority
|
||||
var orderedSubscribers = _eventSubscribers.Values.OrderBy(t => t?.Priority ?? 0).ToList();
|
||||
orderedSubscribers.ForEach(subscriber =>
|
||||
{
|
||||
if (subscriber is IInternalEventSubscriber eventSubscriber)
|
||||
{
|
||||
InternalEventBus.Register(eventSubscriber.EventName, eventSubscriber);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputPath>../LFlow_Bin/</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<UseCommonOutputDirectory>true</UseCommonOutputDirectory>
|
||||
<OutputType>Library</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Enum\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,19 @@
|
|||
namespace LFlow.Middleware
|
||||
{
|
||||
|
||||
public interface ILFlowMiddleware
|
||||
{
|
||||
/// <summary>
|
||||
/// 优先级
|
||||
/// </summary>
|
||||
int Priority { get; }
|
||||
/// <summary>
|
||||
/// 中间件执行入口
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="next"></param>
|
||||
/// <returns></returns>
|
||||
Task RunAsync(HttpContext context, Func<Task> next);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputPath>../LFlow_Bin/</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<UseCommonOutputDirectory>true</UseCommonOutputDirectory>
|
||||
<OutputType>Library</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,19 @@
|
|||
using LFlow.Middleware.Register;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
||||
namespace LFlow.Middleware
|
||||
{
|
||||
public static class MiddlewareExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Use LFlow Middleware
|
||||
/// 配置中间件
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
public static async void UseLFlowMiddleware(this IApplicationBuilder app)
|
||||
{
|
||||
app.BuildMiddlewareServiceProvider();
|
||||
await MiddlewareRegister.Handle(app);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
namespace LFlow.Middleware.Middlewares
|
||||
{
|
||||
public class LoggingMiddleware : ILFlowMiddleware
|
||||
{
|
||||
private readonly ILogger<LoggingMiddleware> _logger;
|
||||
|
||||
public LoggingMiddleware(ILogger<LoggingMiddleware> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public int Priority => 1;
|
||||
|
||||
public async Task RunAsync(HttpContext context, Func<Task> next)
|
||||
{
|
||||
var controllerName = context.GetRouteData()?.Values["controller"]?.ToString();
|
||||
var actionName = context.GetRouteData()?.Values["action"]?.ToString();
|
||||
var requestId = context.Request.Headers["X-Request-Id"].ToString();
|
||||
if (string.IsNullOrEmpty(requestId))
|
||||
{
|
||||
requestId = Guid.NewGuid().ToString();
|
||||
context.Request.Headers.Append("X-Request-Id", requestId);
|
||||
}
|
||||
using (_logger?.BeginScope(requestId))
|
||||
{
|
||||
_logger?.LogInformation("Request Id: {requestId}", requestId);
|
||||
_logger?.LogInformation("Controller: {controllerName} / Action : {actionName}", controllerName, actionName);
|
||||
// _logger?.LogInformation("Router Data {@routerData}", context.GetRouteData());
|
||||
try
|
||||
{
|
||||
await next();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.LogError(ex, "An error occurred while processing the request. Request Id: {requestId}", requestId);
|
||||
//await context.Response.WriteAsync(JsonConvert.SerializeObject(ApiResult<object>.FailResult("无权限!", 100501)));
|
||||
// _logger?.LogInformation("Response {@response}", context.Response);
|
||||
}
|
||||
}
|
||||
if (!context.Response.Headers.ContainsKey("X-Request-Id"))
|
||||
{
|
||||
|
||||
}
|
||||
// context.Response.Headers.Append("X-Request-Id", requestId);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
using System.Reflection;
|
||||
|
||||
namespace LFlow.Middleware.Register
|
||||
{
|
||||
public static class MiddlewareRegister
|
||||
{
|
||||
private static IServiceProvider? _serviceProvider;
|
||||
|
||||
private static readonly IDictionary<Type, ILFlowMiddleware> _middlewares = new Dictionary<Type, ILFlowMiddleware>();
|
||||
private static List<Type> _middlewareTypes = [];
|
||||
public static void RegisterMiddlewares(this IServiceCollection service, List<Assembly> assemblies)
|
||||
{
|
||||
if (assemblies == null || assemblies.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// 列入系统内置中间件
|
||||
var allAssemblies = new List<Assembly>(assemblies)
|
||||
{
|
||||
Assembly.GetAssembly(typeof(ILFlowMiddleware))!
|
||||
};
|
||||
|
||||
allAssemblies.ForEach(assembly =>
|
||||
{
|
||||
var types = assembly.GetTypes().ToList();
|
||||
foreach (var type in types)
|
||||
{
|
||||
if (type.GetInterface(nameof(ILFlowMiddleware)) != null)
|
||||
{
|
||||
service.AddSingleton(type);
|
||||
_middlewareTypes.Add(type);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void BuildMiddlewareServiceProvider(this IApplicationBuilder application)
|
||||
{
|
||||
_serviceProvider = application.ApplicationServices;
|
||||
_middlewareTypes.ForEach(type =>
|
||||
{
|
||||
if (_serviceProvider.GetService(type) is ILFlowMiddleware middleware)
|
||||
_middlewares.Add(type, middleware);
|
||||
});
|
||||
}
|
||||
/// <summary>
|
||||
/// 处理中间件
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="next"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task Handle(IApplicationBuilder application)
|
||||
{
|
||||
//var logger = application.ApplicationServices.GetService<ILogger>();
|
||||
var orderedMiddlewares = _middlewares.Values.OrderBy(m => m.Priority).ToList();
|
||||
foreach (var middleware in orderedMiddlewares)
|
||||
{
|
||||
await Task.FromResult(application.Use(middleware.RunAsync));
|
||||
//logger?.LogInformation("Middleware {MiddlewareName} is registered.", middleware.GetType().Name);
|
||||
Console.WriteLine($"[{DateTime.Now:hh:mm:ss} INF] Middleware {middleware.GetType().Name} is registered.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Base.Utils;
|
||||
using LFlow.OnlineManegement.Model;
|
||||
using LFlow.OnlineManegement.Service;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace LFlow.OnlineManegement.Controller;
|
||||
/// <summary>
|
||||
/// 在线用户管理
|
||||
/// </summary>
|
||||
/// <param name="service"></param>
|
||||
public class OnlineManagementController(IOnlineManagementService service) : BaseController
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 查询所有在线用户
|
||||
/// </summary>
|
||||
/// <param name="pageIndex"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public PagedApiResult<List<OnlineDto>> ListAll(int pageIndex, int pageSize)
|
||||
{
|
||||
int dataTotal = 0;
|
||||
var result = service.GetAllOnlineUser(pageIndex, pageSize, ref dataTotal);
|
||||
if (result == null || result.Count == 0)
|
||||
{
|
||||
return PagedFail(result, "No data found", 404);
|
||||
}
|
||||
return Success(result, dataTotal, pageIndex, pageSize);
|
||||
}
|
||||
/// <summary>
|
||||
/// 注册在线用户
|
||||
/// </summary>
|
||||
/// <param name="onlineInfo"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public ApiResult<OnlineDto> OnlineRegistered(OnlineDto onlineInfo)
|
||||
{
|
||||
return Success(service.OnlineRegistered(onlineInfo));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputPath>../LFlow_Bin/Services/</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<UseCommonOutputDirectory>true</UseCommonOutputDirectory>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<DocumentationFile>..\LFlow_Bin\Services\OnlineManegement.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LFlow.Base\LFlow.Base.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,15 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
|
||||
namespace LFlow.OnlineManegement.Model
|
||||
{
|
||||
public class OnlineDto : IModel
|
||||
{
|
||||
public string? ID { get; set; }
|
||||
|
||||
public string? HostName { get; set; }
|
||||
public string? IPAddress { get; set; }
|
||||
public string? MacAddress { get; set; }
|
||||
public string? OS { get; set; }
|
||||
public string? LastOnlineTime { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using SqlSugar;
|
||||
|
||||
namespace LFlow.OnlineManegement.Model
|
||||
{
|
||||
[SugarTable("T_U_ONLINE")]
|
||||
public class OnlineModel : IDataModel
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public string ID { get; set; }
|
||||
|
||||
public string HostName { get; set; }
|
||||
public string IPAddress { get; set; }
|
||||
public string MacAddress { get; set; }
|
||||
public string OS { get; set; }
|
||||
public string LastOnlineTime { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Base.Utils;
|
||||
using LFlow.OnlineManegement.Model;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Serilog;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LFlow.OnlineManegement
|
||||
{
|
||||
public class OnlineManegementModule : IModule
|
||||
{
|
||||
public void ConfigureModule(IServiceCollection services)
|
||||
{
|
||||
// 将模型添加到需要初始化数据库表的队列中
|
||||
CodeFirst.AddType(typeof(OnlineModel));
|
||||
// 获取当前程序集
|
||||
var assembly = Assembly.GetAssembly(typeof(OnlineManegementModule))!;
|
||||
var types = assembly.GetTypes().ToList();
|
||||
//注册服务
|
||||
RegisterModule.RegisterAllService(types, services);
|
||||
//注册仓储
|
||||
RegisterModule.RegisterAllRepo(types, services);
|
||||
//RegisterModule.RegisterAllModel(types, services);
|
||||
services.AddControllers().AddApplicationPart(assembly);
|
||||
Log.Logger?.Information("OnlineManegementModule ConfigureModule done");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using LFlow.Base.Default;
|
||||
using LFlow.OnlineManegement.Model;
|
||||
using SqlSugar;
|
||||
|
||||
namespace LFlow.OnlineManegement.Repository
|
||||
{
|
||||
public class OnlineManagementRepo(ISqlSugarClient db) : DefaultCurdRepo<OnlineModel, string>(db)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using LFlow.OnlineManegement.Model;
|
||||
|
||||
namespace LFlow.OnlineManegement.Service;
|
||||
public interface IOnlineManagementService : IService//<VersionDto>
|
||||
{
|
||||
List<OnlineDto> GetAllOnlineUser(int pageIndex, int pageSize, ref int dataTotal);
|
||||
|
||||
OnlineDto OnlineRegistered(OnlineDto onlineInfo);
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using LFlow.OnlineManegement.Model;
|
||||
using Mapster;
|
||||
|
||||
namespace LFlow.OnlineManegement.Service;
|
||||
/// <summary>
|
||||
/// 在线管理服务
|
||||
/// </summary>
|
||||
public class OnlineManagementService(IRepo<OnlineModel, string> _repo) : IOnlineManagementService
|
||||
{
|
||||
public List<OnlineDto> GetAllOnlineUser(int pageIndex, int pageSize, ref int dataTotal)
|
||||
{
|
||||
var result = _repo.GetAll(pageIndex, pageSize, ref dataTotal).Adapt<List<OnlineDto>>();
|
||||
return result;
|
||||
}
|
||||
|
||||
public OnlineDto OnlineRegistered(OnlineDto onlineInfo)
|
||||
{
|
||||
bool isUpdate = false;
|
||||
if (string.IsNullOrEmpty(onlineInfo.ID))
|
||||
{
|
||||
onlineInfo.ID = Guid.NewGuid().ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_repo.Get(onlineInfo.ID) == null)
|
||||
{
|
||||
isUpdate = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
isUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
return _repo.SaveOrUpdate(onlineInfo.Adapt<OnlineModel>(), isUpdate).Adapt<OnlineDto>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Base.Utils;
|
||||
using LFlow.Permission.Model;
|
||||
using LFlow.Permission.Service;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Serilog;
|
||||
|
||||
namespace LFlow.Permission.Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 权限控制
|
||||
/// </summary>
|
||||
public class PermissionController : BaseController
|
||||
{
|
||||
/// <summary>
|
||||
/// 权限服务
|
||||
/// </summary>
|
||||
private IPermissionService service;
|
||||
/// <summary>
|
||||
/// 日志
|
||||
/// </summary>
|
||||
private ILogger logger;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="service"></param>
|
||||
/// <param name="logger"></param>
|
||||
public PermissionController(IPermissionService service, ILogger logger)
|
||||
|
||||
{
|
||||
this.service = service;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询权限
|
||||
/// </summary>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="pageIndex"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<PagedApiResult<List<PermissionDto>>> GetAll(int pageSize, int pageIndex)
|
||||
{
|
||||
var total = 0;
|
||||
var list = await service.GetPermissionListAsync(pageIndex, pageSize, ref total);
|
||||
return new PagedApiResult<List<PermissionDto>>
|
||||
{
|
||||
Data = list,
|
||||
TotalCount = total
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 添加程序权限
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ApiResult<List<PermissionDto>>> GetProgPermissions()
|
||||
{
|
||||
var result = await service.GetPermissions();
|
||||
return Success(result);
|
||||
}
|
||||
/// <summary>
|
||||
/// Test method to throw an exception
|
||||
/// </summary>
|
||||
/// <returns>ApiResult with an error message</returns>
|
||||
[HttpGet]
|
||||
public Task<ApiResult<object>> TestException()
|
||||
{
|
||||
// var a = 0 / 1;
|
||||
throw new Exception("Test exception");
|
||||
// return Task.FromResult(Success((object)"Success"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LFlow.Base\LFlow.Base.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputPath>../LFlow_Bin/Services/</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<UseCommonOutputDirectory>true</UseCommonOutputDirectory>
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<DocumentationFile>..\LFlow_Bin\Services\Permission.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,64 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
|
||||
namespace LFlow.Permission.Model
|
||||
{
|
||||
public class PermissionDto : IModel
|
||||
{
|
||||
/// <summary>
|
||||
/// ID
|
||||
/// </summary>
|
||||
public string? ID
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
/// <summary>
|
||||
/// 角色ID
|
||||
/// </summary>
|
||||
public string? RoleId
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
/// <summary>
|
||||
/// 权限对应程序ID
|
||||
/// </summary>
|
||||
public string? PermissionProgID
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
/// <summary>
|
||||
/// 权限对应程序名称
|
||||
/// </summary>
|
||||
public string? PermissionProgName
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
/// <summary>
|
||||
/// 权限名称
|
||||
/// </summary>
|
||||
public string? PermissionName
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
/// <summary>
|
||||
/// 权限接口
|
||||
/// </summary>
|
||||
public string? PermissionAction
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
/// <summary>
|
||||
/// 是否公开
|
||||
/// </summary>
|
||||
public bool IsPublic
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using SqlSugar;
|
||||
|
||||
namespace LFlow.Permission.Model
|
||||
{
|
||||
[SugarTable("T_U_PERMISSION")]
|
||||
public class PermissionModel : IDataModel
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public string ID
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public string RoleId
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
/// <summary>
|
||||
/// 权限对应程序ID
|
||||
/// </summary>
|
||||
public string ProgID
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
/// <summary>
|
||||
/// 权限对应程序名称
|
||||
/// </summary>
|
||||
public string ProgName
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
/// <summary>
|
||||
/// 权限名称
|
||||
/// </summary>
|
||||
public string PermissionName
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
/// <summary>
|
||||
/// 权限接口
|
||||
/// </summary>
|
||||
public string PermissionAction
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
/// <summary>
|
||||
/// 是否公开
|
||||
/// </summary>
|
||||
public bool IsPublic
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
using System.Net.Sockets;
|
||||
using LFlow.Base;
|
||||
using LFlow.Base.Utils;
|
||||
using LFlow.Cache.Interface;
|
||||
using LFlow.Middleware;
|
||||
using LFlow.Permission.Service;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace LFlow.Permission;
|
||||
|
||||
/// <summary>
|
||||
/// 权限中间件
|
||||
/// </summary>
|
||||
public class PermissionMiddleware(ISelfCache selfCache ) : ILFlowMiddleware
|
||||
{
|
||||
/// <summary>
|
||||
/// 优先级
|
||||
/// </summary>
|
||||
public int Priority => 1;
|
||||
|
||||
/// <summary>
|
||||
/// 执行入口
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="next"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public async Task RunAsync(HttpContext context, Func<Task> next)
|
||||
{
|
||||
// var progName = context.GetRouteData()?.Values["controller"]?.ToString();
|
||||
// var progAction = context.GetRouteData()?.Values["action"]?.ToString();
|
||||
// if (progName != null)
|
||||
// {
|
||||
// var service = App.GetService<IPermissionService>();
|
||||
// var progPermission = service != null ? await service.GetProgPerminssionListAsync(progName) : null;
|
||||
// var currentPermission = progPermission?.FirstOrDefault(p => p.PermissionAction == progAction);
|
||||
// if (currentPermission == null || currentPermission!.IsPublic)
|
||||
// {
|
||||
// await next();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //TODO 从缓存中根据Token获取用户信息,并判断是否有权限
|
||||
// await context.Response.WriteAsync(JsonConvert.SerializeObject(ApiResult<object>.FailResult("无权限!", 100501)));
|
||||
// var token = context.Request.Cookies["Token"]?.ToString();
|
||||
// if(token != null){
|
||||
// var obj = selfCache.GetAsync(token!);
|
||||
// }else{
|
||||
// await context.Response.WriteAsync(JsonConvert.SerializeObject(ApiResult<object>.FailResult("未登录!", 100500)));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// // 预检请求
|
||||
// if (context.Request.Method == "OPTIONS")
|
||||
// {
|
||||
await next();
|
||||
// // context.Response.StatusCode = StatusCodes.Status200OK;
|
||||
// }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Base.Utils;
|
||||
using LFlow.Permission.Model;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Serilog;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LFlow.Permission;
|
||||
/// <summary>
|
||||
/// 权限模块
|
||||
/// </summary>
|
||||
public class PermissionModule : IModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置模块
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
public void ConfigureModule(IServiceCollection services)
|
||||
{
|
||||
CodeFirst.AddType(typeof(PermissionModel));
|
||||
var assembly = Assembly.GetAssembly(typeof(PermissionModule))!;
|
||||
var types = assembly.GetTypes().ToList();
|
||||
types.RegisterAllService(services);
|
||||
types.RegisterAllRepo(services);
|
||||
//RegisterModule.RegisterAllModel(types, services);
|
||||
services.AddControllers().AddApplicationPart(assembly);
|
||||
Log.Logger?.Information("UserManagementModule ConfigureModule done");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using LFlow.Base.Default;
|
||||
using LFlow.Permission.Model;
|
||||
using SqlSugar;
|
||||
|
||||
namespace LFlow.Permission.Repository
|
||||
{
|
||||
internal class RoleRepo(ISqlSugarClient client) : DefaultCurdRepo<PermissionModel, string>(client)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Permission.Model;
|
||||
|
||||
namespace LFlow.Permission.Service
|
||||
{
|
||||
public interface IPermissionService : IService//<VersionDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取权限列表
|
||||
/// </summary>
|
||||
/// <param name="pageIndex"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="total"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<PermissionDto>> GetPermissionListAsync(int pageIndex, int pageSize, ref int total);
|
||||
/// <summary>
|
||||
/// 根据ID获取权限信息
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
Task<PermissionDto> GetPermissionAsync(string id);
|
||||
/// <summary>
|
||||
/// 添加一项权限
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
Task<PermissionDto> AddPermissionAsync(PermissionDto model);
|
||||
/// <summary>
|
||||
/// 更新权限内容
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
Task<PermissionDto> UpdatePermissionAsync(PermissionDto model);
|
||||
/// <summary>
|
||||
/// 删除一项权限
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> DeletePermissionAsync(string id);
|
||||
/// <summary>
|
||||
/// 获取程序权限列表
|
||||
/// </summary>
|
||||
/// <param name="progID"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<PermissionDto>> GetProgPerminssionListAsync(string progID);
|
||||
/// <summary>
|
||||
/// 获取所有权限项
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<List<PermissionDto>> GetPermissions();
|
||||
/// <summary>
|
||||
/// 获取用户权限
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<List<PermissionDto>> GetUserPermissions();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
using LFlow.Base;
|
||||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Base.Utils;
|
||||
using LFlow.Cache.Interface;
|
||||
using LFlow.Permission.Model;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Mvc.Routing;
|
||||
|
||||
namespace LFlow.Permission.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色服务
|
||||
/// </summary>
|
||||
public class PermissionService(IRepo<PermissionModel, string> repo, ISelfCache cacher) : IPermissionService
|
||||
{
|
||||
/// <summary>
|
||||
/// 添加权限项
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
public Task<PermissionDto> AddPermissionAsync(PermissionDto model)
|
||||
{
|
||||
var savedModel = repo.SaveOrUpdate(model.Adapt<PermissionModel>(), isUpdate: false);
|
||||
var result = savedModel?.MapTo<PermissionDto>() ?? throw new InvalidOperationException("Failed to add the permission model.");
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除权限项并清理缓存
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public Task<int> DeletePermissionAsync(string id)
|
||||
{
|
||||
cacher.RemoveAsync(id);
|
||||
return Task.FromResult(repo.DeleteById(id));
|
||||
}
|
||||
/// <summary>
|
||||
/// 根据ID获取权限
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PermissionDto> GetPermissionAsync(string id)
|
||||
{
|
||||
var cachedPermission = await cacher.GetAsync<PermissionModel>(id);
|
||||
if (cachedPermission != null)
|
||||
{
|
||||
return cachedPermission!.MapTo<PermissionDto>()!;
|
||||
}
|
||||
var permission = await Task.FromResult(repo.Get(id));
|
||||
if (permission != null)
|
||||
{
|
||||
await cacher.SetAsync(id, permission);
|
||||
}
|
||||
return permission?.MapTo<PermissionDto>() ?? new PermissionDto();
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取权限列表
|
||||
/// </summary>
|
||||
/// <param name="pageIndex"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="total"></param>
|
||||
/// <returns></returns>
|
||||
public Task<List<PermissionDto>> GetPermissionListAsync(int pageIndex, int pageSize, ref int total)
|
||||
{
|
||||
return Task.FromResult(repo.GetAll(pageIndex, pageSize, ref total).Adapt<List<PermissionDto>>());
|
||||
}
|
||||
|
||||
public Task<List<PermissionDto>> GetPermissions()
|
||||
{
|
||||
List<PermissionDto> permissions = [];
|
||||
App.SubServiceAssembly.ForEach(service =>
|
||||
{
|
||||
var types = service.GetTypes();
|
||||
foreach (var item in types.Where(type => type.IsSubclassOf(typeof(BaseController))))
|
||||
{
|
||||
var progName = item.Name.Replace("Controller", "");
|
||||
foreach (var method in item.GetMethods())
|
||||
{
|
||||
var attrs = method.CustomAttributes.Where(attr =>
|
||||
{
|
||||
return attr.AttributeType.IsSubclassOf(typeof(HttpMethodAttribute));
|
||||
});
|
||||
if (attrs != null && attrs.Count() > 0)
|
||||
{
|
||||
var permission = new PermissionDto
|
||||
{
|
||||
//ProgID = progName,
|
||||
PermissionAction = method.Name,
|
||||
PermissionProgID = progName
|
||||
};
|
||||
permissions.Add(permission);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
return Task.FromResult(permissions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取程序权限列表
|
||||
/// </summary>
|
||||
/// <param name="progID"></param>
|
||||
/// <returns></returns>
|
||||
public Task<List<PermissionDto>> GetProgPerminssionListAsync(string progID)
|
||||
{
|
||||
return Task.FromResult(repo.Search(new PermissionModel
|
||||
{
|
||||
ProgID = progID
|
||||
}).Adapt<List<PermissionDto>>());
|
||||
}
|
||||
|
||||
public Task<List<PermissionDto>> GetUserPermissions()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新权限项
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
public Task<PermissionDto> UpdatePermissionAsync(PermissionDto model)
|
||||
{
|
||||
if (model != null && !string.IsNullOrEmpty(model.ID))
|
||||
{
|
||||
cacher.RemoveAsync(model.ID);
|
||||
}
|
||||
if (model != null)
|
||||
{
|
||||
var permissionModel = model?.Adapt<PermissionModel>() ?? throw new ArgumentNullException(nameof(model));
|
||||
var savedModel = repo.SaveOrUpdate(permissionModel, isUpdate: true);
|
||||
return Task.FromResult(savedModel?.MapTo<PermissionDto>() ?? throw new InvalidOperationException("Failed to update the permission model."));
|
||||
}
|
||||
throw new ArgumentNullException(nameof(model));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Role.Service;
|
||||
using Serilog;
|
||||
|
||||
namespace LFlow.Role.Controller
|
||||
{
|
||||
public class RoleController(IRoleService service, ILogger logger) : BaseController
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputPath>../LFlow_Bin/Services/</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<UseCommonOutputDirectory>true</UseCommonOutputDirectory>
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<DocumentationFile>..\LFlow_Bin\Services\Role.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LFlow.Base\LFlow.Base.csproj" />
|
||||
<ProjectReference Include="..\LFlow.Permission\LFlow.Permission.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,53 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Permission.Model;
|
||||
|
||||
namespace LFlow.Role.Model
|
||||
{
|
||||
public class RoleDto : IModel
|
||||
{
|
||||
public string? ID
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string? RoleName
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string? RoleDesc
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string? RoleType
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string? RoleStatus
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public bool? IsDefault
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public bool? IsEnable
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
/// <summary>
|
||||
/// 权限列表
|
||||
/// </summary>
|
||||
public List<PermissionDto> Permissions { get; set; } = [];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using SqlSugar;
|
||||
|
||||
namespace LFlow.Role.Model
|
||||
{
|
||||
[SugarTable("T_U_ROLE")]
|
||||
public class RoleModel : IDataModel
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public string ID
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string RoleName
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string RoleDesc
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string RoleType
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string RoleStatus
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public bool IsDefault
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public bool IsEnable
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using LFlow.Base.Default;
|
||||
using LFlow.Role.Model;
|
||||
using SqlSugar;
|
||||
|
||||
namespace LFlow.Role.Repository
|
||||
{
|
||||
internal class RoleRepo(ISqlSugarClient client) : DefaultCurdRepo<RoleModel, string>(client)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Base.Utils;
|
||||
using LFlow.Role.Model;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Serilog;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LFlow.Role
|
||||
{
|
||||
public class RoleModule : IModule
|
||||
{
|
||||
public void ConfigureModule(IServiceCollection services)
|
||||
{
|
||||
CodeFirst.AddType(typeof(RoleModel));
|
||||
var assembly = Assembly.GetAssembly(typeof(RoleModule))!;
|
||||
var types = assembly.GetTypes().ToList();
|
||||
RegisterModule.RegisterAllService(types, services);
|
||||
RegisterModule.RegisterAllRepo(types, services);
|
||||
//RegisterModule.RegisterAllModel(types, services);
|
||||
services.AddControllers().AddApplicationPart(assembly);
|
||||
Log.Logger?.Information("UserManegementModule ConfigureModule done");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Role.Model;
|
||||
|
||||
namespace LFlow.Role.Service
|
||||
{
|
||||
public interface IRoleService : IService//<VersionDto>
|
||||
{
|
||||
Task<List<RoleDto>> GetRoleListAsync(int pageIndex, int pageSize, ref int total);
|
||||
Task<RoleDto> GetRoleAsync(string id);
|
||||
Task<RoleDto> AddRoleAsync(RoleDto model);
|
||||
Task<RoleDto> UpdateRoleAsync(RoleDto model);
|
||||
Task<int> DeleteRoleAsync(string id);
|
||||
/// <summary>
|
||||
/// 获取角色权限列表
|
||||
/// </summary>
|
||||
/// <param name="progID"></param>
|
||||
/// <returns></returns>
|
||||
Task<RoleDto> GetRolePerminssionListAsync(string roleId);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Base.Utils;
|
||||
using LFlow.Cache.Interface;
|
||||
using LFlow.Permission.Service;
|
||||
using LFlow.Role.Model;
|
||||
using Mapster;
|
||||
|
||||
namespace LFlow.Role.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色服务
|
||||
/// </summary>
|
||||
public class RoleService(IRepo<RoleModel, string> repo, IPermissionService permissionService, ISelfCache cacher) : IRoleService
|
||||
{
|
||||
/// <summary>
|
||||
/// 添加角色
|
||||
/// </summary>
|
||||
/// <param name="model"></param>
|
||||
/// <returns></returns>
|
||||
public Task<RoleDto> AddRoleAsync(RoleDto model)
|
||||
{
|
||||
var savedRole = repo.SaveOrUpdate(model.Adapt<RoleModel>(), isUpdate: false);
|
||||
if (savedRole == null)
|
||||
{
|
||||
throw new InvalidOperationException("Failed to save or update the role.");
|
||||
}
|
||||
var roleDto = savedRole.MapTo<RoleDto>();
|
||||
if (roleDto == null)
|
||||
{
|
||||
throw new InvalidOperationException("Failed to map the saved role to RoleDto.");
|
||||
}
|
||||
return Task.FromResult(roleDto);
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除角色并清理缓存
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public Task<int> DeleteRoleAsync(string id)
|
||||
{
|
||||
cacher.RemoveAsync(id);
|
||||
return Task.FromResult(repo.DeleteById(id));
|
||||
}
|
||||
|
||||
public async Task<RoleDto> GetRolePerminssionListAsync(string roleId)
|
||||
{
|
||||
var roleDto = GetRoleAsync(roleId).Result;
|
||||
if (roleDto == null)
|
||||
{
|
||||
return new RoleDto();
|
||||
}
|
||||
var permissions = await permissionService.GetProgPerminssionListAsync(roleId);
|
||||
if (permissions != null && permissions.Count >= 0)
|
||||
{
|
||||
roleDto.Permissions = permissions!;
|
||||
return roleDto;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new RoleDto();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据ID获取角色
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<RoleDto> GetRoleAsync(string id)
|
||||
{
|
||||
var cachedRole = await cacher.GetAsync<RoleDto>(id);
|
||||
if (cachedRole != null)
|
||||
{
|
||||
return cachedRole;
|
||||
}
|
||||
var role = await Task.FromResult(repo.Get(id));
|
||||
if (role != null)
|
||||
{
|
||||
await cacher.SetAsync(id, role);
|
||||
}
|
||||
return role?.MapTo<RoleDto>() ?? new RoleDto();
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取角色列表
|
||||
/// </summary>
|
||||
/// <param name="pageIndex"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="total"></param>
|
||||
/// <returns></returns>
|
||||
public Task<List<RoleDto>> GetRoleListAsync(int pageIndex, int pageSize, ref int total)
|
||||
{
|
||||
var roleModels = repo.GetAll(pageIndex, pageSize, ref total);
|
||||
var roleDtos = roleModels?.Select(role => role.MapTo<RoleDto>()).ToList() ?? [];
|
||||
return Task.FromResult(roleDtos ?? [])!;
|
||||
}
|
||||
|
||||
public Task<RoleDto> UpdateRoleAsync(RoleDto model)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Base.Utils;
|
||||
using LFlow.UserManagement.Model;
|
||||
using LFlow.UserManagement.Service;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Serilog;
|
||||
|
||||
namespace LFlow.UserManagement.Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户管理
|
||||
/// </summary>
|
||||
public class UserManagementController(IUserManagementService service, ILogger logger) : BaseController
|
||||
{
|
||||
/// <summary>
|
||||
/// 登录
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public ApiResult<UserDto>? Login(UserDto user)
|
||||
{
|
||||
var loginedUser = service.Login(user);
|
||||
if (loginedUser == null)
|
||||
{
|
||||
//logger.Error("登录失败,用户名或密码错误");
|
||||
return Fail(loginedUser, "登录失败,用户名或密码错误", 10001);
|
||||
}
|
||||
return Success(loginedUser);
|
||||
}
|
||||
/// <summary>
|
||||
/// 注册
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public ApiResult<UserDto> Register(UserDto user)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Success(service.Register(user));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Fail<UserDto>(null, ex.Message, 500);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
using LFlow.InternalEventBus.Interface;
|
||||
using Serilog;
|
||||
|
||||
namespace LFlow.UserManagement
|
||||
{
|
||||
internal class InitEventSubscriber(ILogger logger) : IInternalEventSubscriber
|
||||
{
|
||||
public int Priority => 1;
|
||||
public string EventName => "Init";
|
||||
|
||||
public Task<bool> Handle(object data)
|
||||
{
|
||||
logger.Information($"Init event received. data => {data}");
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputPath>../LFlow_Bin/Services/</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<UseCommonOutputDirectory>true</UseCommonOutputDirectory>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<DocumentationFile>..\LFlow_Bin\Services\UserManagement.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LFlow.Base\LFlow.Base.csproj" />
|
||||
<ProjectReference Include="..\LFlow.Role\LFlow.Role.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,37 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Role.Model;
|
||||
|
||||
namespace LFlow.UserManagement.Model
|
||||
{
|
||||
public class UserDto : IModel
|
||||
{
|
||||
public string? ID
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string? UserName
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public string? UserEmail
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? UserPassword
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public RoleDto? UserRole
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string? Token
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using SqlSugar;
|
||||
|
||||
namespace LFlow.UserManagement.Model
|
||||
{
|
||||
[SugarTable("T_U_USERINFO")]
|
||||
public class UserModel : IDataModel
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public string ID
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string UserName
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public string UserEmail
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string UserPassword
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using LFlow.Base.Default;
|
||||
using LFlow.UserManagement.Model;
|
||||
using SqlSugar;
|
||||
|
||||
namespace LFlow.UserManagement.Repository
|
||||
{
|
||||
internal class UserManagementRepo(ISqlSugarClient client) : DefaultCurdRepo<UserModel, string>(client)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using LFlow.UserManagement.Model;
|
||||
|
||||
namespace LFlow.UserManagement.Service
|
||||
{
|
||||
public interface IUserManagementService : IService//<VersionDto>
|
||||
{
|
||||
UserDto? Login(UserDto user);
|
||||
Task<UserDto>? LoginAsync(UserDto user);
|
||||
|
||||
UserDto? Register(UserDto user);
|
||||
Task<UserDto>? RegisterAsync(UserDto user);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
using Azure.Core;
|
||||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Base.Utils;
|
||||
using LFlow.Cache.Interface;
|
||||
using LFlow.UserManagement.Model;
|
||||
using LFlow.UserManagement.Util;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace LFlow.UserManagement.Service
|
||||
{
|
||||
/// <summary>
|
||||
/// 在线管理服务
|
||||
/// </summary>
|
||||
public class UserManagementService(IRepo<UserModel, string> repo, ISelfCache cacher) : IUserManagementService
|
||||
{
|
||||
public UserDto? Login(UserDto user)
|
||||
{
|
||||
var userPwd = PasswordHelper.HashPassword(user.UserPassword);
|
||||
|
||||
var userModel = repo.WhereSearchId(new UserModel
|
||||
{
|
||||
UserName = user!.UserName!,
|
||||
UserPassword = userPwd
|
||||
});
|
||||
|
||||
if (userModel == null || !userModel.Any())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var firstUserId = userModel.FirstOrDefault();
|
||||
if (firstUserId == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var loginedUser = repo.Get(firstUserId);
|
||||
loginedUser.UserPassword = "";
|
||||
var token = Guid.NewGuid().ToString();
|
||||
// loginedUser.Token = token;
|
||||
cacher.SetAsync(token, loginedUser, TimeSpan.FromHours(2));
|
||||
var result = loginedUser.MapTo<UserDto>();
|
||||
if(result != null){
|
||||
result.Token = token;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Task<UserDto>? LoginAsync(UserDto user)
|
||||
{
|
||||
return Task.FromResult(this.Login(user));
|
||||
}
|
||||
|
||||
public UserDto? Register(UserDto user)
|
||||
{
|
||||
if (user.UserEmail == null || user.UserName == null || user.UserPassword == null)
|
||||
{
|
||||
throw new Exception("用户名、密码、邮箱不能为空");
|
||||
}
|
||||
var userPwd = PasswordHelper.HashPassword(user.UserPassword);
|
||||
var ids = repo.WhereSearchId(new UserModel
|
||||
{
|
||||
UserName = user.UserName
|
||||
});
|
||||
if (ids != null && ids.Count > 0)
|
||||
{
|
||||
throw new Exception("用户名已存在");
|
||||
}
|
||||
var userModel = new UserModel
|
||||
{
|
||||
ID = Guid.NewGuid().ToString(),
|
||||
UserName = user.UserName,
|
||||
UserEmail = user.UserEmail,
|
||||
UserPassword = userPwd
|
||||
};
|
||||
var savedUser = repo.SaveOrUpdate(userModel, false).MapTo<UserDto>();
|
||||
savedUser.UserPassword = "";
|
||||
return savedUser;
|
||||
}
|
||||
|
||||
public Task<UserDto> RegisterAsync(UserDto user)
|
||||
{
|
||||
return Task.FromResult(this.Register(user));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Base.Utils;
|
||||
using LFlow.UserManagement.Model;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Serilog;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LFlow.UserManagement
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户管理模块
|
||||
/// </summary>
|
||||
public class UserManagementModule : IModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置模块
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
public void ConfigureModule(IServiceCollection services)
|
||||
{
|
||||
CodeFirst.AddType(typeof(UserModel));
|
||||
var assembly = Assembly.GetAssembly(typeof(UserManagementModule))!;
|
||||
var types = assembly.GetTypes().ToList();
|
||||
types.RegisterAllService(services);
|
||||
types.RegisterAllRepo(services);
|
||||
//RegisterModule.RegisterAllModel(types, services);
|
||||
services.AddControllers().AddApplicationPart(assembly);
|
||||
Log.Logger?.Information("UserManagementModule ConfigureModule done");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
using LFlow.Base;
|
||||
using LFlow.Base.Utils;
|
||||
using LFlow.Cache.Interface;
|
||||
using LFlow.Middleware;
|
||||
using LFlow.Permission.Service;
|
||||
using LFlow.UserManagement.Model;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Newtonsoft.Json;
|
||||
using Serilog;
|
||||
|
||||
namespace LFlow.UserManagement
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户管理中间件
|
||||
/// </summary>
|
||||
/// <param name="logger"></param>
|
||||
public class UserMiddleware(ILogger logger,ISelfCache selfCache) : ILFlowMiddleware
|
||||
{
|
||||
/// <summary>
|
||||
/// 优先级
|
||||
/// </summary>
|
||||
public int Priority => 1;
|
||||
/// <summary>
|
||||
/// 执行入口
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="next"></param>
|
||||
public async Task RunAsync(Microsoft.AspNetCore.Http.HttpContext context, Func<Task> next)
|
||||
{
|
||||
var progName = context.GetRouteData()?.Values["controller"]?.ToString();
|
||||
var progAction = context.GetRouteData()?.Values["action"]?.ToString();
|
||||
if (progName != null)
|
||||
{
|
||||
var service = App.GetService<IPermissionService>();
|
||||
var progPermission = service != null ? await service.GetProgPerminssionListAsync(progName) : null;
|
||||
var currentPermission = progPermission?.FirstOrDefault(p => p.PermissionAction == progAction);
|
||||
if (currentPermission == null || currentPermission!.IsPublic)
|
||||
{
|
||||
await next();
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO 从缓存中根据Token获取用户信息,并判断是否有权限
|
||||
await context.Response.WriteAsync(JsonConvert.SerializeObject(ApiResult<object>.FailResult("无权限!", 100501)));
|
||||
var token = context.Request.Cookies["Token"]?.ToString();
|
||||
if (token != null)
|
||||
{
|
||||
var user = selfCache.GetAsync<UserModel>(token!);
|
||||
var userPermissions = service?.GetPermissions();
|
||||
}
|
||||
else
|
||||
{
|
||||
await context.Response.WriteAsync(JsonConvert.SerializeObject(ApiResult<object>.FailResult("未登录!", 100500)));
|
||||
}
|
||||
}
|
||||
}
|
||||
// 预检请求
|
||||
if (context.Request.Method == "OPTIONS")
|
||||
{
|
||||
await next();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace LFlow.UserManagement.Util
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class PasswordHelper
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="password"></param>
|
||||
/// <returns></returns>
|
||||
public static string HashPassword(string password)
|
||||
{
|
||||
byte[] data = Encoding.Default.GetBytes(password);
|
||||
byte[] hashData = MD5.HashData(data);
|
||||
StringBuilder sb = new();
|
||||
foreach (byte b in hashData)
|
||||
{
|
||||
sb.Append(b.ToString("x2"));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Base.Utils;
|
||||
using LFlow.VersionManagement.Enums;
|
||||
using LFlow.VersionManagement.Model;
|
||||
using LFlow.VersionManagement.Service;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Minio;
|
||||
using SqlSugar;
|
||||
|
||||
namespace LFlow.VersionManagement.Controller;
|
||||
public class VersionManagementController(IVersionManagementService service, IMinioClient _client) : BaseController
|
||||
{
|
||||
|
||||
|
||||
|
||||
[HttpDelete]
|
||||
public int DeleteById(string id)
|
||||
{
|
||||
return service.DeleteById(id);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public PagedApiResult<List<VersionDto>> GetAll(int pageIndex, int pageSize)
|
||||
{
|
||||
var total = 0;
|
||||
var result = service.GetAll(pageIndex, pageSize, ref total);
|
||||
return PagedApiResult<List<VersionDto>>.SuccessResult(
|
||||
data: Mapper.Map<List<VersionDto>>(result) ?? [],
|
||||
total,
|
||||
pageIndex,
|
||||
pageSize
|
||||
);
|
||||
//return new PagedApiResult<List<VersionDto>>
|
||||
//{
|
||||
// Data = Mapper.Map<List<VersionDto>>(result),
|
||||
// PageIndex = pageIndex,
|
||||
// PageSize = pageSize,
|
||||
// Message = "获取成功",
|
||||
// Code = 200,
|
||||
// Success = true,
|
||||
// TotalCount = total
|
||||
//};
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public ApiResult<VersionDto> GetById(string id)
|
||||
{
|
||||
var result = service.GetById(id).Adapt<VersionDto>();
|
||||
return ApiResult<VersionDto>.SuccessResult(result);
|
||||
}
|
||||
[HttpPost]
|
||||
public ApiResult<VersionDto> Save(VersionDto entity, bool isUpdate)
|
||||
{
|
||||
if (!isUpdate)
|
||||
{
|
||||
entity.ID = Guid.NewGuid().ToString();
|
||||
entity.DownloadUrl = "/";
|
||||
}
|
||||
var result = service.Save(entity, isUpdate).Adapt<VersionDto>();
|
||||
return ApiResult<VersionDto>.SuccessResult(result);
|
||||
}
|
||||
/// <summary>
|
||||
/// 保存文件
|
||||
/// </summary>
|
||||
/// <param name="formFile"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("upload")]
|
||||
public async Task<IActionResult> SaveFile(IFormFile formFile)
|
||||
{
|
||||
if (formFile == null || formFile.Length == 0)
|
||||
{
|
||||
return BadRequest("No file uploaded.");
|
||||
}
|
||||
|
||||
MinIOService minIOService = new MinIOService(_client);
|
||||
var guid = await minIOService.Upload(formFile);
|
||||
|
||||
return Ok(guid);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public List<VersionDto> Search(VersionDto whereObj)
|
||||
{
|
||||
return service.Search(whereObj).Adapt<List<VersionDto>>();
|
||||
}
|
||||
|
||||
//[HttpPost]
|
||||
//public ApiResult<VersionDto> CheckUpdate(VersionDto current)
|
||||
//{
|
||||
|
||||
//}
|
||||
[HttpGet]
|
||||
public ApiResult<VersionDto> GetLastUpdate(VersionChannel channel, UpgradeTargetType targetType)
|
||||
{
|
||||
return ApiResult<VersionDto>.SuccessResult(service.GetLastVersion(channel, targetType));
|
||||
}
|
||||
}
|
|
@ -8,14 +8,12 @@
|
|||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<UseCommonOutputDirectory>true</UseCommonOutputDirectory>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<DocumentationFile>..\LFlow_Bin\Services\VersionManagement.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LFlow.Base\LFlow.Base.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Controller\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -37,6 +37,7 @@ public class VersionDto : IModel
|
|||
{
|
||||
get; set;
|
||||
}
|
||||
#region 文件信息
|
||||
/// <summary>
|
||||
/// 文件名
|
||||
/// </summary>
|
||||
|
@ -47,7 +48,7 @@ public class VersionDto : IModel
|
|||
/// <summary>
|
||||
/// 文件大小
|
||||
/// </summary>
|
||||
public string? FileSize
|
||||
public double? FileSize
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
@ -59,6 +60,14 @@ public class VersionDto : IModel
|
|||
get; set;
|
||||
}
|
||||
/// <summary>
|
||||
/// 文件最后修改时间
|
||||
/// </summary>
|
||||
public DateTime LastModifyTime
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// 是否强制更新
|
||||
/// </summary>
|
||||
public bool IsRequired
|
||||
|
|
|
@ -54,7 +54,7 @@ public class VersionModel : IDataModel
|
|||
/// <summary>
|
||||
/// 文件大小
|
||||
/// </summary>
|
||||
public string? FileSize
|
||||
public double? FileSize
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
@ -66,6 +66,13 @@ public class VersionModel : IDataModel
|
|||
get; set;
|
||||
}
|
||||
/// <summary>
|
||||
/// 文件最后修改时间
|
||||
/// </summary>
|
||||
public DateTime LastModifyTime
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
/// <summary>
|
||||
/// 是否强制更新
|
||||
/// </summary>
|
||||
public bool IsRequired
|
||||
|
|
|
@ -1,17 +1,28 @@
|
|||
using LFlow.Base.Default;
|
||||
using LFlow.Base.Utils;
|
||||
using LFlow.VersionManagement.Enums;
|
||||
using LFlow.VersionManagement.Model;
|
||||
using SqlSugar;
|
||||
|
||||
namespace LFlow.VersionManagement.Repository;
|
||||
public class VersionManagementRepo(ISqlSugarClient db) : DefaultCurdRepo<VersionModel, string>(db)
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据条件搜索
|
||||
/// </summary>
|
||||
/// <param name="whereObj"></param>
|
||||
/// <returns></returns>
|
||||
public override List<VersionModel> Search(VersionModel whereObj)
|
||||
{
|
||||
return db.Queryable<VersionModel>()
|
||||
.Where(whereObj.ToWhereExp())
|
||||
.ToList();
|
||||
}
|
||||
/// <summary>
|
||||
/// 根据条件搜索ID
|
||||
/// </summary>
|
||||
/// <param name="whereObj"></param>
|
||||
/// <returns></returns>
|
||||
public override List<string> WhereSearchId(VersionModel whereObj)
|
||||
{
|
||||
return db.Queryable<VersionModel>()
|
||||
|
@ -20,4 +31,19 @@ public class VersionManagementRepo(ISqlSugarClient db) : DefaultCurdRepo<Version
|
|||
.Select(x => x.ID)
|
||||
.ToList();
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取最新版本
|
||||
/// </summary>
|
||||
/// <param name="channel"></param>
|
||||
/// <param name="targetType"></param>
|
||||
/// <returns></returns>
|
||||
public VersionModel GetLatestVersion(VersionChannel channel, UpgradeTargetType targetType)
|
||||
{
|
||||
return db.Queryable<VersionModel>()
|
||||
.Where(mt => channel == mt.VersionChannel && targetType == mt.UpgradeTargetType)
|
||||
.GroupBy(mt => mt.CurrentVersion)
|
||||
.OrderBy(mt => mt.LastPublishTime, OrderByType.Desc)
|
||||
.First();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,17 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using LFlow.VersionManagement.Enums;
|
||||
using LFlow.VersionManagement.Model;
|
||||
|
||||
namespace LFlow.VersionManagement.Service;
|
||||
public interface IVersionManagementService : IService<VersionDto>
|
||||
public interface IVersionManagementService : IService//<VersionDto>
|
||||
{
|
||||
VersionDto GetById(string id);
|
||||
List<VersionDto> Search(VersionDto whereObj);
|
||||
|
||||
int DeleteById(string id);
|
||||
VersionDto Save(VersionDto entity, bool isUpdate);
|
||||
|
||||
List<VersionDto> GetAll(int pageIndex, int pageSize, ref int total);
|
||||
|
||||
VersionDto? GetLastVersion(VersionChannel channel, UpgradeTargetType targetType);
|
||||
}
|
||||
|
|
|
@ -1,60 +1,37 @@
|
|||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Base.Utils;
|
||||
using LFlow.VersionManagement.Enums;
|
||||
using LFlow.VersionManagement.Model;
|
||||
using LFlow.VersionManagement.Repository;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace LFlow.VersionManagement.Service;
|
||||
/// <summary>
|
||||
/// 版本管理服务
|
||||
/// </summary>
|
||||
public class VersionManagementService : BaseController, IVersionManagementService
|
||||
public class VersionManagementService : IVersionManagementService
|
||||
{
|
||||
private readonly IRepo<VersionModel, string> _repo;
|
||||
public VersionManagementService(IRepo<VersionModel, string> repo)
|
||||
{
|
||||
_repo = repo;
|
||||
}
|
||||
[HttpDelete]
|
||||
public int DeleteById(string id)
|
||||
{
|
||||
return _repo.DeleteById(id);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public PagedApiResult<List<VersionDto>> GetAll(int pageIndex, int pageSize)
|
||||
{
|
||||
var total = 0;
|
||||
var result = _repo.GetAll(pageIndex, pageSize, ref total);
|
||||
return new PagedApiResult<List<VersionDto>>
|
||||
{
|
||||
Data = Mapper.Map<List<VersionDto>>(result),
|
||||
PageIndex = pageIndex,
|
||||
PageSize = pageSize,
|
||||
Message = "获取成功",
|
||||
Success = true,
|
||||
TotalCount = total
|
||||
};
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public VersionDto GetById(string id)
|
||||
{
|
||||
return _repo.Get(id).Adapt<VersionDto>();
|
||||
}
|
||||
[HttpPost]
|
||||
public VersionDto Save(VersionDto entity, bool isUpdate)
|
||||
{
|
||||
return _repo.SaveOrUpdate(entity.Adapt<VersionModel>(), isUpdate).Adapt<VersionDto>();
|
||||
}
|
||||
[HttpPost]
|
||||
public int DeleteById(string id) => _repo.DeleteById(id);
|
||||
public List<VersionDto> GetAll(int pageIndex, int pageSize, ref int total) => _repo.GetAll(pageIndex, pageSize, ref total).Adapt<List<VersionDto>>();
|
||||
public VersionDto GetById(string id) => _repo.Get(id).Adapt<VersionDto>();
|
||||
public VersionDto Save(VersionDto entity, bool isUpdate) => _repo.SaveOrUpdate(entity.Adapt<VersionModel>(), isUpdate).Adapt<VersionDto>();
|
||||
// 搜索需要增加分页
|
||||
public List<VersionDto> Search(VersionDto whereObj)
|
||||
=> _repo.Search(whereObj.Adapt<VersionModel>()).Adapt<List<VersionDto>>();
|
||||
public VersionDto? GetLastVersion(VersionChannel channel, UpgradeTargetType targetType)
|
||||
{
|
||||
return _repo.Search(whereObj.Adapt<VersionModel>()).Adapt<List<VersionDto>>();
|
||||
}
|
||||
[HttpPost]
|
||||
public List<string> SearchAllId(VersionDto whereObj)
|
||||
{
|
||||
return _repo.WhereSearchId(whereObj.Adapt<VersionModel>());
|
||||
if (_repo is VersionManagementRepo versionRepo)
|
||||
{
|
||||
return versionRepo.GetLatestVersion(channel, targetType).Adapt<VersionDto>();
|
||||
}
|
||||
else
|
||||
{
|
||||
return default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
using System.Reflection;
|
||||
using LFlow.Base.Interfaces;
|
||||
using LFlow.Base.Utils;
|
||||
using LFlow.VersionManagement.Model;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Serilog;
|
||||
using System.Reflection;
|
||||
|
||||
namespace LFlow.User;
|
||||
namespace LFlow.VersionManagement;
|
||||
|
||||
public class VersionManagementModule : IModule
|
||||
{
|
||||
|
@ -13,10 +14,11 @@ public class VersionManagementModule : IModule
|
|||
CodeFirst.AddType(typeof(VersionModel));
|
||||
var assembly = Assembly.GetAssembly(typeof(VersionManagementModule))!;
|
||||
var types = assembly.GetTypes().ToList();
|
||||
RegisterModule.RegisterAllService(types, services);
|
||||
RegisterModule.RegisterAllRepo(types, services);
|
||||
RegisterModule.RegisterAllModel(types, services);
|
||||
types.RegisterAllService(services);
|
||||
types.RegisterAllRepo(services);
|
||||
//RegisterModule.RegisterAllModel(types, services);
|
||||
services.AddControllers().AddApplicationPart(assembly);
|
||||
Console.WriteLine("UserModule ConfigureModule");
|
||||
Log.Logger?.Information("VersionManagementModule ConfigureModule done");
|
||||
//Console.WriteLine("UserModule ConfigureModule");
|
||||
}
|
||||
}
|
||||
|
|
44
LFlow.sln
44
LFlow.sln
|
@ -5,7 +5,21 @@ VisualStudioVersion = 17.5.002.0
|
|||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LFlow.Base", "LFlow.Base\LFlow.Base.csproj", "{C581AFB2-50BA-4357-AD0A-AF287194837D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LFlow.VersionManagement", "LFlow.VersionManagement\LFlow.VersionManagement.csproj", "{D52CC594-B10C-4FC0-8B7A-68CE0645A95D}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LFlow.VersionManagement", "LFlow.VersionManagement\LFlow.VersionManagement.csproj", "{D52CC594-B10C-4FC0-8B7A-68CE0645A95D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LFlow.OnlineManegement", "LFlow.OnlineManegement\LFlow.OnlineManegement.csproj", "{E849310F-64AD-453A-A2AA-557731508BF1}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LFlow.UserManagement", "LFlow.UserManagement\LFlow.UserManagement.csproj", "{DA68CE22-AC53-40BD-AB2A-5C52DFDDD548}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LFlow.Middleware", "LFlow.Middleware\LFlow.Middleware.csproj", "{5BFD207E-28B3-40B8-94DF-1723C6A4424B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LFlow.InternalEventBus", "LFlow.InternalEventBus\LFlow.InternalEventBus.csproj", "{72CB0C72-9725-43A5-882D-3E93FD1F8706}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LFlow.Cache", "LFlow.Cache\LFlow.Cache.csproj", "{97D56496-BE2A-4431-A882-7DEA20B72EB0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LFlow.Role", "LFlow.Role\LFlow.Role.csproj", "{05CEB068-167F-4B27-A59A-EFBF0A656C43}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LFlow.Permission", "LFlow.Permission\LFlow.Permission.csproj", "{E7C112C2-534C-4212-959F-FBB4E21A41C1}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -21,6 +35,34 @@ Global
|
|||
{D52CC594-B10C-4FC0-8B7A-68CE0645A95D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D52CC594-B10C-4FC0-8B7A-68CE0645A95D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D52CC594-B10C-4FC0-8B7A-68CE0645A95D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E849310F-64AD-453A-A2AA-557731508BF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E849310F-64AD-453A-A2AA-557731508BF1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E849310F-64AD-453A-A2AA-557731508BF1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E849310F-64AD-453A-A2AA-557731508BF1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DA68CE22-AC53-40BD-AB2A-5C52DFDDD548}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DA68CE22-AC53-40BD-AB2A-5C52DFDDD548}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DA68CE22-AC53-40BD-AB2A-5C52DFDDD548}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DA68CE22-AC53-40BD-AB2A-5C52DFDDD548}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5BFD207E-28B3-40B8-94DF-1723C6A4424B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5BFD207E-28B3-40B8-94DF-1723C6A4424B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5BFD207E-28B3-40B8-94DF-1723C6A4424B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5BFD207E-28B3-40B8-94DF-1723C6A4424B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{72CB0C72-9725-43A5-882D-3E93FD1F8706}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{72CB0C72-9725-43A5-882D-3E93FD1F8706}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{72CB0C72-9725-43A5-882D-3E93FD1F8706}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{72CB0C72-9725-43A5-882D-3E93FD1F8706}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{97D56496-BE2A-4431-A882-7DEA20B72EB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{97D56496-BE2A-4431-A882-7DEA20B72EB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{97D56496-BE2A-4431-A882-7DEA20B72EB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{97D56496-BE2A-4431-A882-7DEA20B72EB0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{05CEB068-167F-4B27-A59A-EFBF0A656C43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{05CEB068-167F-4B27-A59A-EFBF0A656C43}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{05CEB068-167F-4B27-A59A-EFBF0A656C43}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{05CEB068-167F-4B27-A59A-EFBF0A656C43}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E7C112C2-534C-4212-959F-FBB4E21A41C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E7C112C2-534C-4212-959F-FBB4E21A41C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E7C112C2-534C-4212-959F-FBB4E21A41C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E7C112C2-534C-4212-959F-FBB4E21A41C1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
Loading…
Reference in New Issue