z8018
2025-12-18 33846b73b1f13d6d6632e6755a94d7d0fe05508d
Merge branch 'htq20251215' of http://115.159.85.185:8098/r/ZhongRui/ALDbanyunxiangmu into htq20251215
已添加10个文件
已修改7个文件
1515 ■■■■ 文件已修改
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Common/TaskEnum/TaskStatusEnum.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Core/Quartz/ISchedulerCenter.cs 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Core/Quartz/JobFactory.cs 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Core/Quartz/JobSetup.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Core/Quartz/ResponseContent.cs 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Core/Quartz/SchedulerCenterServer.cs 470 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Core/Quartz/TaskInfoDto.cs 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Core/Quartz/TasksQz.cs 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_DTO/Quartz/JobConfig.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundBatchPickingService.cs 44 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs 44 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs 137 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_Inbound.cs 58 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_Outbound.cs 285 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Jobs/AgvTaskJob.cs 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Jobs/QuartzJobMildd.cs 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Program.cs 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_Common/TaskEnum/TaskStatusEnum.cs
@@ -19,6 +19,12 @@
        New = 100,
        /// <summary>
        /// å·²å‘送
        /// </summary>
        [Description("已发送")]
        HasSent = 105,
        /// <summary>
        /// å †åž›æœºå¾…执行
        /// </summary>
        [Description("堆垛机待执行")]
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_Core/Quartz/ISchedulerCenter.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace WIDESEA.QuartzJob
{
    public interface ISchedulerCenter
    {
        /// <summary>
        /// å¼€å¯ä»»åŠ¡è°ƒåº¦
        /// </summary>
        /// <returns></returns>
        Task<ResponseContent> StartScheduleAsync();
        /// <summary>
        /// åœæ­¢ä»»åŠ¡è°ƒåº¦
        /// </summary>
        /// <returns></returns>
        Task<ResponseContent> StopScheduleAsync();
        /// <summary>
        ///
        /// </summary>
        /// <param name="sysSchedule"></param>
        /// <returns></returns>
        Task<ResponseContent> AddScheduleJobAsync(TasksQz sysSchedule);
        /// <summary>
        /// åœæ­¢ä¸€ä¸ªä»»åŠ¡
        /// </summary>
        /// <param name="sysSchedule"></param>
        /// <returns></returns>
        Task<ResponseContent> StopScheduleJobAsync(TasksQz sysSchedule);
        /// <summary>
        /// æ£€æµ‹ä»»åŠ¡æ˜¯å¦å­˜åœ¨
        /// </summary>
        /// <param name="sysSchedule"></param>
        /// <returns></returns>
        Task<bool> IsExistScheduleJobAsync(TasksQz sysSchedule);
        /// <summary>
        /// æš‚停指定的计划任务
        /// </summary>
        /// <param name="sysSchedule"></param>
        /// <returns></returns>
        Task<ResponseContent> PauseJob(TasksQz sysSchedule);
        /// <summary>
        /// æ¢å¤ä¸€ä¸ªä»»åŠ¡
        /// </summary>
        /// <param name="sysSchedule"></param>
        /// <returns></returns>
        Task<ResponseContent> ResumeJob(TasksQz sysSchedule);
        /// <summary>
        /// èŽ·å–ä»»åŠ¡è§¦å‘å™¨çŠ¶æ€
        /// </summary>
        /// <param name="sysSchedule"></param>
        /// <returns></returns>
        Task<List<TaskInfoDto>> GetTaskStaus(TasksQz sysSchedule);
        /// <summary>
        /// èŽ·å–è§¦å‘å™¨æ ‡è¯†
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        string GetTriggerState(string key);
        /// <summary>
        /// ç«‹å³æ‰§è¡Œ ä¸€ä¸ªä»»åŠ¡
        /// </summary>
        /// <param name="tasksQz"></param>
        /// <returns></returns>
        Task<ResponseContent> ExecuteJobAsync(TasksQz tasksQz);
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_Core/Quartz/JobFactory.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
using Quartz;
using Microsoft.Extensions.DependencyInjection;
using Quartz.Spi;
using System;
using System.Collections.Generic;
using System.Text;
namespace WIDESEA.QuartzJob
{
    public class JobFactory : IJobFactory
    {
        /// <summary>
        /// æ³¨å…¥åå°„获取依赖对象
        /// </summary>
        private readonly IServiceProvider _serviceProvider;
        public JobFactory(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
        }
        /// <summary>
        /// å®žçŽ°æŽ¥å£Job
        /// </summary>
        /// <param name="bundle"></param>
        /// <param name="scheduler"></param>
        /// <returns></returns>
        public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
        {
            try
            {
                var serviceScope = _serviceProvider.CreateScope();
                var job = serviceScope.ServiceProvider.GetService(bundle.JobDetail.JobType) as IJob;
                return job;
            }
            catch (Exception)
            {
                throw;
            }
        }
        public void ReturnJob(IJob job)
        {
            var disposable = job as IDisposable;
            if (disposable != null)
            {
                disposable.Dispose();
            }
        }
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_Core/Quartz/JobSetup.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
using Microsoft.Extensions.DependencyInjection;
using Quartz;
using Quartz.Spi;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
namespace WIDESEA.QuartzJob
{
    /// <summary>
    /// ä»»åŠ¡è°ƒåº¦ å¯åŠ¨æœåŠ¡
    /// </summary>
    public static class JobSetup
    {
        public static void AddJobSetup(this IServiceCollection services)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));
            //services.AddSingleton<IJobFactory, JobFactory>();
            //services.AddTransient<AgvTaskJob>();//Job使用瞬时依赖注入
            //services.AddSingleton<ISchedulerCenter, SchedulerCenterServer>();
        }
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_Core/Quartz/ResponseContent.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace WIDESEA.QuartzJob
{
    public class ResponseContent
    {
        public ResponseContent()
        {
        }
        public ResponseContent(bool status)
        {
            Status = status;
        }
        public bool Status { get; set; }
        public string Code { get; set; }
        public string Message { get; set; }
        public object Data { get; set; }
        public ResponseContent OK()
        {
            Status = true;
            return this;
        }
        public static ResponseContent Instance
        {
            get { return new ResponseContent(); }
        }
        public ResponseContent OK(string message = null, object data = null)
        {
            Status = true;
            Message = message;
            Data = data;
            return this;
        }
        public ResponseContent Error(string message = null)
        {
            Status = false;
            Message = message;
            return this;
        }
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_Core/Quartz/SchedulerCenterServer.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,470 @@
using Quartz;
using Quartz.Impl;
using Quartz.Impl.Triggers;
using Quartz.Spi;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using WIDESEA_Core.Helper;
namespace WIDESEA.QuartzJob
{
    public class SchedulerCenterServer : ISchedulerCenter
    {
        private Task<IScheduler> _scheduler;
        private readonly IJobFactory _iocjobFactory;
        public SchedulerCenterServer(IJobFactory jobFactory)
        {
            _iocjobFactory = jobFactory;
            _scheduler = GetSchedulerAsync();
        }
        private Task<IScheduler> GetSchedulerAsync()
        {
            if (_scheduler != null)
                return _scheduler;
            else
            {
                // ä»ŽFactory中获取Scheduler实例
                NameValueCollection collection = new NameValueCollection
                {
                    { "quartz.serializer.type", "binary" },
                };
                StdSchedulerFactory factory = new StdSchedulerFactory(collection);
                return _scheduler = factory.GetScheduler();
            }
        }
        /// <summary>
        /// å¼€å¯ä»»åŠ¡è°ƒåº¦
        /// </summary>
        /// <returns></returns>
        public async Task<ResponseContent> StartScheduleAsync()
        {
            var result = new ResponseContent();
            try
            {
                _scheduler.Result.JobFactory = _iocjobFactory;
                if (!_scheduler.Result.IsStarted)
                {
                    //等待任务运行完成
                    await _scheduler.Result.Start();
                    ConsoleHelper.WriteSuccessLine("任务调度开启!");
                    result = ResponseContent.Instance.OK($"任务调度开启成功");
                    return result;
                }
                else
                {
                    result = ResponseContent.Instance.OK($"任务调度已经开启");
                    return result;
                }
            }
            catch (Exception)
            {
                throw;
            }
        }
        /// <summary>
        /// åœæ­¢ä»»åŠ¡è°ƒåº¦
        /// </summary>
        /// <returns></returns>
        public async Task<ResponseContent> StopScheduleAsync()
        {
            var result = new ResponseContent();
            try
            {
                if (!_scheduler.Result.IsShutdown)
                {
                    //等待任务运行完成
                    await _scheduler.Result.Shutdown();
                    //await Console.Out.WriteLineAsync("任务调度停止!");
                    result = ResponseContent.Instance.OK($"任务调度停止成功");
                    return result;
                }
                else
                {
                    result = ResponseContent.Instance.OK($"任务调度已经停止");
                    return result;
                }
            }
            catch (Exception)
            {
                throw;
            }
        }
        /// <summary>
        /// æ·»åŠ ä¸€ä¸ªè®¡åˆ’ä»»åŠ¡ï¼ˆæ˜ å°„ç¨‹åºé›†æŒ‡å®šIJob实现类)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tasksQz"></param>
        /// <returns></returns>
        public async Task<ResponseContent> AddScheduleJobAsync(TasksQz tasksQz)
        {
            var result = new ResponseContent();
            if (tasksQz != null)
            {
                try
                {
                    JobKey jobKey = new JobKey(tasksQz.Id.ToString(), tasksQz.JobGroup);
                    if (await _scheduler.Result.CheckExists(jobKey))
                    {
                        result = ResponseContent.Instance.OK($"该任务计划已经在执行:【{tasksQz.Name}】,请勿重复启动!");
                        return result;
                    }
                    #region è®¾ç½®å¼€å§‹æ—¶é—´å’Œç»“束时间
                    if (tasksQz.BeginTime == null)
                    {
                        tasksQz.BeginTime = DateTime.Now;
                    }
                    DateTimeOffset starRunTime = DateBuilder.NextGivenSecondDate(tasksQz.BeginTime, 1);//设置开始时间
                    if (tasksQz.EndTime == null)
                    {
                        tasksQz.EndTime = DateTime.MaxValue.AddDays(-1);
                    }
                    DateTimeOffset endRunTime = DateBuilder.NextGivenSecondDate(tasksQz.EndTime, 1);//设置暂停时间
                    #endregion
                    #region é€šè¿‡åå°„获取程序集类型和类
                    Assembly assembly = Assembly.Load(new AssemblyName(tasksQz.AssemblyName));
                    Type jobType = assembly.GetType(tasksQz.AssemblyName + "." + tasksQz.ClassName);
                    #endregion
                    //判断任务调度是否开启
                    //if (!_scheduler.Result.IsStarted)
                    //{
                    //    await StartScheduleAsync();
                    //}
                    //传入反射出来的执行程序集
                    IJobDetail job = new JobDetailImpl(tasksQz.Id.ToString(), tasksQz.JobGroup, jobType);
                    job.JobDataMap.Add("JobParam", tasksQz.JobParams);
                    ITrigger trigger;
                    #region æ³›åž‹ä¼ é€’
                    //IJobDetail job = JobBuilder.Create<T>()
                    //    .WithIdentity(sysSchedule.Name, sysSchedule.JobGroup)
                    //    .Build();
                    #endregion
                    if (tasksQz.Cron != null && CronExpression.IsValidExpression(tasksQz.Cron) && tasksQz.TriggerType > 0)
                    {
                        trigger = CreateCronTrigger(tasksQz);
                        ((CronTriggerImpl)trigger).MisfireInstruction = MisfireInstruction.CronTrigger.DoNothing;
                    }
                    else
                    {
                        trigger = CreateSimpleTrigger(tasksQz);
                    }
                    // å‘Šè¯‰Quartz使用我们的触发器来安排作业
                    await _scheduler.Result.ScheduleJob(job, trigger);
                    //await Task.Delay(TimeSpan.FromSeconds(120));
                    //await Console.Out.WriteLineAsync("关闭了调度器!");
                    //await _scheduler.Result.Shutdown();
                    result = ResponseContent.Instance.OK($"【{tasksQz.Name}】成功");
                    return result;
                }
                catch (Exception ex)
                {
                    result = ResponseContent.Instance.Error($"任务计划异常:【{ex.Message}】");
                    return result;
                }
            }
            else
            {
                result = ResponseContent.Instance.Error($"任务计划不存在:【{tasksQz?.Name}】");
                return result;
            }
        }
        /// <summary>
        /// ä»»åŠ¡æ˜¯å¦å­˜åœ¨?
        /// </summary>
        /// <returns></returns>
        public async Task<bool> IsExistScheduleJobAsync(TasksQz sysSchedule)
        {
            JobKey jobKey = new JobKey(sysSchedule.Id.ToString(), sysSchedule.JobGroup);
            if (await _scheduler.Result.CheckExists(jobKey))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// æš‚停一个指定的计划任务
        /// </summary>
        /// <returns></returns>
        public async Task<ResponseContent> StopScheduleJobAsync(TasksQz sysSchedule)
        {
            var result = new ResponseContent();
            try
            {
                JobKey jobKey = new JobKey(sysSchedule.Id.ToString(), sysSchedule.JobGroup);
                if (!await _scheduler.Result.CheckExists(jobKey))
                {
                    result = ResponseContent.Instance.Error($"未找到要暂停的任务:【{sysSchedule.Name}】");
                    return result;
                }
                else
                {
                    await _scheduler.Result.DeleteJob(jobKey);
                    result = ResponseContent.Instance.OK($"【{sysSchedule.Name}】成功");
                    return result;
                }
            }
            catch (Exception)
            {
                throw;
            }
        }
        /// <summary>
        /// æ¢å¤æŒ‡å®šçš„计划任务
        /// </summary>
        /// <param name="sysSchedule"></param>
        /// <returns></returns>
        public async Task<ResponseContent> ResumeJob(TasksQz sysSchedule)
        {
            var result = new ResponseContent();
            try
            {
                JobKey jobKey = new JobKey(sysSchedule.Id.ToString(), sysSchedule.JobGroup);
                if (!await _scheduler.Result.CheckExists(jobKey))
                {
                    result = ResponseContent.Instance.Error($"未找到要恢复的任务:【{sysSchedule.Name}】");
                    return result;
                }
                await _scheduler.Result.ResumeJob(jobKey);
                result = ResponseContent.Instance.OK($"【{sysSchedule.Name}】成功");
                return result;
            }
            catch (Exception)
            {
                throw;
            }
        }
        /// <summary>
        /// æš‚停指定的计划任务
        /// </summary>
        /// <param name="sysSchedule"></param>
        /// <returns></returns>
        public async Task<ResponseContent> PauseJob(TasksQz sysSchedule)
        {
            var result = new ResponseContent();
            try
            {
                JobKey jobKey = new JobKey(sysSchedule.Id.ToString(), sysSchedule.JobGroup);
                if (!await _scheduler.Result.CheckExists(jobKey))
                {
                    result = ResponseContent.Instance.Error($"未找到要暂停的任务:【{sysSchedule.Name}】");
                    return result;
                }
                await _scheduler.Result.PauseJob(jobKey);
                result = ResponseContent.Instance.Error($"【{sysSchedule.Name}】成功");
                return result;
            }
            catch (Exception)
            {
                throw;
            }
        }
        #region çŠ¶æ€çŠ¶æ€å¸®åŠ©æ–¹æ³•
        public async Task<List<TaskInfoDto>> GetTaskStaus(TasksQz sysSchedule)
        {
            var ls = new List<TaskInfoDto>();
            var noTask = new List<TaskInfoDto>{ new TaskInfoDto {
                jobId = sysSchedule.Id.ToString(),
                jobGroup = sysSchedule.JobGroup,
                triggerId = "",
                triggerGroup = "",
                triggerStatus = "不存在"
            } };
            JobKey jobKey = new JobKey(sysSchedule.Id.ToString(), sysSchedule.JobGroup);
            IJobDetail job = await _scheduler.Result.GetJobDetail(jobKey);
            if (job == null)
            {
                return noTask;
            }
            //info.Append(string.Format("任务ID:{0}\r\n任务名称:{1}\r\n", job.Key.Name, job.Description));
            var triggers = await _scheduler.Result.GetTriggersOfJob(jobKey);
            if (triggers == null || triggers.Count == 0)
            {
                return noTask;
            }
            foreach (var trigger in triggers)
            {
                var triggerStaus = await _scheduler.Result.GetTriggerState(trigger.Key);
                string state = GetTriggerState(triggerStaus.ToString());
                ls.Add(new TaskInfoDto
                {
                    jobId = job.Key.Name,
                    jobGroup = job.Key.Group,
                    triggerId = trigger.Key.Name,
                    triggerGroup = trigger.Key.Group,
                    triggerStatus = state
                });
                //info.Append(string.Format("触发器ID:{0}\r\n触发器名称:{1}\r\n状态:{2}\r\n", item.Key.Name, item.Description, state));
            }
            return ls;
        }
        public string GetTriggerState(string key)
        {
            string state = null;
            if (key != null)
                key = key.ToUpper();
            switch (key)
            {
                case "1":
                    state = "暂停";
                    break;
                case "2":
                    state = "完成";
                    break;
                case "3":
                    state = "出错";
                    break;
                case "4":
                    state = "阻塞";
                    break;
                case "0":
                    state = "正常";
                    break;
                case "-1":
                    state = "不存在";
                    break;
                case "BLOCKED":
                    state = "阻塞";
                    break;
                case "COMPLETE":
                    state = "完成";
                    break;
                case "ERROR":
                    state = "出错";
                    break;
                case "NONE":
                    state = "不存在";
                    break;
                case "NORMAL":
                    state = "正常";
                    break;
                case "PAUSED":
                    state = "暂停";
                    break;
            }
            return state;
        }
        #endregion
        #region åˆ›å»ºè§¦å‘器帮助方法
        /// <summary>
        /// åˆ›å»ºSimpleTrigger触发器(简单触发器)
        /// </summary>
        /// <param name="sysSchedule"></param>
        /// <param name="starRunTime"></param>
        /// <param name="endRunTime"></param>
        /// <returns></returns>
        private ITrigger CreateSimpleTrigger(TasksQz sysSchedule)
        {
            if (sysSchedule.CycleRunTimes > 0)
            {
                ITrigger trigger = TriggerBuilder.Create()
                .WithIdentity(sysSchedule.Id.ToString(), sysSchedule.JobGroup)
                .StartAt(sysSchedule.BeginTime.Value)
                .WithSimpleSchedule(x => x
                    .WithIntervalInSeconds(sysSchedule.IntervalSecond)
                    .WithRepeatCount(sysSchedule.CycleRunTimes - 1))
                .EndAt(sysSchedule.EndTime.Value)
                .Build();
                return trigger;
            }
            else
            {
                ITrigger trigger = TriggerBuilder.Create()
                .WithIdentity(sysSchedule.Id.ToString(), sysSchedule.JobGroup)
                .StartAt(sysSchedule.BeginTime.Value)
                .WithSimpleSchedule(x => x
                    .WithIntervalInSeconds(sysSchedule.IntervalSecond)
                    .RepeatForever()
                )
                .EndAt(sysSchedule.EndTime.Value)
                .Build();
                return trigger;
            }
            // è§¦å‘作业立即运行,然后每10秒重复一次,无限循环
        }
        /// <summary>
        /// åˆ›å»ºç±»åž‹Cron的触发器
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        private ITrigger CreateCronTrigger(TasksQz sysSchedule)
        {
            // ä½œä¸šè§¦å‘器
            return TriggerBuilder.Create()
                   .WithIdentity(sysSchedule.Id.ToString(), sysSchedule.JobGroup)
                   .StartAt(sysSchedule.BeginTime.Value)//开始时间
                   .EndAt(sysSchedule.EndTime.Value)//结束数据
                   .WithCronSchedule(sysSchedule.Cron)//指定cron表达式
                   .ForJob(sysSchedule.Id.ToString(), sysSchedule.JobGroup)//作业名称
                   .Build();
        }
        #endregion
        /// <summary>
        /// ç«‹å³æ‰§è¡Œ ä¸€ä¸ªä»»åŠ¡
        /// </summary>
        /// <param name="tasksQz"></param>
        /// <returns></returns>
        public async Task<ResponseContent> ExecuteJobAsync(TasksQz tasksQz)
        {
            var result = new ResponseContent();
            try
            {
                JobKey jobKey = new JobKey(tasksQz.Id.ToString(), tasksQz.JobGroup);
                //判断任务是否存在,存在则 è§¦å‘一次,不存在则先添加一个任务,触发以后再 åœæ­¢ä»»åŠ¡
                if (!await _scheduler.Result.CheckExists(jobKey))
                {
                    //不存在 åˆ™ æ·»åŠ ä¸€ä¸ªè®¡åˆ’ä»»åŠ¡
                    await AddScheduleJobAsync(tasksQz);
                    //触发执行一次
                    await _scheduler.Result.TriggerJob(jobKey);
                    //停止任务
                    await StopScheduleJobAsync(tasksQz);
                    result = ResponseContent.Instance.OK($"立即执行计划任务:【{tasksQz.Name}】成功");
                }
                else
                {
                    await _scheduler.Result.TriggerJob(jobKey);
                    result = ResponseContent.Instance.OK($"立即执行计划任务:【{tasksQz.Name}】成功");
                }
            }
            catch (Exception ex)
            {
                result = ResponseContent.Instance.Error($"立即执行计划任务失败:【{ex.Message}】");
            }
            return result;
        }
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_Core/Quartz/TaskInfoDto.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace WIDESEA.QuartzJob
{
    public class TaskInfoDto
    {
        /// <summary>
        /// ä»»åŠ¡ID
        /// </summary>
        public string jobId { get; set; }
        /// <summary>
        /// ä»»åŠ¡åç§°
        /// </summary>
        public string jobName { get; set; }
        /// <summary>
        /// ä»»åŠ¡åˆ†ç»„
        /// </summary>
        public string jobGroup { get; set; }
        /// <summary>
        /// è§¦å‘器ID
        /// </summary>
        public string triggerId { get; set; }
        /// <summary>
        /// è§¦å‘器名称
        /// </summary>
        public string triggerName { get; set; }
        /// <summary>
        /// è§¦å‘器分组
        /// </summary>
        public string triggerGroup { get; set; }
        /// <summary>
        /// è§¦å‘器状态
        /// </summary>
        public string triggerStatus { get; set; }
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_Core/Quartz/TasksQz.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace WIDESEA.QuartzJob
{
    /// <summary>
    /// ä»»åŠ¡è®¡åˆ’è¡¨
    /// </summary>
    public class TasksQz
    {
        /// <summary>
        /// ä»»åŠ¡åç§°
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// ä»»åŠ¡åˆ†ç»„
        /// </summary>
        public string JobGroup { get; set; }
        /// <summary>
        /// ä»»åŠ¡è¿è¡Œæ—¶é—´è¡¨è¾¾å¼
        /// </summary>
        public string Cron { get; set; }
        /// <summary>
        /// ä»»åŠ¡æ‰€åœ¨DLL对应的程序集名称
        /// </summary>
        public string AssemblyName { get; set; }
        /// <summary>
        /// ä»»åŠ¡æ‰€åœ¨ç±»
        /// </summary>
        public string ClassName { get; set; }
        /// <summary>
        /// ä»»åŠ¡æè¿°
        /// </summary>
        public string Remark { get; set; }
        /// <summary>
        /// æ‰§è¡Œæ¬¡æ•°
        /// </summary>
        public int RunTimes { get; set; }
        /// <summary>
        /// å¼€å§‹æ—¶é—´
        /// </summary>
        public DateTime? BeginTime { get; set; }
        /// <summary>
        /// ç»“束时间
        /// </summary>
        public DateTime? EndTime { get; set; }
        /// <summary>
        /// è§¦å‘器类型(0、simple 1、cron)
        /// </summary>
        public int TriggerType { get; set; }
        /// <summary>
        /// æ‰§è¡Œé—´é𔿗¶é—´, ç§’为单位
        /// </summary>
        public int IntervalSecond { get; set; }
        /// <summary>
        /// å¾ªçŽ¯æ‰§è¡Œæ¬¡æ•°
        /// </summary>
        public int CycleRunTimes { get; set; }
        /// <summary>
        /// æ˜¯å¦å¯åЍ
        /// </summary>
        public bool IsStart { get; set; } = true;
        /// <summary>
        /// æ‰§è¡Œä¼ å‚
        /// </summary>
        public string JobParams { get; set; }
        public bool? IsDeleted { get; set; }
        /// <summary>
        /// åˆ›å»ºæ—¶é—´
        /// </summary>
        public DateTime CreateTime { get; set; } = DateTime.Now;
        /// <summary>
        /// ä»»åŠ¡å†…å­˜ä¸­çš„çŠ¶æ€
        /// </summary>
        public List<TaskInfoDto> Triggers { get; set; }
        public int Id { get; set; }
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_DTO/Quartz/JobConfig.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WIDESEA_DTO.Quartz
{
    public class JobConfig
    {
        public Type JobType { get; set; }
        public string Identity { get; set; }
        public string Group { get; set; }
        public int IntervalInSeconds { get; set; }
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundBatchPickingService.cs
@@ -3665,29 +3665,29 @@
                });
              
                var essTask = new TaskModel()
                {
                    taskType = "putaway",
                    taskGroupCode = "",
                    groupPriority = 0,
                    tasks = new List<TasksType>{  new() {
                            taskCode = returnTask.TaskNum.ToString(),
                            taskPriority = 0,
                            taskDescribe = new TaskDescribeType
                            {
                                containerCode = palletCode,
                                containerType = "CT_KUBOT_STANDARD",
                                fromLocationCode = stations.GetValueOrDefault(targetAddress) ?? "",
                                toStationCode = "",
                                toLocationCode = returnTask.TargetAddress,
                                deadline = 0,
                                storageTag = ""
                            }
                        } }
                };
                //var essTask = new TaskModel()
                //{
                //    taskType = "putaway",
                //    taskGroupCode = "",
                //    groupPriority = 0,
                //    tasks = new List<TasksType>{  new() {
                //            taskCode = returnTask.TaskNum.ToString(),
                //            taskPriority = 0,
                //            taskDescribe = new TaskDescribeType
                //            {
                //                containerCode = palletCode,
                //                containerType = "CT_KUBOT_STANDARD",
                //                fromLocationCode = stations.GetValueOrDefault(targetAddress) ?? "",
                //                toStationCode = "",
                //                toLocationCode = returnTask.TargetAddress,
                //                deadline = 0,
                //                storageTag = ""
                //            }
                //        } }
                //};
                var resultTask = await _eSSApiService.CreateTaskAsync(essTask);
                _logger.LogInformation($"ReturnRemaining åˆ›å»ºä»»åŠ¡æˆåŠŸ: {resultTask}");
                //var resultTask = await _eSSApiService.CreateTaskAsync(essTask);
                //_logger.LogInformation($"ReturnRemaining åˆ›å»ºä»»åŠ¡æˆåŠŸ: {resultTask}");
             
            }
            catch (Exception ex)
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs
@@ -1678,29 +1678,29 @@
                //if (moveResult)
                //{
                //  åˆ›å»ºå›žåº“任务
                var essTask = new TaskModel()
                {
                    taskType = "putaway",
                    taskGroupCode = "",
                    groupPriority = 0,
                    tasks = new List<TasksType>{  new() {
                            taskCode = returnTask.TaskNum.ToString(),
                            taskPriority = 0,
                            taskDescribe = new TaskDescribeType
                            {
                                containerCode = palletCode,
                                containerType = "CT_KUBOT_STANDARD",
                                fromLocationCode = stations.GetValueOrDefault(targetAddress) ?? "",
                                toStationCode = "",
                                toLocationCode = returnTask.TargetAddress,
                                deadline = 0,
                                storageTag = ""
                            }
                        } }
                };
                //var essTask = new TaskModel()
                //{
                //    taskType = "putaway",
                //    taskGroupCode = "",
                //    groupPriority = 0,
                //    tasks = new List<TasksType>{  new() {
                //            taskCode = returnTask.TaskNum.ToString(),
                //            taskPriority = 0,
                //            taskDescribe = new TaskDescribeType
                //            {
                //                containerCode = palletCode,
                //                containerType = "CT_KUBOT_STANDARD",
                //                fromLocationCode = stations.GetValueOrDefault(targetAddress) ?? "",
                //                toStationCode = "",
                //                toLocationCode = returnTask.TargetAddress,
                //                deadline = 0,
                //                storageTag = ""
                //            }
                //        } }
                //};
                var resultTask = await _eSSApiService.CreateTaskAsync(essTask);
                _logger.LogInformation($"ReturnRemaining åˆ›å»ºä»»åŠ¡æˆåŠŸ: {resultTask}");
                //var resultTask = await _eSSApiService.CreateTaskAsync(essTask);
                //_logger.LogInformation($"ReturnRemaining åˆ›å»ºä»»åŠ¡æˆåŠŸ: {resultTask}");
                //}
            }
            catch (Exception ex)
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
@@ -292,7 +292,7 @@
            task.TaskStatus = TaskStatusEnum.Finish.ObjToInt();
            //  BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成);
            var result = _task_HtyService.DeleteAndMoveIntoHty(task, OperateTypeEnum.人工删除);
            var result = _task_HtyService.DeleteAndMoveIntoHty(task, OperateTypeEnum.自动完成);
            if (!result)
            {
                await Db.Deleteable(task).ExecuteCommandAsync();
@@ -502,27 +502,27 @@
            locationInfo.LocationStatus = LocationStatusEnum.Free.ObjToInt();
            _locationInfoService.Repository.UpdateData(locationInfo);
            var outloks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>().Where(x => x.TaskNum == task.TaskNum).ToListAsync();
            var stock = _stockService.StockInfoService.Db.Queryable<Dt_StockInfo>()
                                  .Includes(x => x.Details)
                                  .Where(x => x.PalletCode == task.PalletCode)
                                  .First();
            var stockids = outloks.Select(x => x.StockId).ToList();
            _stockService.StockInfoService.Db.Updateable<Dt_StockInfo>()
                                  .SetColumns(it => new Dt_StockInfo
            stock.StockStatus = StockStatusEmun.出库完成.ObjToInt();
            stock.LocationCode = "";
            stock.Details.ForEach(x =>
                                  {
                                      StockStatus = StockStatusEmun.出库锁定.ObjToInt()
                                  })
                                  .Where(it => stockids.Contains(it.Id))
                                  .ExecuteCommand();
                x.Status = StockStatusEmun.出库完成.ObjToInt();
            });
            _stockService.StockInfoDetailService.Db.Updateable<Dt_StockInfoDetail>()
                                  .SetColumns(it => new Dt_StockInfoDetail
            _stockService.StockInfoService.Db.UpdateNav(stock).IncludesAllFirstLayer().ExecuteCommand();
            var result = _task_HtyService.DeleteAndMoveIntoHty(task, OperateTypeEnum.自动完成);
            if (!result)
                                  {
                                      Status = StockStatusEmun.出库锁定.ObjToInt()
                                  })
                                  .Where(it => stockids.Contains(it.StockId))
                                  .ExecuteCommand();
                await Db.Deleteable(task).ExecuteCommandAsync();
            }
            return WebResponseContent.Instance.OK();
@@ -566,10 +566,9 @@
                stockInfo.StockStatus = StockStatusEmun.入库完成.ObjToInt();
                _stockRepository.UpdateData(stockInfo);
                var outboundOrder = _outboundOrderService.Db.Queryable<Dt_OutboundOrder>().First(x => x.OrderNo == task.OrderNo);
                //var outboundOrder = _outboundOrderService.Db.Queryable<Dt_OutboundOrder>().First(x => x.OrderNo == task.OrderNo);
                task.TaskStatus = TaskStatusEnum.Finish.ObjToInt();
                // BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? WIDESEA_Core.Enums.OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成);
                var result = _task_HtyService.DeleteAndMoveIntoHty(task, OperateTypeEnum.人工删除);
                if (!result)
                {
@@ -584,14 +583,14 @@
                    _logger.LogInformation($"InEmptyTaskCompleted AddLocationStatusChangeRecord : {ex.Message} ");
                }
                if (outboundOrder != null)
                {
                    await HandleOutboundOrderToMESCompletion(outboundOrder, outboundOrder.OrderNo);
                }
                else
                {
                    _logger.LogInformation($"TaskService  InEmptyTaskCompleted: {task.TaskNum} ,未找到出库单。  ");
                }
                //if (outboundOrder != null)
                //{
                //    await HandleOutboundOrderToMESCompletion(outboundOrder, outboundOrder.OrderNo);
                //}
                //else
                //{
                //    _logger.LogInformation($"TaskService  InEmptyTaskCompleted: {task.TaskNum} ,未找到出库单。  ");
                //}
                return content;
            }
@@ -636,23 +635,23 @@
                var beforelocationStatus = locationInfo.LocationStatus;
                // èŽ·å–æ‰€æœ‰å›žåº“ä¸­çš„å‡ºåº“é”å®šè®°å½•
                var returnLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
                    .Where(it => it.OrderNo == task.OrderNo &&
                               it.PalletCode == task.PalletCode &&
                               it.Status == (int)OutLockStockStatusEnum.回库中)
                    .ToListAsync();
                //var returnLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
                //    .Where(it => it.OrderNo == task.OrderNo &&
                //               it.PalletCode == task.PalletCode &&
                //               it.Status == (int)OutLockStockStatusEnum.回库中)
                //    .ToListAsync();
                // æ›´æ–°å‡ºåº“锁定记录状态为回库完成
                foreach (var lockInfo in returnLocks)
                {
                    lockInfo.Status = (int)OutLockStockStatusEnum.已回库;
                }
                //foreach (var lockInfo in returnLocks)
                //{
                //    lockInfo.Status = (int)OutLockStockStatusEnum.已回库;
                //}
                if (returnLocks.Any())
                {
                    await _outStockLockInfoService.Db.Updateable(returnLocks).ExecuteCommandAsync();
                    _logger.LogInformation($"更新{returnLocks.Count}条锁定记录为已回库状态");
                }
                //if (returnLocks.Any())
                //{
                //    await _outStockLockInfoService.Db.Updateable(returnLocks).ExecuteCommandAsync();
                //    _logger.LogInformation($"更新{returnLocks.Count}条锁定记录为已回库状态");
                //}
                // æ›´æ–°åº“存信息
                stockInfo.LocationCode = task.TargetAddress;
@@ -664,7 +663,7 @@
                    foreach (var detail in stockInfo.Details)
                    {
                        detail.Status = StockStatusEmun.入库完成.ObjToInt();
                        detail.OutboundQuantity = 0; // å…¥åº“完成时出库数量清零
                        detail.OutboundQuantity = 0;
                    }
                    _stockService.StockInfoDetailService.Repository.UpdateData(stockInfo.Details);
                }
@@ -673,7 +672,7 @@
                // åˆ é™¤é›¶åº“存数据
                await DeleteZeroQuantityStockDetails(stockInfo.Id);
                await UpdateAffectedOrderDetails(task.OrderNo, returnLocks);
                //await UpdateAffectedOrderDetails(task.OrderNo, returnLocks);
                // æ›´æ–°è´§ä½çŠ¶æ€
                if (stockInfo.PalletType == PalletTypeEnum.Empty.ObjToInt())
                {
@@ -697,7 +696,7 @@
                    await Db.Deleteable(task).ExecuteCommandAsync();
                }
                await RecalculateOrderStatus(task.OrderNo);
                //await RecalculateOrderStatus(task.OrderNo);
                try
                {
                    // è®°å½•货位状态变更
@@ -714,32 +713,32 @@
                    _logger.LogInformation($"InPickTaskCompleted AddLocationStatusChangeRecord : {ex.Message} ");
                }
                _logger.LogInformation($"托盘回库完成处理成功 - ä»»åŠ¡å·: {task.TaskNum}, æ‰˜ç›˜: {task.PalletCode}, è®¢å•: {task.OrderNo} è´§ä½çŠ¶æ€ï¼š{locationInfo.LocationStatus}");
                _ = Task.Run(async () =>
                {
                    try
                    {
                        var outboundOrder = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>()
                            .FirstAsync(x => x.OrderNo == task.OrderNo);
                //_logger.LogInformation($"托盘回库完成处理成功 - ä»»åŠ¡å·: {task.TaskNum}, æ‰˜ç›˜: {task.PalletCode}, è®¢å•: {task.OrderNo} è´§ä½çŠ¶æ€ï¼š{locationInfo.LocationStatus}");
                //_ = Task.Run(async () =>
                //{
                //    try
                //    {
                //        var outboundOrder = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>()
                //            .FirstAsync(x => x.OrderNo == task.OrderNo);
                        if (outboundOrder != null)
                        {
                            // æ£€æŸ¥è®¢å•是否已完成,只有完成时才向MES反馈
                            if (outboundOrder.OrderStatus == (int)OutOrderStatusEnum.出库完成)
                            {
                                await HandleOutboundOrderToMESCompletion(outboundOrder, outboundOrder.OrderNo);
                            }
                            else
                            {
                                _logger.LogInformation($"订单{task.OrderNo}状态为{outboundOrder.OrderStatus},暂不向MES反馈");
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError($"异步MES反馈处理失败 - OrderNo: {task.OrderNo}, Error: {ex.Message}");
                    }
                });
                //        if (outboundOrder != null)
                //        {
                //            // æ£€æŸ¥è®¢å•是否已完成,只有完成时才向MES反馈
                //            if (outboundOrder.OrderStatus == (int)OutOrderStatusEnum.出库完成)
                //            {
                //                await HandleOutboundOrderToMESCompletion(outboundOrder, outboundOrder.OrderNo);
                //            }
                //            else
                //            {
                //                _logger.LogInformation($"订单{task.OrderNo}状态为{outboundOrder.OrderStatus},暂不向MES反馈");
                //            }
                //        }
                //    }
                //    catch (Exception ex)
                //    {
                //        _logger.LogError($"异步MES反馈处理失败 - OrderNo: {task.OrderNo}, Error: {ex.Message}");
                //    }
                //});
            }
            catch (Exception ex)
            {
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_Inbound.cs
@@ -127,33 +127,33 @@
                    _stockRepository.UpdateData(stockInfo);
                    _unitOfWorkManage.CommitTran();
                }
                TaskModel esstask = new TaskModel()
                {
                    taskType = "putaway",
                    taskGroupCode = "",
                    groupPriority = 0,
                    tasks = new List<TasksType>
                    {
                            new()
                            {
                                taskCode=newTask.TaskNum.ToString(),
                                taskPriority=0,
                                taskDescribe=new TaskDescribeType{
                                containerCode=palletCode,
                                containerType= "CT_KUBOT_STANDARD",
                                fromLocationCode=stations.GetValueOrDefault(stationCode)??"",
                                toStationCode="",
                                toLocationCode=locationInfo.LocationCode,
                                deadline=0,storageTag=""
                                }
                            }
                    }
                };
                //TaskModel esstask = new TaskModel()
                //{
                //    taskType = "putaway",
                //    taskGroupCode = "",
                //    groupPriority = 0,
                //    tasks = new List<TasksType>
                //    {
                //            new()
                //            {
                //                taskCode=newTask.TaskNum.ToString(),
                //                taskPriority=0,
                //                taskDescribe=new TaskDescribeType{
                //                containerCode=palletCode,
                //                containerType= "CT_KUBOT_STANDARD",
                //                fromLocationCode=stations.GetValueOrDefault(stationCode)??"",
                //                toStationCode="",
                //                toLocationCode=locationInfo.LocationCode,
                //                deadline=0,storageTag=""
                //                }
                //            }
                //    }
                //};
 
                var result = await _eSSApiService.CreateTaskAsync(esstask);
                //var result = await _eSSApiService.CreateTaskAsync(esstask);
                _logger.LogInformation("创建任务返回:  " + result);
                if (result)
                //_logger.LogInformation("创建任务返回:  " + result);
                //if (result)
                {
                    try
                    {
@@ -169,10 +169,10 @@
                    }
                    return WebResponseContent.Instance.OK();
                }
                else
                {
                    return WebResponseContent.Instance.Error("下发机器人任务失败!");
                }
                //else
                //{
                //    return WebResponseContent.Instance.Error("下发机器人任务失败!");
                //}
            }
            catch (Exception ex)
            {
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_Outbound.cs
@@ -88,31 +88,33 @@
                    _unitOfWorkManage.CommitTran();
                    TaskModel esstask = new TaskModel()
                    {
                        taskType = "carry",
                        taskGroupCode = "",
                        groupPriority = 0,
                        tasks = new List<TasksType>
                        {
                                new()
                                {
                                    taskCode=task.TaskNum.ToString(),
                                    taskPriority=0,
                                    taskDescribe=new TaskDescribeType{
                                    containerCode=stockInfo.PalletCode,
                                    containerType= "CT_KUBOT_STANDARD",
                                    fromLocationCode=stockInfo.LocationCode??"",
                                    toStationCode="",
                                    toLocationCode="1-2",
                                    deadline=0,storageTag=""
                                    }
                                }
                        }
                    };
                    var result = await _eSSApiService.CreateTaskAsync(esstask);
                    //TaskModel esstask = new TaskModel()
                    //{
                    //    taskType = "carry",
                    //    taskGroupCode = "",
                    //    groupPriority = 0,
                    //    tasks = new List<TasksType>
                    //    {
                    //            new()
                    //            {
                    //                taskCode=task.TaskNum.ToString(),
                    //                taskPriority=0,
                    //                taskDescribe=new TaskDescribeType
                    //                {
                    //                    containerCode=stockInfo.PalletCode,
                    //                    containerType= "CT_KUBOT_STANDARD",
                    //                    fromLocationCode=stockInfo.LocationCode??"",
                    //                    toStationCode="",
                    //                    toLocationCode="1-2",
                    //                    deadline=0,
                    //                    storageTag=""
                    //                }
                    //            }
                    //    }
                    //};
                    //var result = await _eSSApiService.CreateTaskAsync(esstask);
                    _logger.LogInformation("创建任务PalletOutboundTask è¿”回:  " + result);
                    //_logger.LogInformation("创建任务PalletOutboundTask è¿”回:  " + result);
                }
                return content.OK("空托出库成功!");
            }
@@ -314,45 +316,46 @@
                    _outboundOrderDetailService.Repository.UpdateData(outboundOrderDetails);
                }
                _unitOfWorkManage.CommitTran();
                TaskModel esstask = new TaskModel()
                {
                    taskType = "carry",
                    taskGroupCode = "",
                    groupPriority = 0,
                    tasks = new List<TasksType>()
                };
                foreach (var task in tasks)
                {
                    esstask.
                       tasks.Add(new TasksType
                       {
                           taskCode = task.TaskNum.ToString(),
                           taskPriority = 0,
                           taskDescribe = new TaskDescribeType
                           {
                               containerCode = task.PalletCode,
                               containerType = "CT_KUBOT_STANDARD",
                               fromLocationCode = task.SourceAddress ?? "",
                               toStationCode = "",
                               toLocationCode = task.TargetAddress,
                               deadline = 0,
                               storageTag = ""
                           }
                       }
                   );
                }
                var result = await _eSSApiService.CreateTaskAsync(esstask);
                _logger.LogInformation("创建任务PalletOutboundTask è¿”回:  " + result);
                if (result)
                {
                    return WebResponseContent.Instance.OK();
                }
                else
                {
                    return WebResponseContent.Instance.Error("下发机器人任务失败!");
                }
                //TaskModel esstask = new TaskModel()
                //{
                //    taskType = "carry",
                //    taskGroupCode = "",
                //    groupPriority = 0,
                //    tasks = new List<TasksType>()
                //};
                //foreach (var task in tasks)
                //{
                //    esstask.
                //       tasks.Add(new TasksType
                //       {
                //           taskCode = task.TaskNum.ToString(),
                //           taskPriority = 0,
                //           taskDescribe = new TaskDescribeType
                //           {
                //               containerCode = task.PalletCode,
                //               containerType = "CT_KUBOT_STANDARD",
                //               fromLocationCode = task.SourceAddress ?? "",
                //               toStationCode = "",
                //               toLocationCode = task.TargetAddress,
                //               deadline = 0,
                //               storageTag = ""
                //           }
                //       }
                //   );
                //}
                //var result = await _eSSApiService.CreateTaskAsync(esstask);
                //_logger.LogInformation("创建任务PalletOutboundTask è¿”回:  " + result);
                //if (result)
                //{
                //    return WebResponseContent.Instance.OK();
                //}
                //else
                //{
                //    return WebResponseContent.Instance.Error("下发机器人任务失败!");
                //}
            }
            catch (Exception ex)
            {
@@ -776,46 +779,47 @@
                    _outboundOrderDetailService.Repository.UpdateData(outboundOrderDetails);
                }
                _unitOfWorkManage.CommitTran();
                //PushTasksToWCS(tasks);
                TaskModel esstask = new TaskModel()
                {
                    taskType = "carry",
                    taskGroupCode = "",
                    groupPriority = 0,
                    tasks = new List<TasksType>()
                };
                foreach (var task in tasks)
                {
                    esstask.
                       tasks.Add(new TasksType
                       {
                           taskCode = task.TaskNum.ToString(),
                           taskPriority = 0,
                           taskDescribe = new TaskDescribeType
                           {
                               containerCode = task.PalletCode,
                               containerType = "CT_KUBOT_STANDARD",
                               fromLocationCode = task.SourceAddress ?? "",
                               toStationCode = "",
                               toLocationCode = task.TargetAddress,
                               deadline = 0,
                               storageTag = ""
                           }
                       }
                   );
                }
                var result = await _eSSApiService.CreateTaskAsync(esstask);
                _logger.LogInformation("创建任务PalletOutboundTask è¿”回:  " + result);
                if (result)
                {
                    return WebResponseContent.Instance.OK();
                }
                else
                {
                    return WebResponseContent.Instance.Error("下发机器人任务失败!");
                }
                //PushTasksToWCS(tasks);
                //TaskModel esstask = new TaskModel()
                //{
                //    taskType = "carry",
                //    taskGroupCode = "",
                //    groupPriority = 0,
                //    tasks = new List<TasksType>()
                //};
                //foreach (var task in tasks)
                //{
                //    esstask.
                //       tasks.Add(new TasksType
                //       {
                //           taskCode = task.TaskNum.ToString(),
                //           taskPriority = 0,
                //           taskDescribe = new TaskDescribeType
                //           {
                //               containerCode = task.PalletCode,
                //               containerType = "CT_KUBOT_STANDARD",
                //               fromLocationCode = task.SourceAddress ?? "",
                //               toStationCode = "",
                //               toLocationCode = task.TargetAddress,
                //               deadline = 0,
                //               storageTag = ""
                //           }
                //       }
                //   );
                //}
                //var result = await _eSSApiService.CreateTaskAsync(esstask);
                //_logger.LogInformation("创建任务PalletOutboundTask è¿”回:  " + result);
                //if (result)
                //{
                //    return WebResponseContent.Instance.OK();
                //}
                //else
                //{
                //    return WebResponseContent.Instance.Error("下发机器人任务失败!");
                //}
            }
            catch (Exception ex)
@@ -1173,46 +1177,47 @@
                BaseDal.AddData(tasks);
                _locationInfoService.UpdateData(locationInfos);
                _unitOfWorkManage.CommitTran();
                TaskModel esstask = new TaskModel()
                {
                    taskType = "carry",
                    taskGroupCode = "",
                    groupPriority = 0,
                    tasks = new List<TasksType>()
                };
                foreach (var task in tasks)
                {
                    esstask.
                       tasks.Add(new TasksType
                       {
                           taskCode = task.TaskNum.ToString(),
                           taskPriority = 0,
                           taskDescribe = new TaskDescribeType
                           {
                               containerCode = task.PalletCode,
                               containerType = "CT_KUBOT_STANDARD",
                               fromLocationCode = task.SourceAddress ?? "",
                               toStationCode = "",
                               toLocationCode = task.TargetAddress,
                               deadline = 0,
                               storageTag = ""
                           }
                       }
                   );
                }
                var result = await _eSSApiService.CreateTaskAsync(esstask);
                _logger.LogInformation("创建任务PalletOutboundTask è¿”回:  " + result);
                if (result)
                {
                    return WebResponseContent.Instance.OK();
                }
                else
                {
                    return WebResponseContent.Instance.Error("下发机器人任务失败!");
                }
                content.OK();
                //TaskModel esstask = new TaskModel()
                //{
                //    taskType = "carry",
                //    taskGroupCode = "",
                //    groupPriority = 0,
                //    tasks = new List<TasksType>()
                //};
                //foreach (var task in tasks)
                //{
                //    esstask.
                //       tasks.Add(new TasksType
                //       {
                //           taskCode = task.TaskNum.ToString(),
                //           taskPriority = 0,
                //           taskDescribe = new TaskDescribeType
                //           {
                //               containerCode = task.PalletCode,
                //               containerType = "CT_KUBOT_STANDARD",
                //               fromLocationCode = task.SourceAddress ?? "",
                //               toStationCode = "",
                //               toLocationCode = task.TargetAddress,
                //               deadline = 0,
                //               storageTag = ""
                //           }
                //       }
                //   );
                //}
                //var result = await _eSSApiService.CreateTaskAsync(esstask);
                //_logger.LogInformation("创建任务PalletOutboundTask è¿”回:  " + result);
                //if (result)
                //{
                //    return WebResponseContent.Instance.OK();
                //}
                //else
                //{
                //    return WebResponseContent.Instance.Error("下发机器人任务失败!");
                //}
                //content.OK();
            }
            catch (Exception ex)
            {
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_WMSServer/Jobs/AgvTaskJob.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,72 @@
using Quartz;
using SqlSugar;
using WIDESEA_Common.TaskEnum;
using WIDESEA_DTO.Basic;
using WIDESEA_IBasicService;
using WIDESEA_Model.Models;
namespace WIDESEA_WMSServer
{
    [DisallowConcurrentExecution]
    public class AgvTaskJob : IJob
    {
        private readonly ILogger<AgvTaskJob> _logger;
        private readonly ISqlSugarClient _db;
        private readonly IESSApiService _eSSApiService;
        // é€šè¿‡æž„造函数直接注入依赖
        public AgvTaskJob(ILogger<AgvTaskJob> logger, ISqlSugarClient db, IESSApiService eSSApiService)
        {
            _logger = logger;
            _db = db;
            _eSSApiService = eSSApiService;
        }
        public async Task Execute(IJobExecutionContext context)
        {
            try
            {
                var tasks = await _db.Queryable<Dt_Task>()
                    .Where(x => x.TaskStatus == (int)TaskStatusEnum.New)
                    .ToListAsync();
                foreach (var item in tasks)
                {
                    TaskModel esstask = new TaskModel()
                    {
                        taskType = item.TaskType.GetTaskTypeGroup()==TaskTypeGroup.InboundGroup? "putaway": "carry",
                        taskGroupCode = "",
                        groupPriority = 0,
                        tasks = new List<TasksType>
                        {
                                new()
                                {
                                    taskCode=item.TaskNum.ToString(),
                                    taskPriority=0,
                                    taskDescribe = new TaskDescribeType
                                    {
                                        containerCode = item.PalletCode,
                                        containerType = "CT_KUBOT_STANDARD",
                                        fromLocationCode = item.SourceAddress,
                                        toStationCode = "",
                                        toLocationCode = item.TargetAddress,
                                        deadline = 0,
                                    }
                                }
                        }
                    };
                    var result = await _eSSApiService.CreateTaskAsync(esstask);
                    if (result)
                    {
                        item.TaskStatus = (int)TaskStatusEnum.HasSent;
                        await _db.Updateable(item).ExecuteCommandAsync();
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "定时任务执行失败");
            }
        }
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_WMSServer/Jobs/QuartzJobMildd.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@

using Microsoft.AspNetCore.Builder;
using System;
using System.Collections.Generic;
using System.Text;
using WIDESEA.QuartzJob;
using WIDESEA_Core.Helper;
namespace WIDESEA_WMSServer
{
    /// <summary>
    /// Quartz å¯åŠ¨æœåŠ¡
    /// </summary>
    public static class QuartzJobMiddleWare
    {
        public static void UseQuartzJobMildd(this IApplicationBuilder app)
        {
            if (app == null) throw new ArgumentNullException(nameof(app));
            var schedulerCenter = app.ApplicationServices.GetService(typeof(ISchedulerCenter)) as ISchedulerCenter;
            try
            {
                var allQzServices = new List<TasksQz>()
                {
                    new TasksQz()
                    {
                         Id = 1,
                         AssemblyName = "WIDESEA_WMSServer",
                         ClassName = "AgvTaskJob",
                         CreateTime = DateTime.Now,
                         IntervalSecond = 3,
                         IsDeleted = false,
                         IsStart = false,
                         JobGroup = "WIDESEA_WMSServer",
                         Name = "AgvTaskJob",
                         TriggerType = 0
                    },
                };
                foreach (var item in allQzServices)
                {
                    var ResuleModel = schedulerCenter.AddScheduleJobAsync(item).Result;
                    if (ResuleModel.Status)
                    {
                        ConsoleHelper.WriteSuccessLine($"{item.ClassName}启动成功");
                    }
                    else
                    {
                        Console.Out.WriteLine($"QuartzNetJob{item.Name}启动失败!错误信息:{ResuleModel.Message}");
                    }
                }
                schedulerCenter.StartScheduleAsync();
            }
            catch (Exception e)
            {
                throw;
            }
        }
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_WMSServer/Program.cs
@@ -10,11 +10,14 @@
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using Quartz;
using Quartz.Impl;
using Quartz.Spi;
using Serilog;
using System.Net.Security;
using System.Reflection;
using System.Runtime.ConstrainedExecution;
using System.Text;
using WIDESEA.QuartzJob;
using WIDESEA_Core;
using WIDESEA_Core.Authorization;
using WIDESEA_Core.BaseServices;
@@ -24,8 +27,11 @@
using WIDESEA_Core.Helper;
//using WIDESEA_Core.HostedService;
using WIDESEA_Core.Middlewares;
using WIDESEA_DTO.Quartz;
using WIDESEA_WMSServer;
using WIDESEA_WMSServer.Filter;
using WIDESEA_WMSServer.Jobs;
using static Quartz.Logging.OperationName;
var builder = WebApplication.CreateBuilder(args);
@@ -150,13 +156,15 @@
    client.Timeout = TimeSpan.FromSeconds(30);
})  ;
builder.Services.AddSingleton<IJobFactory, JobFactory>();
builder.Services.AddTransient<AgvTaskJob>();//Job使用瞬时依赖注入
builder.Services.AddSingleton<ISchedulerCenter, SchedulerCenterServer>();
 
builder.Services.AddQuartz(q =>
{
    
    var jobKey = new JobKey("ErpJob");
    q.AddJob<ErpJob>(opts => opts.WithIdentity(jobKey));
    // æ·»åŠ è§¦å‘å™¨ - æ¯å¤©10:00, 14:00, 20:00执行
    q.AddTrigger(opts => opts
@@ -171,13 +179,12 @@
        .ForJob(inventoryLockJobKey)
        .WithIdentity("InventoryLockJob-trigger")
        .WithCronSchedule("0 0/10 * * * ?")); // æ¯10分钟执行一次
});
 
builder.Services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
var app = builder.Build();
app.UseQuartzJobMildd();
 
app.UseMiniProfiler();//性能分析器
app.ConfigureApplication();//配置文件