using HT.Cloud.Code; using HT.Cloud.Domain.SystemSecurity; using HT.Cloud.Service.AutoJob; using HT.Cloud.Service; using Microsoft.Extensions.DependencyInjection; using Quartz; using Quartz.Impl.Triggers; using Quartz.Spi; using SqlSugar; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Reflection; using System.Threading.Tasks; namespace HT.Cloud.Service.AutoJob { public class JobExecute : IJob { private IScheduler _scheduler; private ISchedulerFactory _schedulerFactory; private IJobFactory _iocJobfactory; private readonly IHttpClientFactory _httpClient; public JobExecute(ISchedulerFactory schedulerFactory, IJobFactory iocJobfactory, IHttpClientFactory httpClient) { _scheduler = schedulerFactory.GetScheduler().GetAwaiter().GetResult(); _scheduler.JobFactory = iocJobfactory; _schedulerFactory = schedulerFactory; _iocJobfactory = iocJobfactory; _httpClient = httpClient; } public Task Execute(IJobExecutionContext context) { return Task.Run(async () => { using var dbContext = new SqlSugarClient(DBInitialize.GetConnectionConfigs(true), //全局上下文生效 db => { foreach (var item in DBInitialize.GetConnectionConfigs(false)) { db.GetConnection(item.ConfigId).DefaultConfig(); } }); string jobId = ""; JobDataMap jobData = null; OpenJobEntity dbJobEntity = null; DateTime now = DateTime.Now; try { jobData = context.JobDetail.JobDataMap; jobId = jobData.GetString("F_Id"); // 获取数据库中的任务 dbJobEntity = await dbContext.Queryable().Where(a => a.F_Id == jobId).FirstAsync(); if (dbJobEntity != null) { if (dbJobEntity.F_EnabledMark == true) { CronTriggerImpl trigger = context.Trigger as CronTriggerImpl; if (trigger != null) { if (trigger.CronExpressionString != dbJobEntity.F_CronExpress) { // 更新任务周期 trigger.CronExpressionString = dbJobEntity.F_CronExpress; await _scheduler.RescheduleJob(trigger.Key, trigger); return; } #region 执行任务 OpenJobLogEntity log = new OpenJobLogEntity(); log.F_Id = Utils.GuId(); log.F_JobId = jobId; log.F_JobName = dbJobEntity.F_JobName; log.F_CreatorTime = now; AlwaysResult result = new AlwaysResult(); if (dbJobEntity.F_JobType == 0) { //反射执行就行 var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory; //反射取指定前后缀的dll var referencedAssemblies = Directory.GetFiles(path, "HT.Cloud.*.dll").Select(Assembly.LoadFrom).ToArray(); var types = referencedAssemblies .SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces() .Contains(typeof(IJobTask)))).ToArray(); string filename = dbJobEntity.F_FileName; var implementType = types.Where(x => x.IsClass && x.FullName == filename).FirstOrDefault(); var obj = System.Activator.CreateInstance(implementType, dbContext); // 创建实例(带参数) MethodInfo method = implementType.GetMethod("Start", new Type[] { }); // 获取方法信息 object[] parameters = null; result = ((Task)method.Invoke(obj, parameters)).GetAwaiter().GetResult(); // 调用方法,参数为空 if (result.state.ToString() == ResultType.success.ToString()) { log.F_EnabledMark = true; log.F_Description = "执行成功," + result.message.ToString(); } else { log.F_EnabledMark = false; log.F_Description = "执行失败," + result.message.ToString(); } } else if (dbJobEntity.F_JobType == 5) { var dbContextTemp = dbContext.AsTenant().GetConnectionScope(dbJobEntity.F_JobDBProvider); try { dbContextTemp.Ado.BeginTran(); if (!string.IsNullOrEmpty(dbJobEntity.F_JobSqlParm)) { var dic = dbJobEntity.F_JobSqlParm.ToObject>(); List list = new List(); foreach (var item in dic) { list.Add(new SugarParameter(item.Key, item.Value)); } var dbResult = await dbContextTemp.Ado.SqlQueryAsync(dbJobEntity.F_JobSql, list); log.F_EnabledMark = true; log.F_Description = "执行成功," + dbResult.ToJson(); } else { var dbResult = await dbContextTemp.Ado.SqlQueryAsync(dbJobEntity.F_JobSql); log.F_EnabledMark = true; log.F_Description = "执行成功," + dbResult.ToJson(); } dbContextTemp.Ado.CommitTran(); } catch (Exception ex) { log.F_EnabledMark = false; log.F_Description = "执行失败," + ex.Message; dbContextTemp.Ado.RollbackTran(); } } else { HttpMethod method = HttpMethod.Get; switch (dbJobEntity.F_JobType) { case 1: method = HttpMethod.Get; break; case 2: method = HttpMethod.Post; break; case 3: method = HttpMethod.Put; break; case 4: method = HttpMethod.Delete; break; } var dic = dbJobEntity.F_RequestHeaders.ToObject>(); if (dic == null) { dic = new Dictionary(); } //请求头添加租户号 dic.Add("dbNumber", dbJobEntity.F_DbNumber); try { var temp = await new HttpWebClient(_httpClient).ExecuteAsync(dbJobEntity.F_RequestUrl, method, dbJobEntity.F_RequestString, dic); log.F_EnabledMark = true; log.F_Description = $"执行成功。{temp}"; } catch (Exception ex) { log.F_EnabledMark = false; log.F_Description = "执行失败," + ex.Message.ToString(); } } #endregion 执行任务 dbContext.Ado.BeginTran(); if (log.F_EnabledMark == true) { await dbContext.Updateable(a => new OpenJobEntity { F_LastRunMark = true, F_LastRunTime = now, }).Where(a => a.F_Id == jobId).ExecuteCommandAsync(); } else { await dbContext.Updateable(a => new OpenJobEntity { F_LastRunMark = false, F_LastRunTime = now, F_LastRunErrTime = now, F_LastRunErrMsg = log.F_Description }).Where(a => a.F_Id == jobId).ExecuteCommandAsync(); } if (dbJobEntity.F_IsLog == "是") { dbContext.Insertable(log).ExecuteCommand(); } dbContext.Ado.CommitTran(); } } } } catch (Exception ex) { LogHelper.WriteWithTime(ex); } }); } } }