old_flsystem/应用/EncourageUser/TaskJob.cs

296 lines
12 KiB
C#
Raw Permalink Normal View History

2022-09-20 03:10:29 +00:00
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
{
/// <summary>
/// 运行中的任务
/// </summary>
public static Dictionary<long, CancellationTokenSource> JobDic = new Dictionary<long, CancellationTokenSource>();
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<fl_qunfa_task>("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<fl_qunfa_user>().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<fl_plugin_encourage_user_messs>().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<fl_qunfa_user>().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}");
}
}
/// <summary>
/// 执行发送任务
/// </summary>
/// <param name="users">发送用户集合</param>
/// <param name="tCancel">取消任务</param>
private static void SendTask(fl_qunfa_task qunTask, List<fl_qunfa_user> users, fl_plugin_encourage_user_messs taskMess, CancellationTokenSource tCancel)
{
fl_qunfa_task quntask = qunTask;
List<fl_qunfa_user> 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();
}
/// <summary>
/// 是否在发送时间段
/// </summary>
/// <param name="job"></param>
/// <returns></returns>
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);
}
/// <summary>
/// 今日发送人数是否达标,还可发送返回true
/// </summary>
/// <returns></returns>
private static bool CheckSendNum(long taskid, int dayCeilingNum)
{
var today = HttpExtend.GetTimeStamp(DateTime.Today);
var db = ApiClient.GetSession();
var daySendNum = db.Queryable<fl_qunfa_user>().Count(f => f.taskid == taskid && f.issend && today <= f.sendtime);
return dayCeilingNum > daySendNum;//今天发送的数量比限定的少返回true
}
/// <summary>
/// 取消任务
/// </summary>
/// <param name="id"></param>
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}");
}
}
}
}