old_flsystem/应用/EncourageUser/TaskJob.cs

296 lines
12 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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}");
}
}
}
}