using Api.Framework; using Api.Framework.Model; using Api.Framework.SDK; using Api.Framework.Tools; using Chat.Framework; using Chat.Framework.WXSdk.Implement; using CsharpHttpHelper; using EncourageUser.Entitys; using Newtonsoft.Json; using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace EncourageUser { public class TaskJob : TimerTask { /// /// 运行中的任务 /// public static Dictionary JobDic = new Dictionary(); public static bool isrun { get; set; } = false; public override void Run(object state, bool timedOut) { if (isrun) return; try { isrun = true; var session = ApiClient.GetSession(); var jobs = session.Find("select * from fl_qunfa_task where execType = @execType", new { execType = ExecType.未执行完毕 }); if (jobs == null || jobs.Count == 0) return; foreach (var job in jobs) { //if (JobDic.ContainsKey(job.id)) // continue; //更新任务发送用户数量 var qfUser = session.Queryable().Where(f => f.taskid == job.id).ToList(); if (qfUser.Count == 0) continue; else { var unSendNum = qfUser.Count(f => !f.issend); if (unSendNum == 0) { job.execType = ExecType.执行完毕; if (JobDic.ContainsKey(job.id)) { Abort(job.id); continue; } } else if (!CheckSendNum(job.id, job.totalSentCount) && IsSendTime(job) && job.endTime.Date == DateTime.Today)// job.execType = ExecType.执行完毕; else if (job.endTime < DateTime.Now)//已经超出任务结束日期 job.execType = ExecType.执行失效; else job.execType = ExecType.未执行完毕; job.unsendnum = unSendNum; job.allsendnum = qfUser.Count; job.sendnum = qfUser.Count - unSendNum; session.Updateable(job).ExecuteCommand(); if (job.execType != ExecType.未执行完毕) continue; } if (!JobDic.ContainsKey(job.id) && IsSendTime(job) && CheckSendNum(job.id, job.totalSentCount)) { //回复语不存在直接不执行 var mess = session.Queryable().First(f => f.id == job.messid); if (mess == null) { job.execType = ExecType.执行失效; session.Updateable(job).ExecuteCommand(); continue; } ExecTask(job, mess); } } } catch (Exception) { EventClient.OnEvent(this, $"群发工具异常 -> 检测时间:{DateTime.Now.ToString("HH:mm:ss")}"); } finally { isrun = false; } } private static void ExecTask(fl_qunfa_task job, fl_plugin_encourage_user_messs taskMess) { var task = job; try { var taskCancel = new CancellationTokenSource(); fl_plugin_encourage_user_messs taskmess = taskMess; Task.Factory.StartNew(() => { try { var db = ApiClient.GetSession(); var mList = db.Queryable().Where(f => f.taskid == job.id); //未发送的用户集合 var unSendMList = mList.Where(f => !f.issend).ToList(); //机器人分组 var rGroup = unSendMList.GroupBy(f => f.robotname).Select(f => f.Key).ToList(); foreach (var rname in rGroup) { if (taskCancel.IsCancellationRequested) return; var sendMList = unSendMList.Where(f => f.robotname == rname).ToList(); if (sendMList.Count != 0) { JobDic[task.id] = taskCancel; EventClient.OnEvent("", $"成功下达群发任务:{task.id}"); SendTask(task, sendMList, taskmess, taskCancel); } } } catch (Exception ex) { EventClient.OnEvent("", $"处理群发任务{task.id}异常:{ex.Message} - {ex.StackTrace}"); } }, taskCancel.Token); } catch (Exception ex) { EventClient.OnEvent("", $"处理群发任务{task.id}异常2:{ex.Message} - {ex.StackTrace}"); } } /// /// 执行发送任务 /// /// 发送用户集合 /// 取消任务 private static void SendTask(fl_qunfa_task qunTask, List users, fl_plugin_encourage_user_messs taskMess, CancellationTokenSource tCancel) { fl_qunfa_task quntask = qunTask; List sendUsers = users; CancellationTokenSource taskCancel = tCancel; fl_plugin_encourage_user_messs taskmess = taskMess; Task.Factory.StartNew(() => { try { var num = 1; foreach (var user in sendUsers) { //判断是否在可发送时间段 或者 今日发送数量已上限 if (!IsSendTime(quntask) || !CheckSendNum(quntask.id, quntask.totalSentCount) || taskCancel.IsCancellationRequested) return; var flag = false;//判断是否执行发送,执行了休眠才休眠 if (user.chattype == ChatType.企业微信 || user.chattype == ChatType.微信) { var robot = ChatClient.WXClient.FirstOrDefault(f => f.Key == user.robotname).Value; if (robot == null || robot.Status != Chat.Framework.WXSdk.WxStatus.在线) continue; flag = true; robot.SendMessage(user.username, taskmess.mess); UpdUser(user); } else if (user.chattype == ChatType.QQ) { var robot = ChatClient.QQClients.FirstOrDefault(f => f.Key == user.robotname).Value; if (robot == null || !robot.IsLogin) continue; flag = true; robot.SendMessage(uint.Parse(user.username), taskmess.mess); UpdUser(user); } if (flag) { EventClient.OnEvent("发送任务", $"执行群发任务:{quntask.id},用户:{user.username},{DateTime.Now}"); var second = quntask.interval; if (quntask.restSendCount <= num) { second = quntask.restInterval; num = 0; } //发送休眠时间 Thread.Sleep(second * 1000 + new Random(Guid.NewGuid().GetHashCode()).Next(100, 1000)); num++; } } } catch (Exception ex) { EventClient.OnEvent("", $"执行群发任务中异常:{ex.Message} - {ex.StackTrace}"); } finally { Abort(quntask.id); } }, taskCancel.Token); } private static void UpdUser(fl_qunfa_user user) { user.sendtime = HttpExtend.GetTimeStamp(DateTime.Now); user.issend = true; var db = ApiClient.GetSession(); db.Updateable(user).ExecuteCommand(); } /// /// 是否在发送时间段 /// /// /// private static bool IsSendTime(fl_qunfa_task job) { var now = DateTime.Now; var date = now.ToString("yyyy-MM-dd"); var startTime1 = DateTime.Parse($"{date} {job.startTime.Hour}:{job.startTime.Minute}:{job.startTime.Second}"); var endTime1 = DateTime.Parse($"{date} {job.endTime.Hour}:{job.endTime.Minute}:{job.endTime.Second}"); var startTime = DateTime.Parse($"{job.startTime}"); var endTime = DateTime.Parse($"{job.endTime}"); //if (startTime <= now && now <= endTime && startTime1 <= now && now <= endTime1 && !JobDic.ContainsKey(job.id)) return (startTime <= now && now <= endTime && startTime1 <= now && now <= endTime1); } /// /// 今日发送人数是否达标,还可发送返回true /// /// private static bool CheckSendNum(long taskid, int dayCeilingNum) { var today = HttpExtend.GetTimeStamp(DateTime.Today); var db = ApiClient.GetSession(); var daySendNum = db.Queryable().Count(f => f.taskid == taskid && f.issend && today <= f.sendtime); return dayCeilingNum > daySendNum;//今天发送的数量比限定的少返回true } /// /// 取消任务 /// /// public static void Abort(long id) { try { if (JobDic == null || JobDic.Count == 0) return; if (!JobDic.ContainsKey(id)) return; JobDic[id].Cancel(); JobDic.Remove(id); EventClient.OnEvent("取消任务", $"取消群发任务:{id}"); } catch (Exception ex) { EventClient.OnEvent("取消任务", $"取消群发任务异常:{ex.Message} - {ex.StackTrace}"); } } public static void AbortAll() { try { if (JobDic == null || JobDic.Count == 0) return; foreach (var taskCancel in JobDic.Values) { taskCancel.Cancel(); } JobDic.Clear(); EventClient.OnEvent("取消任务", $"取消所有群发任务"); } catch (Exception ex) { EventClient.OnEvent("取消任务", $"取消所有群发任务异常:{ex.Message} - {ex.StackTrace}"); } } } }