Skip to content

Commit ae5a2d7

Browse files
集成定时任务Quartz,更新文件:数据库表(db文件夹中找)Sys_QuartzLog、Sys_QuartzOptions同时将两张表正常生成代码(生成代码时类库选择system,文件夹输入Quartz) ;后台vol.core类型下Filters、Quartz文件夹、Startup.cs、system类库下Quartz文件夹;VOL.WebApi类库下System->Partial文件夹下Sys_QuartzOptions.cs文件;前端:extension->system文件夹下quartz;页面菜单->下拉框绑定设置中添加数据字典:参照现有字典配置:请求方式
1 parent 2de819c commit ae5a2d7

File tree

122 files changed

+24532
-750
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

122 files changed

+24532
-750
lines changed

.Net6版本/VOL.Core/Filters/ApiAuthorizeFilter.cs

+9-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using VOL.Core.Configuration;
1010
using VOL.Core.Extensions;
1111
using VOL.Core.ManageUser;
12+
using static VOL.Core.Filters.ApiTaskAttribute;
1213

1314
namespace VOL.Core.Filters
1415
{
@@ -31,8 +32,15 @@ public void OnAuthorization(AuthorizationFilterContext context)
3132
//if (context.Filters.Any(item => item is IAllowAnonymousFilter))
3233
if (context.ActionDescriptor.EndpointMetadata.Any(item => item is IAllowAnonymous))
3334
{
34-
//如果使用了固定Token不过期,直接对token的合法性及token是否存在进行验证
3535
if (context.Filters
36+
.Where(item => item is IApiTaskFilter)
37+
.FirstOrDefault() is IApiTaskFilter apiTaskFilter)
38+
{
39+
apiTaskFilter.OnAuthorization(context);
40+
return;
41+
}
42+
//如果使用了固定Token不过期,直接对token的合法性及token是否存在进行验证
43+
else if (context.Filters
3644
.Where(item => item is IFixedTokenFilter)
3745
.FirstOrDefault() is IFixedTokenFilter tokenFilter)
3846
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using Microsoft.AspNetCore.Authorization;
2+
using Microsoft.AspNetCore.Mvc;
3+
using Microsoft.AspNetCore.Mvc.Filters;
4+
using Microsoft.Extensions.Primitives;
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Text;
8+
using VOL.Core.Configuration;
9+
using VOL.Core.Extensions;
10+
using VOL.Core.Quartz;
11+
12+
namespace VOL.Core.Filters
13+
{
14+
public interface IApiTaskFilter : IFilterMetadata
15+
{
16+
AuthorizationFilterContext OnAuthorization(AuthorizationFilterContext context);
17+
}
18+
public class ApiTaskAttribute : Attribute, IApiTaskFilter, IAllowAnonymous
19+
{
20+
public AuthorizationFilterContext OnAuthorization(AuthorizationFilterContext context)
21+
{
22+
return QuartzAuthorization.Validation(context) ;
23+
}
24+
}
25+
26+
}
+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using Microsoft.AspNetCore.Http;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.IO;
5+
using System.Net;
6+
using System.Net.Http;
7+
using System.Net.Http.Headers;
8+
using System.Text;
9+
using System.Threading.Tasks;
10+
11+
namespace VOL.Core.Quartz
12+
{
13+
public static class HttpManager
14+
{
15+
16+
public static async Task<string> SendAsync(this IHttpClientFactory httpClientFactory,
17+
HttpMethod method,
18+
string url,
19+
string postData=null,
20+
int timeOut=180,
21+
Dictionary<string, string> headers = null)
22+
{
23+
var client = httpClientFactory.CreateClient();
24+
var content = new StringContent(postData??"");
25+
var request = new HttpRequestMessage(method, url)
26+
{
27+
Content = content
28+
};
29+
headers ??= new Dictionary<string, string>();
30+
headers.TryAdd(QuartzAuthorization.Key, QuartzAuthorization.AccessKey);
31+
if (headers != null)
32+
{
33+
foreach (var header in headers)
34+
{
35+
request.Headers.Add(header.Key, header.Value);
36+
}
37+
}
38+
try
39+
{
40+
client.Timeout = TimeSpan.FromSeconds(timeOut);
41+
HttpResponseMessage httpResponseMessage = await client.SendAsync(request);
42+
var result = await httpResponseMessage.Content
43+
.ReadAsStringAsync();
44+
return result;
45+
}
46+
catch (Exception ex)
47+
{
48+
Console.WriteLine(ex.Message);
49+
QuartzFileHelper.Error($"http请求异常,url:{url},{ex.Message+ex.StackTrace}");
50+
return ex.Message;
51+
}
52+
}
53+
}
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using Microsoft.Extensions.Configuration;
3+
using Quartz;
4+
using Quartz.Impl;
5+
using Quartz.Impl.Triggers;
6+
using System;
7+
using System.Collections.Generic;
8+
using System.Linq;
9+
using System.Net.Http;
10+
using System.Threading.Tasks;
11+
using VOL.Core.Configuration;
12+
using VOL.Core.EFDbContext;
13+
using VOL.Core.Utilities;
14+
using VOL.Entity.DomainModels;
15+
16+
namespace VOL.Core.Quartz
17+
{
18+
public class HttpResultfulJob : IJob
19+
{
20+
readonly IHttpClientFactory _httpClientFactory;
21+
22+
readonly IServiceProvider _serviceProvider;
23+
/// <summary>
24+
/// 2020.05.31增加构造方法
25+
/// </summary>
26+
/// <param name="serviceProvider"></param>
27+
/// <param name="httpClientFactory"></param>
28+
public HttpResultfulJob(IServiceProvider serviceProvider, IHttpClientFactory httpClientFactory)
29+
{
30+
_httpClientFactory = httpClientFactory;
31+
_serviceProvider = serviceProvider;
32+
}
33+
public async Task Execute(IJobExecutionContext context)
34+
{
35+
DateTime dateTime = DateTime.Now;
36+
Sys_QuartzOptions taskOptions = context.GetTaskOptions();
37+
string httpMessage = "";
38+
AbstractTrigger trigger = (context as JobExecutionContextImpl).Trigger as AbstractTrigger;
39+
if (taskOptions == null)
40+
{
41+
Console.WriteLine($"未获取到作业");
42+
return;
43+
}
44+
if (string.IsNullOrEmpty(taskOptions.ApiUrl) || taskOptions.ApiUrl == "/")
45+
{
46+
Console.WriteLine($"未配置作业:{taskOptions.TaskName}的url地址");
47+
QuartzFileHelper.Error($"未配置作业:{taskOptions.TaskName}的url地址");
48+
return;
49+
}
50+
string exceptionMsg = null;
51+
52+
try
53+
{
54+
using (var dbContext = new VOLContext())
55+
{
56+
var _taskOptions = dbContext.Set<Sys_QuartzOptions>().AsTracking()
57+
.Where(x => x.Id == taskOptions.Id).FirstOrDefault();
58+
59+
if (_taskOptions != null)
60+
{
61+
_taskOptions.LastRunTime = DateTime.Now;
62+
dbContext.Update(_taskOptions);
63+
var entry = dbContext.Entry(_taskOptions);
64+
entry.State = EntityState.Unchanged;
65+
entry.Property("LastRunTime").IsModified = true;
66+
dbContext.SaveChanges();
67+
}
68+
}
69+
70+
Dictionary<string, string> header = new Dictionary<string, string>();
71+
if (!string.IsNullOrEmpty(taskOptions.AuthKey)
72+
&& !string.IsNullOrEmpty(taskOptions.AuthValue))
73+
{
74+
header.Add(taskOptions.AuthKey.Trim(), taskOptions.AuthValue.Trim());
75+
}
76+
77+
httpMessage = await _httpClientFactory.SendAsync(
78+
taskOptions.Method?.ToLower() == "get" ? HttpMethod.Get : HttpMethod.Post,
79+
taskOptions.ApiUrl,
80+
taskOptions.PostData,
81+
taskOptions.TimeOut ?? 180,
82+
header); ;
83+
}
84+
catch (Exception ex)
85+
{
86+
exceptionMsg = ex.Message + ex.StackTrace;
87+
}
88+
finally
89+
{
90+
try
91+
{
92+
var log = new Sys_QuartzLog
93+
{
94+
LogId = Guid.NewGuid(),
95+
TaskName = taskOptions.TaskName,
96+
Id = taskOptions.Id,
97+
CreateDate = dateTime,
98+
ElapsedTime = Convert.ToInt32((DateTime.Now - dateTime).TotalSeconds),
99+
ResponseContent = httpMessage,
100+
ErrorMsg = exceptionMsg,
101+
StratDate = dateTime,
102+
Result = exceptionMsg == null ? 1 : 0,
103+
EndDate = DateTime.Now
104+
};
105+
using (var dbContext = new VOLContext())
106+
{
107+
dbContext.Set<Sys_QuartzLog>().Add(log);
108+
dbContext.SaveChanges();
109+
}
110+
}
111+
catch (Exception ex)
112+
{
113+
Console.WriteLine($"日志写入异常:{taskOptions.TaskName},{ex.Message}");
114+
QuartzFileHelper.Error($"日志写入异常:{typeof(HttpResultfulJob).Name},{taskOptions.TaskName},{ex.Message}");
115+
}
116+
}
117+
Console.WriteLine(trigger.FullName + " " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:sss") + " " + httpMessage);
118+
return;
119+
}
120+
}
121+
public class TaskOptions
122+
{
123+
public string TaskName { get; set; }
124+
public string GroupName { get; set; }
125+
public string Interval { get; set; }
126+
public string ApiUrl { get; set; }
127+
public string AuthKey { get; set; }
128+
public string AuthValue { get; set; }
129+
public string Describe { get; set; }
130+
public string RequestType { get; set; }
131+
public DateTime? LastRunTime { get; set; }
132+
public int Status { get; set; }
133+
}
134+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using Quartz;
2+
using Quartz.Spi;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Threading.Tasks;
7+
8+
namespace VOL.Core.Quartz
9+
{
10+
public class IOCJobFactory: IJobFactory
11+
{
12+
private readonly IServiceProvider _serviceProvider;
13+
public IOCJobFactory(IServiceProvider serviceProvider)
14+
{
15+
_serviceProvider = serviceProvider;
16+
}
17+
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
18+
{
19+
return _serviceProvider.GetService(bundle.JobDetail.JobType) as IJob;
20+
21+
}
22+
23+
public void ReturnJob(IJob job)
24+
{
25+
(job as IDisposable)?.Dispose();
26+
}
27+
}
28+
}
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace VOL.Core.Quartz
6+
{
7+
public enum JobAction
8+
{
9+
新增 = 1,
10+
删除 = 2,
11+
修改 = 3,
12+
暂停 = 4,
13+
停止,
14+
开启,
15+
立即执行
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
using Microsoft.AspNetCore.Mvc.Filters;
3+
using Microsoft.Extensions.Primitives;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Security.Cryptography;
7+
using System.Text;
8+
using VOL.Core.Configuration;
9+
using VOL.Core.Extensions;
10+
11+
namespace VOL.Core.Quartz
12+
{
13+
public static class QuartzAuthorization
14+
{
15+
16+
private static string _quartzAccessKey;
17+
18+
public static string Key = "QuartzAccessKey";
19+
public static string AccessKey
20+
{
21+
get
22+
{
23+
if (string.IsNullOrEmpty(_quartzAccessKey))
24+
{
25+
_quartzAccessKey = GetAccessKey();
26+
}
27+
return _quartzAccessKey;
28+
}
29+
}
30+
public static string GetAccessKey()
31+
{
32+
if (string.IsNullOrEmpty(_quartzAccessKey))
33+
{
34+
_quartzAccessKey = AppSetting.GetSettingString(Key);
35+
}
36+
if (string.IsNullOrEmpty(_quartzAccessKey))
37+
{
38+
_quartzAccessKey = Guid.NewGuid().ToString();
39+
}
40+
using (MD5 md5 = MD5.Create())
41+
{
42+
string md5str = _quartzAccessKey;
43+
byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(AppSetting.Secret.User));
44+
for (int i = 0; i < s.Length; i++)
45+
{
46+
string btos = s[i].ToString("X2");
47+
md5str += btos;
48+
}
49+
return md5str;
50+
}
51+
}
52+
53+
public static AuthorizationFilterContext Validation(AuthorizationFilterContext context)
54+
{
55+
if (context.HttpContext.Request.Headers.TryGetValue(Key, out StringValues value))
56+
{
57+
if (AccessKey != value)
58+
{
59+
context.Result = new ContentResult()
60+
{
61+
Content = new { message = "key不匹配", status = false, code = 401 }.Serialize(),
62+
ContentType = "application/json",
63+
StatusCode = 401
64+
};
65+
return context;
66+
}
67+
}
68+
return context;
69+
}
70+
}
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using VOL.Core.Configuration;
5+
using VOL.Core.Extensions;
6+
using VOL.Core.Utilities;
7+
8+
namespace VOL.Core.Quartz
9+
{
10+
public static class QuartzFileHelper
11+
{
12+
public static void OK(string message)
13+
{
14+
Write(message, "log");
15+
}
16+
17+
public static void Error(string message)
18+
{
19+
Write(message, "error");
20+
}
21+
22+
private static void Write(string message,string folder)
23+
{
24+
try
25+
{
26+
string fileName = DateTime.Now.ToString("yyyy-MM-dd");
27+
string path = $"{AppSetting.CurrentPath}\\quartz\\{folder}\\".ReplacePath();
28+
FileHelper.WriteFile(path, $"{fileName}.txt", message, true);
29+
}
30+
catch (Exception ex)
31+
{
32+
Console.WriteLine($"文件写入异常{message},{ex.Message + ex.StackTrace}");
33+
}
34+
}
35+
}
36+
}

0 commit comments

Comments
 (0)