diff --git a/.idea/.idea.Bunny.WebApi/.idea/GitCommitMessageStorage.xml b/.idea/.idea.Bunny.WebApi/.idea/GitCommitMessageStorage.xml
index 3b56900..e4fd56a 100644
--- a/.idea/.idea.Bunny.WebApi/.idea/GitCommitMessageStorage.xml
+++ b/.idea/.idea.Bunny.WebApi/.idea/GitCommitMessageStorage.xml
@@ -2,19 +2,7 @@
\ No newline at end of file
diff --git a/Bunny.Common/Bunny.Common.csproj b/Bunny.Common/Bunny.Common.csproj
index e27855b..67a2885 100644
--- a/Bunny.Common/Bunny.Common.csproj
+++ b/Bunny.Common/Bunny.Common.csproj
@@ -19,6 +19,7 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/Bunny.Common/Connect/MinioContext.cs b/Bunny.Common/Connect/MinioContext.cs
new file mode 100644
index 0000000..34e0a64
--- /dev/null
+++ b/Bunny.Common/Connect/MinioContext.cs
@@ -0,0 +1,31 @@
+using Bunny.Common.Utils;
+using Microsoft.AspNetCore.Builder;
+using Minio;
+
+namespace Bunny.Common.Connect;
+
+public static class MinioContext
+{
+ public static IMinioClient? MinioClient;
+ public static readonly string BucketName = AppSettings.GetConfig("Minio:BucketName");
+
+ public static void AddMinioContext(this WebApplicationBuilder builder)
+ {
+ var endpoint = AppSettings.GetConfig("Minio:Url");
+ var accessKey = AppSettings.GetConfig("Minio:AccessKey");
+ var secretKey = AppSettings.GetConfig("Minio:SecretKey");
+
+ MinioClient = new MinioClient().WithEndpoint(endpoint).WithCredentials(accessKey, secretKey)
+ // .WithSSL() // 使用HTTPS
+ .Build();
+ Task.Run(ShowAllBucket);
+ }
+
+ private static async Task ShowAllBucket()
+ {
+ var listBucketsAsync = await MinioUtil.ListBucketsAsync();
+ foreach (var bucket in listBucketsAsync.Buckets) Console.WriteLine($"Minio存在的桶:{bucket.Name}");
+
+ Console.WriteLine("Minio 连接成功...");
+ }
+}
\ No newline at end of file
diff --git a/Bunny.Common/Connect/RedisContext.cs b/Bunny.Common/Connect/RedisContext.cs
index e93dd71..37d2e3c 100644
--- a/Bunny.Common/Connect/RedisContext.cs
+++ b/Bunny.Common/Connect/RedisContext.cs
@@ -1,13 +1,14 @@
-using StackExchange.Redis;
+using Microsoft.AspNetCore.Builder;
+using StackExchange.Redis;
namespace Bunny.Common.Connect;
-public class RedisContext
+public static class RedisContext
{
public static IDatabase RedisDatabase;
private static readonly EndPointCollection EndPointCollection = new();
- public static void Initial()
+ public static void AddRedisContext(this WebApplicationBuilder builder)
{
// 获取端口等配置信息
var host = AppSettings.GetConfig("Redis:Host");
diff --git a/Bunny.Common/Utils/MinioUtil.cs b/Bunny.Common/Utils/MinioUtil.cs
new file mode 100644
index 0000000..c5e2190
--- /dev/null
+++ b/Bunny.Common/Utils/MinioUtil.cs
@@ -0,0 +1,205 @@
+using Bunny.Common.Connect;
+using Bunny.Common.Exception;
+using Bunny.Dao.Entity.Constant;
+using Microsoft.AspNetCore.Http;
+using Microsoft.IdentityModel.Tokens;
+using Minio.DataModel;
+using Minio.DataModel.Args;
+using Minio.DataModel.Result;
+using Minio.Exceptions;
+
+namespace Bunny.Common.Utils;
+
+public static class MinioUtil
+{
+ ///
+ /// 创建新的桶,如果不存在则创建
+ ///
+ /// 桶名称
+ public static async Task MakeBucketAsync(string bucketName)
+ {
+ // 判断桶名称是否初始化
+ bucketName = bucketName.IsNullOrEmpty() ? MinioContext.BucketName : bucketName;
+ // minio客户端
+ var minioClient = MinioContext.MinioClient;
+
+ try
+ {
+ var found = await BucketExistsAsync(bucketName);
+ if (!found) await minioClient!.MakeBucketAsync(new MakeBucketArgs().WithBucket(bucketName));
+ }
+ catch (MinioException e)
+ {
+ Console.WriteLine(e);
+ throw new BunnyException(ExceptionConstant.FileSystemException);
+ }
+ }
+
+ ///
+ /// 列出所有的桶
+ ///
+ public static async Task ListBucketsAsync()
+ {
+ var minioClient = MinioContext.MinioClient;
+ try
+ {
+ var listAllMyBucketsResult = await minioClient!.ListBucketsAsync();
+ return listAllMyBucketsResult;
+ }
+ catch (MinioException e)
+ {
+ Console.WriteLine(e);
+ throw new BunnyException(ExceptionConstant.FileSystemException);
+ }
+ }
+
+ ///
+ /// 判断桶是否存在
+ ///
+ ///
+ ///
+ public static async Task BucketExistsAsync(string bucketName)
+ {
+ // 判断桶名称是否初始化
+ bucketName = bucketName.IsNullOrEmpty() ? MinioContext.BucketName : bucketName;
+ // minio客户端
+ var minioClient = MinioContext.MinioClient;
+
+ return await minioClient!.BucketExistsAsync(new BucketExistsArgs().WithBucket(bucketName));
+ }
+
+ ///
+ /// 移出桶
+ ///
+ /// 桶名称
+ public static async Task RemoveBucketAsync(string bucketName)
+ {
+ // 判断桶名称是否初始化
+ bucketName = bucketName.IsNullOrEmpty() ? MinioContext.BucketName : bucketName;
+ // minio客户端
+ var minioClient = MinioContext.MinioClient!;
+
+ try
+ {
+ // 如果存在则移除
+ var found = await BucketExistsAsync(bucketName);
+ if (found) await minioClient.RemoveBucketAsync(new RemoveBucketArgs().WithBucket(bucketName));
+ else Console.WriteLine("桶不存在");
+ }
+ catch (MinioException e)
+ {
+ Console.WriteLine(e);
+ throw new BunnyException(ExceptionConstant.FileSystemException);
+ }
+ }
+
+ ///
+ /// 查看桶的版本信息
+ ///
+ /// 桶名称
+ public static async Task GetVersioningInfoAsync(string bucketName)
+ {
+ // 判断桶名称是否初始化
+ bucketName = bucketName.IsNullOrEmpty() ? MinioContext.BucketName : bucketName;
+ // minio客户端
+ var minioClient = MinioContext.MinioClient!;
+
+ try
+ {
+ var found = await BucketExistsAsync(bucketName);
+ if (!found) Console.WriteLine("桶不存在");
+
+ return await minioClient.GetVersioningAsync(new GetVersioningArgs().WithBucket(bucketName));
+ }
+ catch (MinioException e)
+ {
+ Console.WriteLine(e);
+ throw new BunnyException(ExceptionConstant.FileSystemException);
+ }
+ }
+
+ ///
+ /// 上传文件
+ ///
+ /// 桶名称
+ /// 文件
+ public static async Task PutObjectAsync(IFormFile file, string? bucketName = default)
+ {
+ // 判断桶名称是否初始化
+ bucketName = bucketName.IsNullOrEmpty() ? MinioContext.BucketName : bucketName;
+ // minio客户端
+ var minioClient = MinioContext.MinioClient!;
+
+ var guid = Guid.NewGuid().ToString();
+ var fileName = guid + file.FileName;
+ try
+ {
+ var found = await BucketExistsAsync(bucketName!);
+ if (!found) await MakeBucketAsync(bucketName!);
+
+ await minioClient.PutObjectAsync(new PutObjectArgs().WithBucket(bucketName).WithObject(fileName)
+ .WithStreamData(file.OpenReadStream()).WithObjectSize(file.Length));
+ }
+ catch (MinioException e)
+ {
+ Console.WriteLine(e);
+ throw new BunnyException(ExceptionConstant.FileSystemException);
+ }
+ }
+
+ ///
+ /// 获取文件对象信息
+ ///
+ /// 桶名称
+ /// 文件名
+ public static async Task GetObjectAsync(string filename, string? bucketName = default)
+ {
+ // 判断桶名称是否初始化
+ bucketName = bucketName.IsNullOrEmpty() ? MinioContext.BucketName : bucketName;
+ // minio客户端
+ var minioClient = MinioContext.MinioClient!;
+
+ try
+ {
+ var statObjectArgs = new StatObjectArgs().WithBucket(bucketName).WithObject(filename);
+ await minioClient.StatObjectAsync(statObjectArgs);
+
+ var getObjectArgs = new GetObjectArgs().WithBucket(bucketName).WithObject(filename).WithFile(filename);
+ return await minioClient.GetObjectAsync(getObjectArgs);
+ }
+ catch (MinioException e)
+ {
+ Console.WriteLine(e);
+ throw new BunnyException(ExceptionConstant.FileSystemException);
+ }
+ }
+
+
+ ///
+ /// 桶中内容状态
+ ///
+ /// 桶名称
+ /// 文件名
+ public static async Task StatObject(string filename, string? bucketName = default)
+ {
+ // 判断桶名称是否初始化
+ bucketName = bucketName.IsNullOrEmpty() ? MinioContext.BucketName : bucketName;
+ // minio客户端
+ var minioClient = MinioContext.MinioClient!;
+
+ try
+ {
+ // Get the metadata of the object.
+ var statObjectArgs = new StatObjectArgs()
+ .WithBucket(bucketName)
+ .WithObject(filename);
+ var objectStat = await minioClient.StatObjectAsync(statObjectArgs);
+ return objectStat;
+ }
+ catch (MinioException e)
+ {
+ Console.WriteLine(e);
+ throw new BunnyException(ExceptionConstant.FileSystemException);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Bunny.Service/Bunny.Service.csproj b/Bunny.Service/Bunny.Service.csproj
index 4bb6028..cb95e0e 100644
--- a/Bunny.Service/Bunny.Service.csproj
+++ b/Bunny.Service/Bunny.Service.csproj
@@ -9,6 +9,7 @@
+
diff --git a/Bunny.Service/IService/IJobService.cs b/Bunny.Service/IService/IJobService.cs
new file mode 100644
index 0000000..50ddca4
--- /dev/null
+++ b/Bunny.Service/IService/IJobService.cs
@@ -0,0 +1,9 @@
+namespace Bunny.Service.IService;
+
+public interface IJobService
+{
+ ///
+ /// 开启一个简单的工作
+ ///
+ void StartSimpleJob();
+}
\ No newline at end of file
diff --git a/Bunny.Service/IService/Service/JobService.cs b/Bunny.Service/IService/Service/JobService.cs
new file mode 100644
index 0000000..e127754
--- /dev/null
+++ b/Bunny.Service/IService/Service/JobService.cs
@@ -0,0 +1,40 @@
+using Bunny.Service.Job;
+using Quartz;
+using Quartz.Impl;
+
+namespace Bunny.Service.IService.Service;
+
+public class JobService : IJobService
+{
+ ///
+ /// 开启一个简单的工作
+ /// https://www.youtube.com/watch?v=CuHIScZKup8&list=PLSi1BNmQ61ZohCcl43UdAksg7X3_TSmly&index=6
+ ///
+ public void StartSimpleJob()
+ {
+ var schedulerFactory = new StdSchedulerFactory();
+ // TODO 如果使用异步,必须使用await 和 async
+ // var scheduler = schedulerFactory.GetScheduler();
+ var scheduler = schedulerFactory.GetScheduler().GetAwaiter().GetResult();
+
+ var jobDetail = JobBuilder.Create()
+ .UsingJobData("username", "用户名")
+ .UsingJobData("password", "密码")
+ .WithIdentity("simpleJob", "简单的JOB")
+ .Build();
+ var trigger = TriggerBuilder.Create()
+ .WithIdentity("testTrigger", "测试发出器")
+ .StartNow()
+ // 每隔5秒执行一次,一共重复10次
+ .WithSimpleSchedule(x => x.WithIntervalInSeconds(5).WithRepeatCount(10))
+ .Build();
+
+ // 使用同步方法
+ scheduler.ScheduleJob(jobDetail, trigger).GetAwaiter().GetResult();
+ scheduler.Start().GetAwaiter().GetResult();
+
+ // TODO 使用异步
+ // await _scheduler.ScheduleJob(jobDetail, trigger);
+ // await _scheduler.Start();
+ }
+}
\ No newline at end of file
diff --git a/Bunny.Service/Job/SimJob.cs b/Bunny.Service/Job/SimJob.cs
new file mode 100644
index 0000000..13925e0
--- /dev/null
+++ b/Bunny.Service/Job/SimJob.cs
@@ -0,0 +1,16 @@
+using Quartz;
+
+namespace Bunny.Service.Job;
+
+public class SimJob : IJob
+{
+ public Task Execute(IJobExecutionContext context)
+ {
+ Console.WriteLine("执行一个简单的任务");
+ var dataMap = context.JobDetail.JobDataMap;
+ var username = dataMap.GetString("username");
+ var password = dataMap.GetString("password");
+ Console.WriteLine($"用户名:{username},密码: {password}");
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/Bunny.Service/WebSocket/WebSocketInitial.cs b/Bunny.Service/WebSocket/WebSocketInitial.cs
index 5a12c28..ee3bff0 100644
--- a/Bunny.Service/WebSocket/WebSocketInitial.cs
+++ b/Bunny.Service/WebSocket/WebSocketInitial.cs
@@ -1,8 +1,10 @@
-namespace Bunny.Service.WebSocket;
+using Microsoft.AspNetCore.Builder;
+
+namespace Bunny.Service.WebSocket;
public static class WebSocketInitial
{
- public static void Start()
+ public static void AddWebSocketInitial(this WebApplicationBuilder builder)
{
WebSocketTest.Start();
}
diff --git a/Bunny.WebApi/Config/BaseConfig.cs b/Bunny.WebApi/Config/BaseConfig.cs
index 21b1f6a..18d19ea 100644
--- a/Bunny.WebApi/Config/BaseConfig.cs
+++ b/Bunny.WebApi/Config/BaseConfig.cs
@@ -44,13 +44,15 @@ public class BaseConfig(WebApplicationBuilder builder)
private void UseExtend()
{
// 设置过滤器
- FilterConfig.Initialize(builder);
+ builder.FilterConfigInitialize();
// 初始化Redis
- RedisContext.Initial();
+ builder.AddRedisContext();
+ // 初始化Minio
+ builder.AddMinioContext();
// 初始化 Knife4Net 文档
- Knife4Net.Initialize(builder);
+ builder.AddKnife4Net();
// 启动 webSocket
- WebSocketInitial.Start();
+ builder.AddWebSocketInitial();
}
///
diff --git a/Bunny.WebApi/Config/FilterConfig.cs b/Bunny.WebApi/Config/FilterConfig.cs
index e76495b..1a93188 100644
--- a/Bunny.WebApi/Config/FilterConfig.cs
+++ b/Bunny.WebApi/Config/FilterConfig.cs
@@ -9,7 +9,7 @@ public static class FilterConfig
/// 配置过滤器
///
///
- public static void Initialize(WebApplicationBuilder builder)
+ public static void FilterConfigInitialize(this WebApplicationBuilder builder)
{
// 添加自定义过滤器---全局异常捕获
builder.Services.AddControllers(option =>
diff --git a/Bunny.WebApi/Config/Knife4Net.cs b/Bunny.WebApi/Config/Knife4Net.cs
index 36cb8b5..4272698 100644
--- a/Bunny.WebApi/Config/Knife4Net.cs
+++ b/Bunny.WebApi/Config/Knife4Net.cs
@@ -8,7 +8,7 @@ public static class Knife4Net
///
/// 配置 Knife4j 文档
///
- public static void Initialize(WebApplicationBuilder builder)
+ public static void AddKnife4Net(this WebApplicationBuilder builder)
{
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
diff --git a/Bunny.WebApi/Config/ServiceRegistration.cs b/Bunny.WebApi/Config/ServiceRegistration.cs
index e509de0..b2e22a8 100644
--- a/Bunny.WebApi/Config/ServiceRegistration.cs
+++ b/Bunny.WebApi/Config/ServiceRegistration.cs
@@ -15,6 +15,7 @@ public static class ServiceRegistration
builder.Services.AddScoped();
builder.Services.AddScoped();
builder.Services.AddScoped();
+ builder.Services.AddScoped();
}
///
diff --git a/Bunny.WebApi/Controllers/JobInitController.cs b/Bunny.WebApi/Controllers/JobInitController.cs
new file mode 100644
index 0000000..a6e069b
--- /dev/null
+++ b/Bunny.WebApi/Controllers/JobInitController.cs
@@ -0,0 +1,23 @@
+using Bunny.Dao.Result;
+using Bunny.Service.IService;
+using Microsoft.AspNetCore.Mvc;
+
+namespace Bunny.WebApi.Controllers;
+
+///
+/// Quartz 示例相关
+///
+[Route("/api/[controller]/[action]")]
+public class JobInitController(IJobService jobService) : ControllerBase
+{
+ ///
+ /// 开启一个简单的工作
+ ///
+ ///
+ [HttpPost]
+ public Result StartSimpleJob()
+ {
+ jobService.StartSimpleJob();
+ return Result.Success();
+ }
+}
\ No newline at end of file
diff --git a/Bunny.WebApi/appsettings.json b/Bunny.WebApi/appsettings.json
index f5107f7..e3ef6b2 100644
--- a/Bunny.WebApi/appsettings.json
+++ b/Bunny.WebApi/appsettings.json
@@ -21,5 +21,11 @@
"Password": "02120212",
"DefaultDB": 6,
"AsyncTimeout": 300
+ },
+ "Minio": {
+ "Url": "192.168.3.98:9000",
+ "AccessKey": "bunny",
+ "SecretKey": "02120212",
+ "BucketName": "test"
}
}
\ No newline at end of file