调度服务区分停止和暂停功能优化

页面提交的的时间和本地UTC时差问题优化
Helper优化
加入编码集方便调用特殊编码
This commit is contained in:
hudingwen 2021-01-11 14:07:30 +08:00
parent 30d10b8053
commit f3a63f031e
36 changed files with 2088 additions and 164 deletions

View File

@ -45,6 +45,8 @@
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.9.10" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="5.0.0" />
</ItemGroup>
<ItemGroup>

View File

@ -722,6 +722,7 @@
执行间隔时间, 秒为单位
</summary>
</member>
<!-- Badly formed XML comment ignored for member "P:Blog.Core.Model.Models.TasksQz.CycleRunTimes" -->
<member name="P:Blog.Core.Model.Models.TasksQz.IsStart">
<summary>
是否启动
@ -737,6 +738,11 @@
创建时间
</summary>
</member>
<member name="P:Blog.Core.Model.Models.TasksQz.Triggers">
<summary>
任务内存中的状态
</summary>
</member>
<member name="T:Blog.Core.Model.Models.Topic">
<summary>
Tibug 类别
@ -1381,6 +1387,394 @@
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.MERCHANTID">
<summary>
商户号
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.POSID">
<summary>
柜台号
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.BRANCHID">
<summary>
分行号
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.GROUPMCH">
<summary>
集团商户信息
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.TXCODE">
<summary>
交易码
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.MERFLAG">
<summary>
商户类型
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.TERMNO1">
<summary>
终端编号 1
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.TERMNO2">
<summary>
终端编号 2
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.ORDERID">
<summary>
订单号
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.QRCODE">
<summary>
码信息(一维码、二维码)
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.AMOUNT">
<summary>
订单金额,单位:元
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.PROINFO">
<summary>
商品名称
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.REMARK1">
<summary>
备注 1
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.REMARK2">
<summary>
备注 2
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.FZINFO1">
<summary>
分账信息一
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.FZINFO2">
<summary>
分账信息二
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.SUB_APPID">
<summary>
子商户公众账号 ID
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.RETURN_FIELD">
<summary>
返回信息位图
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.USERPARAM">
<summary>
实名支付
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.detail">
<summary>
商品详情
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.goods_tag">
<summary>
订单优惠标记
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.pubKey">
<summary>
公钥
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.url">
<summary>
请求地址
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayModel.deleteEmpty">
<summary>
是否删除空值
</summary>
</member>
<member name="T:Blog.Core.Model.ViewModels.PayNeedModel">
<summary>
退款参数
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayNeedModel.ORDERID">
<summary>
订单ID
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayNeedModel.PROINFO">
<summary>
商品名称
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayNeedModel.AMOUNT">
<summary>
支付金额(小数点最多两位)
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayNeedModel.QRCODE">
<summary>
二维码/条码信息
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayNeedModel.REMARK1">
<summary>
备注信息1
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayNeedModel.REMARK2">
<summary>
备注信息2
</summary>
</member>
<member name="T:Blog.Core.Model.ViewModels.PayRefundNeedModel">
<summary>
订单参数
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundNeedModel.ORDER">
<summary>
订单号
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundNeedModel.MONEY">
<summary>
退款金额
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundNeedModel.REFUND_CODE">
<summary>
退款流水号(可选)
</summary>
</member>
<member name="T:Blog.Core.Model.ViewModels.PayRefundReturnModel">
<summary>
退款返回消息
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnModel.REQUEST_SN">
<summary>
序列号
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnModel.CUST_ID">
<summary>
商户号
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnModel.TX_CODE">
<summary>
交易码
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnModel.RETURN_CODE">
<summary>
返回码
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnModel.RETURN_MSG">
<summary>
返回码说明
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnModel.LANGUAGE">
<summary>
语言
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnModel.TX_INFO">
<summary>
订单信息
</summary>
</member>
<member name="T:Blog.Core.Model.ViewModels.PayRefundReturnOrderInfoModel">
<summary>
订单信息
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnOrderInfoModel.ORDER_NUM">
<summary>
订单号
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnOrderInfoModel.PAY_AMOUNT">
<summary>
支付金额
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnOrderInfoModel.AMOUNT">
<summary>
退款金额
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnOrderInfoModel.REM1">
<summary>
备注1
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnOrderInfoModel.REM2">
<summary>
备注2
</summary>
</member>
<member name="T:Blog.Core.Model.ViewModels.PayRefundReturnResultModel">
<summary>
退款返回结果消息
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnResultModel.ORDER_NUM">
<summary>
订单号
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnResultModel.PAY_AMOUNT">
<summary>
支付金额
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnResultModel.AMOUNT">
<summary>
退款金额
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnResultModel.REQUEST_SN">
<summary>
序列号
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnResultModel.CUST_ID">
<summary>
商户号
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnResultModel.TX_CODE">
<summary>
交易码
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnResultModel.RETURN_CODE">
<summary>
返回码
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnResultModel.RETURN_MSG">
<summary>
返回码说明
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayRefundReturnResultModel.LANGUAGE">
<summary>
语言
</summary>
</member>
<member name="T:Blog.Core.Model.ViewModels.PayResultModel">
<summary>
支付结果dto
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayResultModel.RESULT">
<summary>
支付结果
Y成功
N失败
U不确定
Q待轮询
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayResultModel.ORDERID">
<summary>
订单ID
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayResultModel.AMOUNT">
<summary>
支付金额
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayResultModel.QRCODETYPE">
<summary>
二维码类型
1龙支付
2微信
3支付宝
4银联
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayResultModel.WAITTIME">
<summary>
等待时间-轮询等待时间
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayResultModel.TRACEID">
<summary>
全局事件跟踪号-建行交易流水号
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayResultModel.ERRCODE">
<summary>
错误码
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayResultModel.ERRMSG">
<summary>
错误信息
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayResultModel.SIGN">
<summary>
验证签名-防止伪造攻击
</summary>
</member>
<member name="T:Blog.Core.Model.ViewModels.PayReturnResultModel">
<summary>
返回支付结果
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayReturnResultModel.ORDERID">
<summary>
发起的订单ID
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayReturnResultModel.AMOUNT">
<summary>
返回支付的金额
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayReturnResultModel.QRCODETYPE">
<summary>
返回支付的类型 1龙支付 2微信 3支付宝 4银联
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayReturnResultModel.TRACEID">
<summary>
返回建行的流水号
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayReturnResultModel.ERRCODE">
<summary>
错误代码
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.PayReturnResultModel.ERRMSG">
<summary>
错误信息
</summary>
</member>
<member name="T:Blog.Core.Model.ViewModels.ServerViewModel">
<summary>
服务器VM
@ -1426,6 +1820,46 @@
菜单展示model
</summary>
</member>
<member name="T:Blog.Core.Model.ViewModels.TaskInfoDto">
<summary>
调度任务触发器信息实体
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.TaskInfoDto.jobId">
<summary>
任务ID
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.TaskInfoDto.jobName">
<summary>
任务名称
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.TaskInfoDto.jobGroup">
<summary>
任务分组
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.TaskInfoDto.triggerId">
<summary>
触发器ID
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.TaskInfoDto.triggerName">
<summary>
触发器名称
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.TaskInfoDto.triggerGroup">
<summary>
触发器分组
</summary>
</member>
<member name="P:Blog.Core.Model.ViewModels.TaskInfoDto.triggerStatus">
<summary>
触发器状态
</summary>
</member>
<member name="T:Blog.Core.Model.ViewModels.TestRestSharpGetDto">
<summary>
用来测试 RestSharp Get 请求

View File

@ -263,6 +263,39 @@
</summary>
<returns></returns>
</member>
<member name="T:Blog.Core.Controllers.PayController">
<summary>
建行聚合支付类
</summary>
</member>
<member name="M:Blog.Core.Controllers.PayController.#ctor(Microsoft.Extensions.Logging.ILogger{Blog.Core.Controllers.PayController},Blog.Core.IServices.IPayServices)">
<summary>
构造函数
</summary>
<param name="logger"></param>
<param name="payServices"></param>
</member>
<member name="M:Blog.Core.Controllers.PayController.Pay(Blog.Core.Model.ViewModels.PayNeedModel)">
<summary>
支付
</summary>
<param name="payModel"></param>
<returns></returns>
</member>
<member name="M:Blog.Core.Controllers.PayController.PayCheck(Blog.Core.Model.ViewModels.PayNeedModel)">
<summary>
支付结果查询-轮询
</summary>
<param name="payModel"></param>
<returns></returns>
</member>
<member name="M:Blog.Core.Controllers.PayController.PayRefund(Blog.Core.Model.ViewModels.PayRefundNeedModel)">
<summary>
退款
</summary>
<param name="payModel"></param>
<returns></returns>
</member>
<member name="T:Blog.Core.Controllers.PermissionController">
<summary>
菜单管理
@ -402,6 +435,13 @@
<param name="tasksQz"></param>
<returns></returns>
</member>
<member name="M:Blog.Core.Controllers.TasksQzController.Delete(System.Int32)">
<summary>
删除一个任务
</summary>
<param name="jobId"></param>
<returns></returns>
</member>
<member name="M:Blog.Core.Controllers.TasksQzController.StartJob(System.Int32)">
<summary>
启动计划任务
@ -416,6 +456,20 @@
<param name="jobId"></param>
<returns></returns>
</member>
<member name="M:Blog.Core.Controllers.TasksQzController.PauseJob(System.Int32)">
<summary>
暂停一个计划任务
</summary>
<param name="jobId"></param>
<returns></returns>
</member>
<member name="M:Blog.Core.Controllers.TasksQzController.ResumeJob(System.Int32)">
<summary>
恢复一个计划任务
</summary>
<param name="jobId"></param>
<returns></returns>
</member>
<member name="M:Blog.Core.Controllers.TasksQzController.ReCovery(System.Int32)">
<summary>
重启一个计划任务

View File

@ -0,0 +1,75 @@
using System.Threading.Tasks;
using Blog.Core.IServices;
using Blog.Core.Model;
using Blog.Core.Model.ViewModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace Blog.Core.Controllers
{
/// <summary>
/// 建行聚合支付类
/// </summary>
[Produces("application/json")]
[Route("api/Pay")]
public class PayController : Controller
{
private readonly ILogger<PayController> _logger;
private readonly IPayServices _payServices;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="logger"></param>
/// <param name="payServices"></param>
public PayController(ILogger<PayController> logger, IPayServices payServices)
{
_logger = logger;
_payServices = payServices;
}
/// <summary>
/// 支付
/// </summary>
/// <param name="payModel"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpGet]
[HttpPost]
[Route("Pay")]
public async Task<MessageModel<PayReturnResultModel>> Pay(PayNeedModel payModel)
{
return await _payServices.Pay(payModel);
}
/// <summary>
/// 支付结果查询-轮询
/// </summary>
/// <param name="payModel"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpGet]
[HttpPost]
[Route("PayCheck")]
public async Task<MessageModel<PayReturnResultModel>> PayCheck(PayNeedModel payModel)
{
return await _payServices.PayCheck(payModel, 1);
}
/// <summary>
/// 退款
/// </summary>
/// <param name="payModel"></param>
/// <returns></returns>
[AllowAnonymous]
[HttpGet]
[HttpPost]
[Route("PayRefund")]
public async Task<MessageModel<PayRefundReturnResultModel>> PayRefund(PayRefundNeedModel payModel)
{
return await _payServices.PayRefund(payModel);
}
}
}

View File

@ -43,14 +43,19 @@ namespace Blog.Core.Controllers
Expression<Func<TasksQz, bool>> whereExpression = a => a.IsDeleted != true && (a.Name != null && a.Name.Contains(key));
var data = await _tasksQzServices.QueryPage(whereExpression, page, intPageSize, " Id desc ");
if (data.dataCount > 0)
{
foreach (var item in data.data)
{
item.Triggers = await _schedulerCenter.GetTaskStaus(item);
}
}
return new MessageModel<PageModel<TasksQz>>()
{
msg = "获取成功",
success = data.dataCount >= 0,
response = data
};
}
/// <summary>
@ -67,11 +72,29 @@ namespace Blog.Core.Controllers
data.success = id > 0;
if (data.success)
{
tasksQz.Id = id;
data.response = id.ObjToString();
data.msg = "添加成功";
data.msg = "更新成功";
if (tasksQz.IsStart)
{
//如果是启动自动
var ResuleModel = await _schedulerCenter.AddScheduleJobAsync(tasksQz);
data.success = ResuleModel.success;
if (ResuleModel.success)
{
data.msg = $"{data.msg}=>启动成功=>{ResuleModel.msg}";
}
else
{
data.msg = $"{data.msg}=>启动失败=>{ResuleModel.msg}";
}
}
}
return data;
else
{
data.msg = "更新失败";
}
return data;
}
@ -91,12 +114,59 @@ namespace Blog.Core.Controllers
{
data.msg = "更新成功";
data.response = tasksQz?.Id.ObjToString();
if (tasksQz.IsStart)
{
var ResuleModelStop = await _schedulerCenter.StopScheduleJobAsync(tasksQz);
data.msg = $"{data.msg}=>停止:{ResuleModelStop.msg}";
var ResuleModelStar = await _schedulerCenter.AddScheduleJobAsync(tasksQz);
data.msg = $"{data.msg}=>启动:{ResuleModelStar.msg}";
}
else
{
var ResuleModelStop = await _schedulerCenter.StopScheduleJobAsync(tasksQz);
data.msg = $"{data.msg}=>停止:{ResuleModelStop.msg}";
}
}
else
{
data.msg = "更新失败";
}
}
return data;
}
/// <summary>
/// 删除一个任务
/// </summary>
/// <param name="jobId"></param>
/// <returns></returns>
[HttpDelete]
public async Task<MessageModel<string>> Delete(int jobId)
{
var data = new MessageModel<string>();
var model = await _tasksQzServices.QueryById(jobId);
if (model != null)
{
data.success = await _tasksQzServices.Delete(model);
data.response = jobId.ObjToString();
if (data.success)
{
data.msg = "更新成功";
var ResuleModel = await _schedulerCenter.StopScheduleJobAsync(model);
data.msg = $"{data.msg}=>任务状态=>{ResuleModel.msg}";
}
else
{
data.msg = "更新失败";
}
}
else
{
data.msg = "任务不存在";
}
return data;
}
/// <summary>
/// 启动计划任务
/// </summary>
@ -110,20 +180,35 @@ namespace Blog.Core.Controllers
var model = await _tasksQzServices.QueryById(jobId);
if (model != null)
{
var ResuleModel = await _schedulerCenter.AddScheduleJobAsync(model);
if (ResuleModel.success)
{
model.IsStart = true;
data.success = await _tasksQzServices.Update(model);
}
model.IsStart = true;
data.success = await _tasksQzServices.Update(model);
data.response = jobId.ObjToString();
if (data.success)
{
data.msg = "启动成功";
data.response = jobId.ObjToString();
data.msg = "更新成功";
var ResuleModel = await _schedulerCenter.AddScheduleJobAsync(model);
if (ResuleModel.success)
{
data.msg = $"{data.msg}=>启动成功=>{ResuleModel.msg}";
}
else
{
data.msg = $"{data.msg}=>启动失败=>{ResuleModel.msg}";
}
}
else
{
data.msg = "更新失败";
}
}
else
{
data.msg = "任务不存在";
}
return data;
}
/// <summary>
/// 停止一个计划任务
@ -138,20 +223,110 @@ namespace Blog.Core.Controllers
var model = await _tasksQzServices.QueryById(jobId);
if (model != null)
{
var ResuleModel = await _schedulerCenter.StopScheduleJobAsync(model);
if (ResuleModel.success)
{
model.IsStart = false;
data.success = await _tasksQzServices.Update(model);
}
model.IsStart = false;
data.success = await _tasksQzServices.Update(model);
data.response = jobId.ObjToString();
if (data.success)
{
data.msg = "暂停成功";
data.response = jobId.ObjToString();
data.msg = "更新成功";
var ResuleModel = await _schedulerCenter.StopScheduleJobAsync(model);
if (ResuleModel.success)
{
data.msg = $"{data.msg}=>停止成功=>{ResuleModel.msg}";
}
else
{
data.msg = $"{data.msg}=>停止失败=>{ResuleModel.msg}";
}
}
else
{
data.msg = "更新失败";
}
}
else
{
data.msg = "任务不存在";
}
return data;
}
/// <summary>
/// 暂停一个计划任务
/// </summary>
/// <param name="jobId"></param>
/// <returns></returns>
[HttpGet]
public async Task<MessageModel<string>> PauseJob(int jobId)
{
var data = new MessageModel<string>();
var model = await _tasksQzServices.QueryById(jobId);
if (model != null)
{
data.success = await _tasksQzServices.Update(model);
data.response = jobId.ObjToString();
if (data.success)
{
data.msg = "更新成功";
var ResuleModel = await _schedulerCenter.PauseJob(model);
if (ResuleModel.success)
{
data.msg = $"{data.msg}=>暂停成功=>{ResuleModel.msg}";
}
else
{
data.msg = $"{data.msg}=>暂停失败=>{ResuleModel.msg}";
}
}
else
{
data.msg = "更新失败";
}
}
else
{
data.msg = "任务不存在";
}
return data;
}
/// <summary>
/// 恢复一个计划任务
/// </summary>
/// <param name="jobId"></param>
/// <returns></returns>
[HttpGet]
public async Task<MessageModel<string>> ResumeJob(int jobId)
{
var data = new MessageModel<string>();
var model = await _tasksQzServices.QueryById(jobId);
if (model != null)
{
model.IsStart = true;
data.success = await _tasksQzServices.Update(model);
data.response = jobId.ObjToString();
if (data.success)
{
data.msg = "更新成功";
var ResuleModel = await _schedulerCenter.ResumeJob(model);
if (ResuleModel.success)
{
data.msg = $"{data.msg}=>恢复成功=>{ResuleModel.msg}";
}
else
{
data.msg = $"{data.msg}=>恢复失败=>{ResuleModel.msg}";
}
}
else
{
data.msg = "更新失败";
}
}
else
{
data.msg = "任务不存在";
}
return data;
}
/// <summary>
/// 重启一个计划任务
@ -162,24 +337,40 @@ namespace Blog.Core.Controllers
public async Task<MessageModel<string>> ReCovery(int jobId)
{
var data = new MessageModel<string>();
var model = await _tasksQzServices.QueryById(jobId);
if (model != null)
{
var ResuleModel = await _schedulerCenter.ResumeJob(model);
if (ResuleModel.success)
{
model.IsStart = true;
data.success = await _tasksQzServices.Update(model);
}
model.IsStart = true;
data.success = await _tasksQzServices.Update(model);
data.response = jobId.ObjToString();
if (data.success)
{
data.msg = "重启成功";
data.response = jobId.ObjToString();
data.msg = "更新成功";
var ResuleModelStop = await _schedulerCenter.StopScheduleJobAsync(model);
var ResuleModelStar = await _schedulerCenter.AddScheduleJobAsync(model);
if (ResuleModelStar.success)
{
data.msg = $"{data.msg}=>停止:{ResuleModelStop.msg}=>启动:{ResuleModelStar.msg}";
data.response = jobId.ObjToString();
}
else
{
data.msg = $"{data.msg}=>停止:{ResuleModelStop.msg}=>启动:{ResuleModelStar.msg}";
data.response = jobId.ObjToString();
}
}
else
{
data.msg = "更新失败";
}
}
else
{
data.msg = "任务不存在";
}
return data;
}
}
}

View File

@ -4,6 +4,8 @@
<!-- 按日期切分日志文件,并将日期作为日志文件的名字 -->
<!--Error-->
<appender name="ErrorLog" type="log4net.Appender.RollingFileAppender">
<!--不加utf-8编码格式中文字符将显示成乱码-->
<param name="Encoding" value="utf-8" />
<file value="Log/"/>
<appendToFile value="true" />
<rollingStyle value="Date" />
@ -28,6 +30,8 @@
<!--Info-->
<appender name="InfoLog" type="log4net.Appender.RollingFileAppender">
<!--不加utf-8编码格式中文字符将显示成乱码-->
<param name="Encoding" value="utf-8" />
<!--定义文件存放位置-->
<file value="Log/"/>
<appendToFile value="true" />

View File

@ -19,6 +19,7 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.IdentityModel.Tokens.Jwt;
using System.Reflection;
using System.Text;
namespace Blog.Core
{
@ -111,9 +112,13 @@ namespace Blog.Core
//options.SerializerSettings.DateFormatString = "yyyy-MM-dd";
//忽略Model中为null的属性
//options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
//设置本地时间而非UTC时间
options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
});
_services = services;
//支持编码大全 例如:支持 System.Text.Encoding.GetEncoding("GB2312") System.Text.Encoding.GetEncoding("GB18030")
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
}
// 注意在Program.CreateHostBuilder添加Autofac服务工厂

View File

@ -1,6 +1,7 @@
{
"Logging": {
"LogLevel": {
"Default": "Information", //Defaultlog4net
"Blog.Core.AuthHelper.ApiResponseHandler": "Error"
},
"IncludeScopes": false,
@ -140,10 +141,10 @@
"AppConfigAlert": {
"Enabled": true
},
"ApiName": "Blog.Core",
"ApiName": "PayApi",
"IdentityServer4": {
"Enabled": false, // false使jwttrue使Ids4
"AuthorizationUrl": "https://ids.neters.club", //
"AuthorizationUrl": "http://localhost:5004", //
"ApiName": "blog.core.api" //
},
"RedisMq": {
@ -213,5 +214,14 @@
"ServicePort": "8081",
"ServiceHealthCheck": "/healthcheck",
"ConsulAddress": "http://localhost:8500"
},
"PayInfo": { //
"MERCHANTID": "", //
"POSID": "", //
"BRANCHID": "", //
"pubKey": "", //
"USER_ID": "", //
"PASSWORD": "", //
"OutAddress": "http://127.0.0.1:12345" //
}
}

View File

@ -9,6 +9,9 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<!--极速模式-->
<meta name="renderer" content="webkit" />
<meta name="force-rendering" content="webkit" />
<title>%(DocumentTitle)</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700" rel="stylesheet">
@ -78,8 +81,9 @@
</svg>
<div id="swagger-ui"></div>
<div id="footer" style="text-align: center;margin-bottom: 10px;">
Copyright © 2018-2020 老张的哲学
<br><span id="poweredby">Powered by .NET 5.0.0 on Docker & CentOS 7.6</span>
Copyright © 2018-2020 爱玩云
<br><span id="poweredby">Powered by .NET 5.0.0 Developed by 繁星</span>
</div>
<!-- Workaround for https://github.com/swagger-api/swagger-editor/issues/1371 -->
<script>
@ -113,7 +117,7 @@
$(".link img").attr("src", "./logo/favicon-32x32.png");
$('#swagger-ui').after("<div class='qqgroup'><img src='https://img.neters.club/doc/wechatgongzhonghao.png' alt='QQ二维码' style='width: 150px;'><div style=\"color: #4990e2;\"><a href=\"../allservices\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"link\">1、查看所有依赖注册的服务</a></div></div><div style='clear: both;'></div>");
$('#swagger-ui').after("<div class='qqgroup'><img src='QQGroup.png' alt='QQ二维码' style='width: 150px;'><div style=\"color: #4990e2;\"><a href=\"../allservices\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"link\">1、查看所有依赖注册的服务</a></div></div><div style='clear: both;'></div>");
}

View File

@ -11,6 +11,7 @@
"BeginTime": "\/Date(1546272000000+0800)\/",
"EndTime": "\/Date(1640966400000+0800)\/",
"IntervalSecond": 0,
"CycleRunTimes": 0,
"IsStart": true,
"JobParams": 1,
"IsDeleted": false,

Can't render this file because it contains an unexpected character in line 3 and column 5.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

@ -1,14 +1,14 @@
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Blog.Core.Common.Helper
{
public class GetNetData
{
public static string Get(string serviceAddress)
{
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceAddress);
request.Method = "GET";
request.ContentType = "text/html;charset=UTF-8";
@ -17,23 +17,36 @@ namespace Blog.Core.Common.Helper
StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8);
string retString = myStreamReader.ReadToEnd();
myStreamReader.Close();
myResponseStream.Close();
myResponseStream.Close();
return retString;
}
public static async Task<string> GetAsync(string serviceAddress)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceAddress);
request.Method = "GET";
request.ContentType = "text/html;charset=UTF-8";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream myResponseStream = response.GetResponseStream();
StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.UTF8);
string retString = await myStreamReader.ReadToEndAsync();
myStreamReader.Close();
myResponseStream.Close();
return retString;
}
public static string Post(string serviceAddress)
public static string Post(string serviceAddress, string strContent = null)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceAddress);
request.Method = "POST";
request.ContentType = "application/json";
string strContent = @"{ ""mmmm"": ""89e"",""nnnnnn"": ""0101943"",""kkkkkkk"": ""e8sodijf9""}";
using (StreamWriter dataStream = new StreamWriter(request.GetRequestStream()))
//判断有无POST内容
if (!string.IsNullOrWhiteSpace(strContent))
{
dataStream.Write(strContent);
dataStream.Close();
using (StreamWriter dataStream = new StreamWriter(request.GetRequestStream()))
{
dataStream.Write(strContent);
dataStream.Close();
}
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string encoding = response.ContentEncoding;
@ -43,13 +56,32 @@ namespace Blog.Core.Common.Helper
}
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding));
string retString = reader.ReadToEnd();
return retString;
}
//解析josn
//JObject jo = JObject.Parse(retString);
//Response.Write(jo["message"]["mmmm"].ToString());
public static async Task<string> PostAsync(string serviceAddress, string strContent = null)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceAddress);
request.Method = "POST";
request.ContentType = "application/json";
//判断有无POST内容
if (!string.IsNullOrWhiteSpace(strContent))
{
using (StreamWriter dataStream = new StreamWriter(request.GetRequestStream()))
{
dataStream.Write(strContent);
dataStream.Close();
}
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string encoding = response.ContentEncoding;
if (encoding == null || encoding.Length < 1)
{
encoding = "UTF-8"; //默认编码
}
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding));
string retString = await reader.ReadToEndAsync();
return retString;
}
}

View File

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace Blog.Core.Common.Helper
{
@ -39,5 +41,52 @@ namespace Blog.Core.Common.Helper
return dataArray.ToList();
}
/// <summary>
/// 根据字段拼接get参数
/// </summary>
/// <param name="dic"></param>
/// <returns></returns>
public static string GetPars(Dictionary<string, string> dic)
{
StringBuilder sb = new StringBuilder();
string urlPars = null;
bool isEnter = false;
foreach (var item in dic)
{
sb.Append($"{(isEnter ? "&" : "")}{item.Key}={item.Value}");
isEnter = true;
}
urlPars = sb.ToString();
return urlPars;
}
/// <summary>
/// 获取一个GUID
/// </summary>
/// <param name="format">格式-默认为N</param>
/// <returns></returns>
public static string GetGUID(string format="N") {
return Guid.NewGuid().ToString(format);
}
/// <summary>
/// 根据GUID获取19位的唯一数字序列
/// </summary>
/// <returns></returns>
public static long GetGuidToLongID()
{
byte[] buffer = Guid.NewGuid().ToByteArray();
return BitConverter.ToInt64(buffer, 0);
}
/// <summary>
/// 获取字符串最后X行
/// </summary>
/// <param name="resourceStr"></param>
/// <param name="length"></param>
/// <returns></returns>
public static string GetCusLine(string resourceStr,int length) {
string[] arrStr = resourceStr.Split("\r\n");
return string.Join("", (from q in arrStr select q).Skip(arrStr.Length - length+1).Take(length).ToArray());
}
}
}

View File

@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
namespace Blog.Core.Common.Helper
{
public class XmlHelper
{
/// <summary>
/// 转换对象为JSON格式数据
/// </summary>
/// <typeparam name="T">类</typeparam>
/// <param name="obj">对象</param>
/// <returns>字符格式的JSON数据</returns>
public static string GetXML<T>(object obj)
{
try
{
XmlSerializer xs = new XmlSerializer(typeof(T));
using (TextWriter tw = new StringWriter())
{
xs.Serialize(tw, obj);
return tw.ToString();
}
}
catch (Exception)
{
return string.Empty;
}
}
/// <summary>
/// Xml格式字符转换为T类型的对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="xml"></param>
/// <returns></returns>
public static T ParseFormByXml<T>(string xml,string rootName="")
{
XmlSerializer serializer = new XmlSerializer(typeof(T), new XmlRootAttribute(rootName));
StringReader reader = new StringReader(xml);
T res = (T)serializer.Deserialize(reader);
reader.Close();
reader.Dispose();
return res;
}
}
}

View File

@ -0,0 +1,37 @@

namespace Blog.Core.Common.StaticHelper
{
public static class StaticPayInfo
{
/// <summary>
/// 商户号
/// </summary>
public readonly static string MERCHANTID = Appsettings.app(new string[] { "PayInfo", "MERCHANTID" }).ObjToString();
/// <summary>
/// 柜台号
/// </summary>
public readonly static string POSID = Appsettings.app(new string[] { "PayInfo", "POSID" }).ObjToString();
/// <summary>
/// 分行号
/// </summary>
public readonly static string BRANCHID = Appsettings.app(new string[] { "PayInfo", "BRANCHID" }).ObjToString();
/// <summary>
/// 公钥
/// </summary>
public readonly static string pubKey = Appsettings.app(new string[] { "PayInfo", "pubKey" }).ObjToString();
/// <summary>
/// 操作员号
/// </summary>
public readonly static string USER_ID = Appsettings.app(new string[] { "PayInfo", "USER_ID" }).ObjToString();
/// <summary>
/// 密码
/// </summary>
public readonly static string PASSWORD = Appsettings.app(new string[] { "PayInfo", "PASSWORD" }).ObjToString();
/// <summary>
/// 外联平台通讯地址
/// </summary>
public readonly static string OutAddress = Appsettings.app(new string[] { "PayInfo", "OutAddress" }).ObjToString();
}
}

View File

@ -37,10 +37,12 @@ namespace Blog.Core.Extensions
c.SwaggerDoc(version, new OpenApiInfo
{
Version = version,
Title = $"{ApiName} 接口文档——{RuntimeInformation.FrameworkDescription}",
Description = $"{ApiName} HTTP API " + version,
Contact = new OpenApiContact { Name = ApiName, Email = "Blog.Core@xxx.com", Url = new Uri("https://neters.club") },
License = new OpenApiLicense { Name = ApiName + " 官方文档", Url = new Uri("http://apk.neters.club/.doc/") }
Title = $"接口文档——{RuntimeInformation.FrameworkDescription}",
Description = $"HTTP API " + version,
//Title = $"{ApiName} 接口文档——{RuntimeInformation.FrameworkDescription}",
//Description = $"{ApiName} HTTP API " + version,
//Contact = new OpenApiContact { Name = ApiName, Email = "Blog.Core@xxx.com", Url = new Uri("https://neters.club") },
//License = new OpenApiLicense { Name = ApiName + " 官方文档", Url = new Uri("http://apk.neters.club/.doc/") }
});
c.OrderActionsBy(o => o.RelativePath);
});

View File

@ -0,0 +1,42 @@

using Blog.Core.IServices.BASE;
using Blog.Core.Model;
using Blog.Core.Model.ViewModels;
using System.Threading.Tasks;
namespace Blog.Core.IServices
{
/// <summary>
/// IPayServices
/// </summary>
public interface IPayServices : IBaseServices<RootEntityTkey<int>>
{
/// <summary>
/// 被扫支付
/// </summary>
/// <returns></returns>
Task<MessageModel<PayReturnResultModel>> Pay(PayNeedModel payModel);
/// <summary>
/// 退款
/// </summary>
/// <param name="payModel"></param>
/// <returns></returns>
Task<MessageModel<PayRefundReturnResultModel>> PayRefund(PayRefundNeedModel payModel);
/// <summary>
/// 轮询查询
/// </summary>
/// <param name="payModel"></param>
/// <param name="times">轮询次数</param>
/// <returns></returns>
Task<MessageModel<PayReturnResultModel>> PayCheck(PayNeedModel payModel,int times);
/// <summary>
/// 验证签名
/// </summary>
/// <param name="strSrc">参数</param>
/// <param name="sign">签名</param>
/// <param name="pubKey">公钥</param>
/// <returns></returns>
bool NotifyCheck(string strSrc, string sign, string pubKey);
}
}

View File

@ -1,5 +1,7 @@
using SqlSugar;
using Blog.Core.Model.ViewModels;
using SqlSugar;
using System;
using System.Collections.Generic;
namespace Blog.Core.Model.Models
{
@ -58,6 +60,9 @@ namespace Blog.Core.Model.Models
/// 执行间隔时间, 秒为单位
/// </summary>
public int IntervalSecond { get; set; }
/// 循环执行次数
/// </summary>
public int CycleRunTimes { get; set; }
/// <summary>
/// 是否启动
/// </summary>
@ -75,5 +80,10 @@ namespace Blog.Core.Model.Models
/// </summary>
[SugarColumn(IsNullable = true)]
public DateTime CreateTime { get; set; } = DateTime.Now;
/// <summary>
/// 任务内存中的状态
/// </summary>
[SugarColumn(IsIgnore = true)]
public List<TaskInfoDto> Triggers { get; set; }
}
}

View File

@ -0,0 +1,102 @@
namespace Blog.Core.Model.ViewModels
{
public class PayModel
{
/// <summary>
/// 商户号
/// </summary>
public string MERCHANTID { get; set; }//105910100190000");// => self::MERCHANTID, // 商户号
/// <summary>
/// 柜台号
/// </summary>
public string POSID { get; set; } //610000000");// => self::POSID, // 柜台号
/// <summary>
/// 分行号
/// </summary>
public string BRANCHID { get; set; } //610000000");// => self::BRANCHID, // 分行号
/// <summary>
/// 集团商户信息
/// </summary>
public string GROUPMCH { get; set; } //;// => '', // 集团商户信息
/// <summary>
/// 交易码
/// </summary>
public string TXCODE { get; set; } //PAY100");// => 'PAY100', // 交易码
/// <summary>
/// 商户类型
/// </summary>
public string MERFLAG { get; set; } //// => '', // 商户类型
/// <summary>
/// 终端编号 1
/// </summary>
public string TERMNO1 { get; set; } //// => '', // 终端编号 1
/// <summary>
/// 终端编号 2
/// </summary>
public string TERMNO2 { get; set; } //// => '', // 终端编号 2
/// <summary>
/// 订单号
/// </summary>
public string ORDERID { get; set; }//// => '', // 订单号
/// <summary>
/// 码信息(一维码、二维码)
/// </summary>
public string QRCODE { get; set; } //// => '', // 码信息(一维码、二维码)
/// <summary>
/// 订单金额,单位:元
/// </summary>
public string AMOUNT { get; set; } //");// => '0.01', // 订单金额,单位:元
/// <summary>
/// 商品名称
/// </summary>
public string PROINFO { get; set; } //// => '', // 商品名称
/// <summary>
/// 备注 1
/// </summary>
public string REMARK1 { get; set; } //// => '', // 备注 1
/// <summary>
/// 备注 2
/// </summary>
public string REMARK2 { get; set; }//// => '', // 备注 2
/// <summary>
/// 分账信息一
/// </summary>
public string FZINFO1 { get; set; } //// => '', // 分账信息一
/// <summary>
/// 分账信息二
/// </summary>
public string FZINFO2 { get; set; } //// => '', // 分账信息二
/// <summary>
/// 子商户公众账号 ID
/// </summary>
public string SUB_APPID { get; set; } //);// => '', // 子商户公众账号 ID
/// <summary>
/// 返回信息位图
/// </summary>
public string RETURN_FIELD { get; set; }// "");// => '', // 返回信息位图
/// <summary>
/// 实名支付
/// </summary>
public string USERPARAM { get; set; } //);// => '', // 实名支付
/// <summary>
/// 商品详情
/// </summary>
public string detail { get; set; }//// => '', // 商品详情
/// <summary>
/// 订单优惠标记
/// </summary>
public string goods_tag { get; set; } //);// => '', // 订单优惠标记
/// <summary>
/// 公钥
/// </summary>
public string pubKey { get; set; }
/// <summary>
/// 请求地址
/// </summary>
public string url { get; set; }
/// <summary>
/// 是否删除空值
/// </summary>
public bool deleteEmpty { get; set; }
}
}

View File

@ -0,0 +1,34 @@
namespace Blog.Core.Model.ViewModels
{
/// <summary>
/// 退款参数
/// </summary>
public class PayNeedModel
{
/// <summary>
/// 订单ID
/// </summary>
public string ORDERID { get; set; }
/// <summary>
/// 商品名称
/// </summary>
public string PROINFO { get; set; }
/// <summary>
/// 支付金额(小数点最多两位)
/// </summary>
public string AMOUNT { get; set; }
/// <summary>
/// 二维码/条码信息
/// </summary>
public string QRCODE { get; set; }
/// <summary>
/// 备注信息1
/// </summary>
public string REMARK1 { get; set; }
/// <summary>
/// 备注信息2
/// </summary>
public string REMARK2 { get; set; }
}
}

View File

@ -0,0 +1,21 @@
namespace Blog.Core.Model.ViewModels
{
/// <summary>
/// 订单参数
/// </summary>
public class PayRefundNeedModel
{
/// <summary>
/// 订单号
/// </summary>
public string ORDER { get; set; }
/// <summary>
/// 退款金额
/// </summary>
public string MONEY { get; set; }
/// <summary>
/// 退款流水号(可选)
/// </summary>
public string REFUND_CODE { get; set; }
}
}

View File

@ -0,0 +1,37 @@
namespace Blog.Core.Model.ViewModels
{
/// <summary>
/// 退款返回消息
/// </summary>
public class PayRefundReturnModel
{
/// <summary>
/// 序列号
/// </summary>
public string REQUEST_SN { get; set; }
/// <summary>
/// 商户号
/// </summary>
public string CUST_ID { get; set; }
/// <summary>
/// 交易码
/// </summary>
public string TX_CODE { get; set; }
/// <summary>
/// 返回码
/// </summary>
public string RETURN_CODE { get; set; }
/// <summary>
/// 返回码说明
/// </summary>
public string RETURN_MSG { get; set; }
/// <summary>
/// 语言
/// </summary>
public string LANGUAGE { get; set; }
/// <summary>
/// 订单信息
/// </summary>
public PayRefundReturnOrderInfoModel TX_INFO { get; set; }
}
}

View File

@ -0,0 +1,30 @@
namespace Blog.Core.Model.ViewModels
{
/// <summary>
/// 订单信息
/// </summary>
public class PayRefundReturnOrderInfoModel
{
/// <summary>
/// 订单号
/// </summary>
public string ORDER_NUM { get; set; }
/// <summary>
/// 支付金额
/// </summary>
public string PAY_AMOUNT { get; set; }
/// <summary>
/// 退款金额
/// </summary>
public string AMOUNT { get; set; }
/// <summary>
/// 备注1
/// </summary>
public string REM1 { get; set; }
/// <summary>
/// 备注2
/// </summary>
public string REM2 { get; set; }
}
}

View File

@ -0,0 +1,45 @@
namespace Blog.Core.Model.ViewModels
{
/// <summary>
/// 退款返回结果消息
/// </summary>
public class PayRefundReturnResultModel
{
/// <summary>
/// 订单号
/// </summary>
public string ORDER_NUM { get; set; }
/// <summary>
/// 支付金额
/// </summary>
public string PAY_AMOUNT { get; set; }
/// <summary>
/// 退款金额
/// </summary>
public string AMOUNT { get; set; }
/// <summary>
/// 序列号
/// </summary>
public string REQUEST_SN { get; set; }
/// <summary>
/// 商户号
/// </summary>
public string CUST_ID { get; set; }
/// <summary>
/// 交易码
/// </summary>
public string TX_CODE { get; set; }
/// <summary>
/// 返回码
/// </summary>
public string RETURN_CODE { get; set; }
/// <summary>
/// 返回码说明
/// </summary>
public string RETURN_MSG { get; set; }
/// <summary>
/// 语言
/// </summary>
public string LANGUAGE { get; set; }
}
}

View File

@ -0,0 +1,53 @@
namespace Blog.Core.Model.ViewModels
{
/// <summary>
/// 支付结果dto
/// </summary>
public class PayResultModel
{
/// <summary>
/// 支付结果
/// Y成功
/// N失败
/// U不确定
/// Q待轮询
/// </summary>
public string RESULT { get; set; }
/// <summary>
/// 订单ID
/// </summary>
public string ORDERID { get; set; }
/// <summary>
/// 支付金额
/// </summary>
public string AMOUNT { get; set; }
/// <summary>
/// 二维码类型
/// 1龙支付
/// 2微信
/// 3支付宝
/// 4银联
/// </summary>
public string QRCODETYPE { get; set; }
/// <summary>
/// 等待时间-轮询等待时间
/// </summary>
public string WAITTIME { get; set; }
/// <summary>
/// 全局事件跟踪号-建行交易流水号
/// </summary>
public string TRACEID { get; set; }
/// <summary>
/// 错误码
/// </summary>
public string ERRCODE { get; set; }
/// <summary>
/// 错误信息
/// </summary>
public string ERRMSG { get; set; }
/// <summary>
/// 验证签名-防止伪造攻击
/// </summary>
public string SIGN { get; set; }
}
}

View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Blog.Core.Model.ViewModels
{
/// <summary>
/// 返回支付结果
/// </summary>
public class PayReturnResultModel
{
/// <summary>
/// 发起的订单ID
/// </summary>
public string ORDERID { get; set; }
/// <summary>
/// 返回支付的金额
/// </summary>
public string AMOUNT { get; set; }
/// <summary>
/// 返回支付的类型 1龙支付 2微信 3支付宝 4银联
/// </summary>
public string QRCODETYPE { get; set; }
/// <summary>
/// 返回建行的流水号
/// </summary>
public string TRACEID { get; set; }
/// <summary>
/// 错误代码
/// </summary>
public string ERRCODE { get; set; }
/// <summary>
/// 错误信息
/// </summary>
public string ERRMSG { get; set; }
}
}

View File

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Blog.Core.Model.ViewModels
{
/// <summary>
/// 调度任务触发器信息实体
/// </summary>
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; }
}
}

View File

@ -17,5 +17,12 @@
<ProjectReference Include="..\Blog.Core.IServices\Blog.Core.IServices.csproj" />
<ProjectReference Include="..\Blog.Core.Repository\Blog.Core.Repository.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="CCB_B2CPay_Util">
<HintPath>File\CCB_B2CPay_Util.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

Binary file not shown.

View File

@ -0,0 +1,416 @@
using Blog.Core.Common.Helper;
using Blog.Core.Common.StaticHelper;
using Blog.Core.IRepository.Base;
using Blog.Core.IServices;
using Blog.Core.Model;
using Blog.Core.Model.ViewModels;
using Blog.Core.Services.BASE;
using CCB_B2CPay_Util;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Blog.Core.Services
{
public partial class PayServices : BaseServices<RootEntityTkey<int>>, IPayServices
{
IBaseRepository<RootEntityTkey<int>> _dal;
ILogger<PayServices> _logger;
public PayServices(IBaseRepository<RootEntityTkey<int>> dal, ILogger<PayServices> logger)
{
this._dal = dal;
base.BaseDal = dal;
_logger = logger;
}
public async Task<MessageModel<PayReturnResultModel>> Pay(PayNeedModel payModel)
{
_logger.LogInformation("支付开始");
MessageModel<PayReturnResultModel> messageModel = new MessageModel<PayReturnResultModel>();
messageModel.response = new PayReturnResultModel();
string url =string.Empty;
string param = string.Empty;
string returnData = string.Empty;
try
{
//被扫支付
string host = "https://ibsbjstar.ccb.com.cn/CCBIS/B2CMainPlat_00_BEPAY?";
////商户信息
//string merInfo = "MERCHANTID=105910100190000&POSID=000000000&BRANCHID=610000000";
////获取柜台完整公钥
//string pubKey = "30819d300d06092a864886f70d010101050003818b0030818702818100a32fb2d51dda418f65ca456431bd2f4173e41a82bb75c2338a6f649f8e9216204838d42e2a028c79cee19144a72b5b46fe6a498367bf4143f959e4f73c9c4f499f68831f8663d6b946ae9fa31c74c9332bebf3cba1a98481533a37ffad944823bd46c305ec560648f1b6bcc64d54d32e213926b26cd10d342f2c61ff5ac2d78b020111";
////加密原串
//string param = merInfo + "&MERFLAG=1&TERMNO1=&TERMNO2=&ORDERID=937857156" +
// "&QRCODE=134737690209713400&AMOUNT=0.01&TXCODE=PAY100&PROINFO=&REMARK1=&REMARK2=&SMERID=&SMERNAME=&SMERTYPEID=" +
// "&SMERTYPE=&TRADECODE=&TRADENAME=&SMEPROTYPE=&PRONAME=";
Dictionary<string, string> dic = new Dictionary<string, string>();
//dic.Add("MERCHANTID", StaticPayInfo.MERCHANTID);// => self::MERCHANTID, // 商户号
dic.Add("POSID", StaticPayInfo.POSID);// => self::POSID, // 柜台号
dic.Add("BRANCHID", StaticPayInfo.BRANCHID);// => self::BRANCHID, // 分行号
dic.Add("TXCODE", "PAY100");// => 'PAY100', // 交易码
dic.Add("MERFLAG", "1");// => '', // 商户类型 1线上 2线下
dic.Add("ORDERID", payModel.ORDERID);//payModel.ORDERID);// => '', // 订单号
dic.Add("QRCODE", payModel.QRCODE);// => '', // 码信息(一维码、二维码)
dic.Add("AMOUNT", payModel.AMOUNT);// => '0.01', // 订单金额,单位:元
dic.Add("PROINFO", payModel.PROINFO);// => '', // 商品名称
dic.Add("REMARK1", payModel.REMARK1);// => '', // 备注 1
dic.Add("REMARK2", payModel.REMARK2);// => '', // 备注 2
//dic.Add("TERMNO1", "");// => '', // 终端编号 1
//dic.Add("TERMNO2", "");// => '', // 终端编号 2
//dic.Add("GROUPMCH", "");// => '', // 集团商户信息
//dic.Add("FZINFO1", "");// => '', // 分账信息一
//dic.Add("FZINFO2", "");// => '', // 分账信息二
//dic.Add("SUB_APPID", "");// => '', // 子商户公众账号 ID
//dic.Add("RETURN_FIELD", "");// => '', // 返回信息位图
//dic.Add("USERPARAM", "");// => '', // 实名支付
//dic.Add("detail", "");// => '', // 商品详情
//dic.Add("goods_tag", "");// => '', // 订单优惠标记
//商户信息
Dictionary<string, string> dicInfo = new Dictionary<string, string>();
dicInfo.Add("MERCHANTID", StaticPayInfo.MERCHANTID);// => self::MERCHANTID, // 商户号
dicInfo.Add("POSID", StaticPayInfo.POSID);// => self::POSID, // 柜台号
dicInfo.Add("BRANCHID", StaticPayInfo.BRANCHID);// => self::BRANCHID, // 分行号
var Info = StringHelper.GetPars(dicInfo);
//获取拼接请求串
param = StringHelper.GetPars(dic);
//加密
var paramEncryption = new CCBPayUtil().makeCCBParam(param, StaticPayInfo.pubKey);
//拼接请求串
url = host + Info + "&ccbParam=" + paramEncryption;
//请求
_logger.LogInformation($"请求地址->{url}");
_logger.LogInformation($"请求参数->{param}");
try
{
returnData = await GetNetData.PostAsync(url);
string lines = StringHelper.GetCusLine(returnData, 15);
}
catch (Exception ex)
{
_logger.LogInformation($"异常信息:{ex.Message}");
_logger.LogInformation($"异常堆栈:{ex.StackTrace}");
messageModel = await PayCheck(payModel,1);
return messageModel;
}
_logger.LogInformation($"响应数据->{returnData}");
//转换数据
PayResultModel payResult;
try
{
payResult = JsonHelper.ParseFormByJson<PayResultModel>(returnData);
}
catch
{
payResult = new PayResultModel { RESULT = "N",ERRMSG= "参数错误" };
}
switch (payResult.RESULT)
{
case "Y":
Dictionary<string, string> dicCheckPars = new Dictionary<string, string>();
dicCheckPars.Add("RESULT", payResult.RESULT);
dicCheckPars.Add("ORDERID", payResult.ORDERID);
dicCheckPars.Add("AMOUNT", payResult.AMOUNT);
dicCheckPars.Add("WAITTIME", payResult.WAITTIME);
dicCheckPars.Add("TRACEID", payResult.TRACEID);
string strCheckPars = StringHelper.GetPars(dicCheckPars);
if (NotifyCheck(strCheckPars, payResult.SIGN, StaticPayInfo.pubKey))
{
messageModel.success = true;
messageModel.msg = "支付成功";
}
else
{
messageModel.success = false;
messageModel.msg = "签名失败";
}
break;
case "N":
messageModel.success = false;
messageModel.msg = "支付失败";
break;
case "U":
case "Q":
int waittime = payResult.WAITTIME.ObjToInt();
if (waittime <= 0) waittime = 5;//如果需要等待默认等待5秒后再次查询
Thread.Sleep(waittime * 1000);
//轮询查询
messageModel = await PayCheck(payModel,1);
break;
default:
messageModel.success = false;
messageModel.msg = "支付失败";
break;
}
messageModel.response.ORDERID = payResult.ORDERID;
messageModel.response.ERRCODE = payResult.ERRCODE;
messageModel.response.ERRMSG = payResult.ERRMSG;
messageModel.response.TRACEID = payResult.TRACEID;
messageModel.response.AMOUNT = payResult.AMOUNT;
messageModel.response.QRCODETYPE = payResult.QRCODETYPE;
}
catch (Exception ex)
{
messageModel.success = false;
messageModel.msg = "服务错误";
messageModel.response.ERRMSG = ex.Message;
_logger.LogInformation($"异常信息:{ex.Message}");
_logger.LogInformation($"异常堆栈:{ex.StackTrace}");
}
finally
{
_logger.LogInformation($"返回数据->{JsonHelper.GetJSON<MessageModel<PayReturnResultModel>>(messageModel)}");
_logger.LogInformation("支付结束");
}
return messageModel;
}
public async Task<MessageModel<PayRefundReturnResultModel>> PayRefund(PayRefundNeedModel payModel)
{
_logger.LogInformation("退款开始");
MessageModel<PayRefundReturnResultModel> messageModel = new MessageModel<PayRefundReturnResultModel>();
messageModel.response = new PayRefundReturnResultModel();
try
{
string REQUEST_SN = StringHelper.GetGuidToLongID().ToString().Substring(0, 16);//请求序列码
string CUST_ID = StaticPayInfo.MERCHANTID;//商户号
string USER_ID = StaticPayInfo.USER_ID;//操作员号
string PASSWORD = StaticPayInfo.PASSWORD;//密码
string TX_CODE = "5W1004";//交易码
string LANGUAGE = "CN";//语言
//string SIGN_INFO = "";//签名信息
//string SIGNCERT = "";//签名CA信息
//外联平台客户端服务部署的地址+设置的监听端口
string sUrl = StaticPayInfo.OutAddress;
//XML请求报文
//string sRequestMsg = $" requestXml=<?xml version=\"1.0\" encoding=\"GB2312\" standalone=\"yes\" ?><TX><REQUEST_SN>{REQUEST_SN}</REQUEST_SN><CUST_ID>{CUST_ID}</CUST_ID><USER_ID>{USER_ID}</USER_ID><PASSWORD>{PASSWORD}</PASSWORD><TX_CODE>{TX_CODE}</TX_CODE><LANGUAGE>{LANGUAGE}</LANGUAGE><TX_INFO><MONEY>{payModel.MONEY}</MONEY><ORDER>{payModel.ORDER}</ORDER><REFUND_CODE>{payModel.REFUND_CODE}</REFUND_CODE></TX_INFO><SIGN_INFO></SIGN_INFO><SIGNCERT></SIGNCERT></TX> ";
string sRequestMsg = $"<?xml version=\"1.0\" encoding=\"GB2312\" standalone=\"yes\" ?><TX><REQUEST_SN>{REQUEST_SN}</REQUEST_SN><CUST_ID>{CUST_ID}</CUST_ID><USER_ID>{USER_ID}</USER_ID><PASSWORD>{PASSWORD}</PASSWORD><TX_CODE>{TX_CODE}</TX_CODE><LANGUAGE>{LANGUAGE}</LANGUAGE><TX_INFO><MONEY>{payModel.MONEY}</MONEY><ORDER>{payModel.ORDER}</ORDER><REFUND_CODE>{payModel.REFUND_CODE}</REFUND_CODE></TX_INFO><SIGN_INFO></SIGN_INFO><SIGNCERT></SIGNCERT></TX> ";
//string sRequestMsg = readRequestFile("E:/02-外联平台/06-测试/测试报文/商户网银/客户端连接-5W1001-W06.txt");
//注意请求报文必须放在requestXml参数送
sRequestMsg = "requestXml=" + sRequestMsg;
_logger.LogInformation("请求地址:" + sUrl);
_logger.LogInformation("请求报文:" + sRequestMsg);
HttpWebRequest request = (System.Net.HttpWebRequest)HttpWebRequest.Create(sUrl);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.KeepAlive = false;
request.Connection = "";
//外联平台使用GB18030编码这里进行转码处理
byte[] byteRquest = Encoding.GetEncoding("GB18030").GetBytes(sRequestMsg);
request.ContentLength = byteRquest.Length;
//发送请求
Stream writerStream = request.GetRequestStream();
await writerStream.WriteAsync(byteRquest, 0, byteRquest.Length);
writerStream.Flush();
writerStream.Close();
//接收请求
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream result = response.GetResponseStream();
StreamReader readerResult = new StreamReader(result, System.Text.Encoding.GetEncoding("GB18030"));
string sResult = await readerResult.ReadToEndAsync();
_logger.LogInformation("响应报文:" + sResult);
var Xmlresult = XmlHelper.ParseFormByXml<PayRefundReturnModel>(sResult, "TX");
if (Xmlresult.RETURN_CODE.Equals("000000"))
{
messageModel.success = true;
messageModel.msg = "退款成功";
}
else
{
messageModel.success = false;
messageModel.msg = "退款失败";
}
messageModel.response.RETURN_MSG = Xmlresult.RETURN_MSG;
messageModel.response.TX_CODE = Xmlresult.TX_CODE;
messageModel.response.REQUEST_SN = Xmlresult.REQUEST_SN;
messageModel.response.RETURN_CODE = Xmlresult.RETURN_CODE;
messageModel.response.CUST_ID = Xmlresult.CUST_ID;
messageModel.response.LANGUAGE = Xmlresult.LANGUAGE;
messageModel.response.AMOUNT = Xmlresult.TX_INFO?.AMOUNT;
messageModel.response.PAY_AMOUNT = Xmlresult.TX_INFO?.PAY_AMOUNT;
messageModel.response.ORDER_NUM = Xmlresult.TX_INFO?.ORDER_NUM;
}
catch (Exception ex)
{
messageModel.success = false;
messageModel.msg = "服务错误";
messageModel.response.RETURN_MSG = ex.Message;
_logger.LogInformation($"异常信息:{ex.Message}");
_logger.LogInformation($"异常堆栈:{ex.StackTrace}");
}
finally
{
_logger.LogInformation("退款结束");
}
return messageModel;
}
public async Task<MessageModel<PayReturnResultModel>> PayCheck(PayNeedModel payModel,int times)
{
_logger.LogInformation("轮序开始");
MessageModel<PayReturnResultModel> messageModel = new MessageModel<PayReturnResultModel>();
messageModel.response = new PayReturnResultModel();
string url = string.Empty;
string param = string.Empty;
string returnData = string.Empty;
try
{
string host = "https://ibsbjstar.ccb.com.cn/CCBIS/B2CMainPlat_00_BEPAY?";
Dictionary<string, string> dic = new Dictionary<string, string>();
dic.Add("MERCHANTID", StaticPayInfo.MERCHANTID);// => self::MERCHANTID, // 商户号
dic.Add("POSID", StaticPayInfo.POSID);// => self::POSID, // 柜台号
dic.Add("BRANCHID", StaticPayInfo.BRANCHID);// => self::BRANCHID, // 分行号
dic.Add("TXCODE", "PAY101");// => 'PAY100', // 交易码
dic.Add("QRYTIME", times.ToString());// => '', // 查询此时(每次加1)
dic.Add("MERFLAG", "1");// => '', // 商户类型
dic.Add("ORDERID", payModel.ORDERID);// => '', // 订单号
dic.Add("QRCODE", payModel.QRCODE);// => '', // 码信息(一维码、二维码)
//dic.Add("GROUPMCH", "");// => '', // 集团商户信息
//dic.Add("QRCODETYPE", "");// => '', // 支付类型1龙支付 2微信 3支付宝 4银联
//dic.Add("TERMNO1", "");// => '', // 终端编号 1
//dic.Add("TERMNO2", "");// => '', // 终端编号 2
//dic.Add("AMOUNT", "");// => '0.01', // 订单金额,单位:元
//dic.Add("PROINFO", "");// => '', // 商品名称
//dic.Add("REMARK1", "");// => '', // 备注 1
//dic.Add("REMARK2", "");// => '', // 备注 2
//dic.Add("FZINFO1", "");// => '', // 分账信息一
//dic.Add("FZINFO2", "");// => '', // 分账信息二
//dic.Add("SUB_APPID", "");// => '', // 子商户公众账号 ID
//dic.Add("RETURN_FIELD", "");// => '', // 返回信息位图
//dic.Add("USERPARAM", "");// => '', // 实名支付
//dic.Add("detail", "");// => '', // 商品详情
//dic.Add("goods_tag", "");// => '', // 订单优惠标记
//商户信息
Dictionary<string, string> dicInfo = new Dictionary<string, string>();
dicInfo.Add("MERCHANTID", StaticPayInfo.MERCHANTID);// => self::MERCHANTID, // 商户号
dicInfo.Add("POSID", StaticPayInfo.POSID);// => self::POSID, // 柜台号
dicInfo.Add("BRANCHID", StaticPayInfo.BRANCHID);// => self::BRANCHID, // 分行号
var Info = StringHelper.GetPars(dicInfo);
//var newDic = dic.OrderBy(t => t.Key).ToDictionary(o => o.Key, p => p.Value);
//参数信息
param = StringHelper.GetPars(dic);
//加密
var paramEncryption = new CCBPayUtil().makeCCBParam(param, StaticPayInfo.pubKey);
//拼接请求串
url = host + Info + "&ccbParam=" + paramEncryption;
//请求
_logger.LogInformation($"请求地址->{url}");
_logger.LogInformation($"请求参数->{param}");
//转换数据
PayResultModel payResult;
try
{
returnData = await GetNetData.PostAsync(url);
_logger.LogInformation($"响应数据->{returnData}");
}
catch (Exception ex)
{
_logger.LogInformation($"异常信息:{ex.Message}");
_logger.LogInformation($"异常堆栈:{ex.StackTrace}");
return await PayCheck(payModel, ++times);
}
try
{
payResult = JsonHelper.ParseFormByJson<PayResultModel>(returnData);
}
catch
{
payResult = new PayResultModel { RESULT = "N", ERRMSG = "参数错误" };
}
switch (payResult.RESULT)
{
case "Y":
Dictionary<string, string> dicCheckPars = new Dictionary<string, string>();
dicCheckPars.Add("RESULT", payResult.RESULT);
dicCheckPars.Add("ORDERID", payResult.ORDERID);
dicCheckPars.Add("AMOUNT", payResult.AMOUNT);
dicCheckPars.Add("WAITTIME", payResult.WAITTIME);
string strCheckPars = StringHelper.GetPars(dicCheckPars);
if (NotifyCheck(strCheckPars, payResult.SIGN, StaticPayInfo.pubKey))
{
messageModel.success = true;
messageModel.msg = "支付成功";
}
else
{
messageModel.success = false;
messageModel.msg = "签名失败";
}
break;
case "N":
messageModel.success = false;
messageModel.msg = "支付失败";
break;
case "U":
case "Q":
int waittime = payResult.WAITTIME.ObjToInt();
if (waittime <= 0) waittime = 5;//如果需要等待默认等待5秒后再次查询
Thread.Sleep(waittime * 1000);
//改成轮询查询
messageModel = await PayCheck(payModel, ++times);
break;
default:
messageModel.success = false;
messageModel.msg = "支付失败";
break;
}
messageModel.response.ORDERID = payResult.ORDERID;
messageModel.response.ERRCODE = payResult.ERRCODE;
messageModel.response.ERRMSG = payResult.ERRMSG;
messageModel.response.TRACEID = payResult.TRACEID;
messageModel.response.AMOUNT = payResult.AMOUNT;
messageModel.response.QRCODETYPE = payResult.QRCODETYPE;
}
catch (Exception ex)
{
messageModel.success = false;
messageModel.msg = "服务错误";
messageModel.response.ERRMSG = ex.Message;
_logger.LogInformation($"异常信息:{ex.Message}");
_logger.LogInformation($"异常堆栈:{ex.StackTrace}");
}
finally
{
_logger.LogInformation("轮序结束");
}
return messageModel;
}
public bool NotifyCheck(string strSrc,string sign,string pubKey) {
return new CCBPayUtil().verifyNotifySign(strSrc, sign, pubKey);
}
}
}

View File

@ -1,5 +1,7 @@
using Blog.Core.Model;
using Blog.Core.Model.Models;
using Blog.Core.Model.ViewModels;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Blog.Core.Tasks
@ -32,6 +34,13 @@ namespace Blog.Core.Tasks
/// <param name="sysSchedule"></param>
/// <returns></returns>
Task<MessageModel<string>> StopScheduleJobAsync(TasksQz sysSchedule);
/// <summary>
/// 暂停指定的计划任务
/// </summary>
/// <param name="sysSchedule"></param>
/// <returns></returns>
Task<MessageModel<string>> PauseJob(TasksQz sysSchedule);
/// <summary>
/// 恢复一个任务
/// </summary>
@ -39,6 +48,19 @@ namespace Blog.Core.Tasks
/// <returns></returns>
Task<MessageModel<string>> 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);
}
}

View File

@ -1,4 +1,6 @@
using Quartz;
using Blog.Core.Common.Helper;
using Blog.Core.IServices;
using Quartz;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
@ -7,6 +9,11 @@ namespace Blog.Core.Tasks
{
public class JobBase
{
public readonly ITasksQzServices _tasksQzServices;
public JobBase(ITasksQzServices tasksQzServices)
{
_tasksQzServices = tasksQzServices;
}
/// <summary>
/// 执行指定任务
/// </summary>
@ -14,17 +21,22 @@ namespace Blog.Core.Tasks
/// <param name="action"></param>
public async Task<string> ExecuteJob(IJobExecutionContext context, Func<Task> func)
{
string jobHistory = $"【{DateTime.Now}】执行任务【Id{context.JobDetail.Key.Name},组别:{context.JobDetail.Key.Group}】";
//记录Job时间
Stopwatch stopwatch = new Stopwatch();
//JOBID
int jobid = context.JobDetail.Key.Name.ObjToInt();
//JOB组名
string groupName = context.JobDetail.Key.Group;
//日志
string jobHistory = $"【{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}】【执行开始】【Id{jobid},组别:{groupName}】";
//耗时
double taskSeconds = 0;
try
{
var s = context.Trigger.Key.Name;
//记录Job时间
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
await func();//执行任务
stopwatch.Stop();
jobHistory += $",【执行成功】,完成时间:{stopwatch.Elapsed.TotalMilliseconds.ToString("00")}毫秒";
//SerilogServer.WriteLog(context.Trigger.Key.Name.Replace("-", ""), $"{context.Trigger.Key.Name}定时任务运行一切OK", "任务结束");
jobHistory += $",【{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}】【执行成功】";
}
catch (Exception ex)
{
@ -33,7 +45,21 @@ namespace Blog.Core.Tasks
e2.RefireImmediately = true;
//SerilogServer.WriteErrorLog(context.Trigger.Key.Name.Replace("-", ""), $"{context.Trigger.Key.Name}任务运行异常", ex);
jobHistory += $",【执行失败】,异常日志:{ex.Message}";
jobHistory += $",【{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}】【执行失败:{ex.Message}】";
}
finally
{
taskSeconds = Math.Round(stopwatch.Elapsed.TotalSeconds, 3);
jobHistory += $",【{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}】【执行结束】(耗时:{taskSeconds}秒)";
var model = await _tasksQzServices.QueryById(jobid);
if (model != null)
{
model.RunTimes += 1;
var separator = "<br>";
model.Remark =
$"{jobHistory}{separator}" + string.Join(separator, StringHelper.GetTopDataBySeparator(model.Remark, separator, 9));
await _tasksQzServices.Update(model);
}
}
Console.Out.WriteLine(jobHistory);

View File

@ -1,7 +1,5 @@
using Blog.Core.Common.Helper;
using Blog.Core.IServices;
using Blog.Core.IServices;
using Quartz;
using System;
using System.Threading.Tasks;
/// <summary>
@ -11,57 +9,24 @@ namespace Blog.Core.Tasks
{
public class Job_Blogs_Quartz : JobBase, IJob
{
private readonly IBlogArticleServices _blogArticleServices;
private readonly ITasksQzServices _tasksQzServices;
private readonly IBlogArticleServices _blogArticleServices;
public Job_Blogs_Quartz(IBlogArticleServices blogArticleServices, ITasksQzServices tasksQzServices)
public Job_Blogs_Quartz(IBlogArticleServices blogArticleServices, ITasksQzServices tasksQzServices):base(tasksQzServices)
{
_blogArticleServices = blogArticleServices;
_tasksQzServices = tasksQzServices;
_blogArticleServices = blogArticleServices;
}
public async Task Execute(IJobExecutionContext context)
{
//var param = context.MergedJobDataMap;
// 可以直接获取 JobDetail 的值
{
var jobKey = context.JobDetail.Key;
var jobId = jobKey.Name;
var executeLog = await ExecuteJob(context, async () => await Run(context, jobId.ObjToInt()));
// 也可以通过数据库配置,获取传递过来的参数
JobDataMap data = context.JobDetail.JobDataMap;
//int jobId = data.GetInt("JobParam");
//var model = await _tasksQzServices.QueryById(jobId);
//if (model != null)
//{
// model.RunTimes += 1;
// model.Remark += $"{executeLog}<br />";
// await _tasksQzServices.Update(model);
//}
await ExecuteJob(context, async () => await Run(context, jobId.ObjToInt()));
}
public async Task Run(IJobExecutionContext context, int jobid)
{
var list = await _blogArticleServices.Query();
if (jobid > 0)
{
var model = await _tasksQzServices.QueryById(jobid);
if (model != null)
{
model.RunTimes += 1;
var separator = "<br>";
model.Remark =
$"【{DateTime.Now}】执行任务【Id{context.JobDetail.Key.Name},组别:{context.JobDetail.Key.Group}】【执行成功】:博客数{list.Count}{separator}"
+ string.Join(separator, StringHelper.GetTopDataBySeparator(model.Remark, separator, 9));
await _tasksQzServices.Update(model);
}
var list = await _blogArticleServices.Query();
}
await Console.Out.WriteLineAsync("博客总数量" + list.Count.ToString());
}
}

View File

@ -18,14 +18,12 @@ namespace Blog.Core.Tasks
{
public class Job_OperateLog_Quartz : JobBase, IJob
{
private readonly IOperateLogServices _operateLogServices;
private readonly ITasksQzServices _tasksQzServices;
private readonly IOperateLogServices _operateLogServices;
private readonly IWebHostEnvironment _environment;
public Job_OperateLog_Quartz(IOperateLogServices operateLogServices, ITasksQzServices tasksQzServices, IWebHostEnvironment environment)
public Job_OperateLog_Quartz(IOperateLogServices operateLogServices, ITasksQzServices tasksQzServices, IWebHostEnvironment environment) : base(tasksQzServices)
{
_operateLogServices = operateLogServices;
_tasksQzServices = tasksQzServices;
_operateLogServices = operateLogServices;
_environment = environment;
}
public async Task Execute(IJobExecutionContext context)
@ -77,23 +75,7 @@ namespace Blog.Core.Tasks
if (operateLogs.Count > 0)
{
var logsIds = await _operateLogServices.Add(operateLogs);
}
if (jobid > 0)
{
var model = await _tasksQzServices.QueryById(jobid);
if (model != null)
{
var list = await _operateLogServices.Query(d => d.IsDeleted == false);
model.RunTimes += 1;
var separator = "<br>";
model.Remark =
$"【{DateTime.Now}】执行任务【Id{context.JobDetail.Key.Name},组别:{context.JobDetail.Key.Group}】【执行成功】:异常数{list.Count}{separator}"
+ string.Join(separator, StringHelper.GetTopDataBySeparator(model.Remark, separator, 9));
await _tasksQzServices.Update(model);
}
}
}
}
}

View File

@ -1,10 +1,12 @@
using Blog.Core.Model;
using Blog.Core.Model.Models;
using Blog.Core.Model.ViewModels;
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.Threading.Tasks;
@ -214,7 +216,7 @@ namespace Blog.Core.Tasks
}
else
{
await this._scheduler.Result.PauseJob(jobKey);
await this._scheduler.Result.DeleteJob(jobKey);
result.success = true;
result.msg = $"暂停任务:【{sysSchedule.Name}】成功";
return result;
@ -229,41 +231,23 @@ namespace Blog.Core.Tasks
/// <summary>
/// 恢复指定的计划任务
/// </summary>
/// <param name="tasksQz"></param>
/// <param name="sysSchedule"></param>
/// <returns></returns>
public async Task<MessageModel<string>> ResumeJob(TasksQz tasksQz)
public async Task<MessageModel<string>> ResumeJob(TasksQz sysSchedule)
{
var result = new MessageModel<string>();
try
{
JobKey jobKey = new JobKey(tasksQz.Id.ToString(), tasksQz.JobGroup);
JobKey jobKey = new JobKey(sysSchedule.Id.ToString(), sysSchedule.JobGroup);
if (!await _scheduler.Result.CheckExists(jobKey))
{
result.success = false;
result.msg = $"未找到要重新的任务:【{tasksQz.Name}】,请先选择添加计划!";
result.msg = $"未找到要恢复的任务:【{sysSchedule.Name}】";
return result;
}
//await this._scheduler.Result.ResumeJob(jobKey);
ITrigger trigger;
if (tasksQz.Cron != null && CronExpression.IsValidExpression(tasksQz.Cron) && tasksQz.TriggerType > 0)
{
trigger = CreateCronTrigger(tasksQz);
}
else
{
trigger = CreateSimpleTrigger(tasksQz);
}
((CronTriggerImpl)trigger).MisfireInstruction = MisfireInstruction.CronTrigger.DoNothing;
TriggerKey triggerKey = new TriggerKey(tasksQz.Id.ToString(), tasksQz.JobGroup);
await _scheduler.Result.RescheduleJob(triggerKey, trigger);
await this._scheduler.Result.ResumeJob(jobKey);
result.success = true;
result.msg = $"恢复计划任务:【{tasksQz.Name}】成功";
result.msg = $"恢复任务:【{sysSchedule.Name}】成功";
return result;
}
catch (Exception)
@ -271,7 +255,121 @@ namespace Blog.Core.Tasks
throw;
}
}
/// <summary>
/// 暂停指定的计划任务
/// </summary>
/// <param name="sysSchedule"></param>
/// <returns></returns>
public async Task<MessageModel<string>> PauseJob(TasksQz sysSchedule)
{
var result = new MessageModel<string>();
try
{
JobKey jobKey = new JobKey(sysSchedule.Id.ToString(), sysSchedule.JobGroup);
if (!await _scheduler.Result.CheckExists(jobKey))
{
result.success = false;
result.msg = $"未找到要暂停的任务:【{sysSchedule.Name}】";
return result;
}
await this._scheduler.Result.PauseJob(jobKey);
result.success = true;
result.msg = $"暂停任务:【{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.ObjToString(),
jobGroup = sysSchedule.JobGroup,
triggerId = "",
triggerGroup = "",
triggerStatus = "不存在"
} };
JobKey jobKey = new JobKey(sysSchedule.Id.ToString(), sysSchedule.JobGroup);
IJobDetail job = await this._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 this._scheduler.Result.GetTriggersOfJob(jobKey);
if (triggers == null || triggers.Count == 0)
{
return noTask;
}
foreach (var trigger in triggers)
{
var triggerStaus = await this._scheduler.Result.GetTriggerState(trigger.Key);
string state = GetTriggerState(triggerStaus.ObjToString());
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>
@ -283,15 +381,16 @@ namespace Blog.Core.Tasks
/// <returns></returns>
private ITrigger CreateSimpleTrigger(TasksQz sysSchedule)
{
if (sysSchedule.RunTimes > 0)
if (sysSchedule.CycleRunTimes > 0)
{
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity(sysSchedule.Id.ToString(), sysSchedule.JobGroup)
.StartAt(sysSchedule.BeginTime.Value)
.EndAt(sysSchedule.EndTime.Value)
.WithSimpleSchedule(x =>
x.WithIntervalInSeconds(sysSchedule.IntervalSecond)
.WithRepeatCount(sysSchedule.RunTimes)).ForJob(sysSchedule.Id.ToString(), sysSchedule.JobGroup).Build();
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(sysSchedule.IntervalSecond)
.WithRepeatCount(sysSchedule.CycleRunTimes - 1))
.EndAt(sysSchedule.EndTime.Value)
.Build();
return trigger;
}
else
@ -299,10 +398,12 @@ namespace Blog.Core.Tasks
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity(sysSchedule.Id.ToString(), sysSchedule.JobGroup)
.StartAt(sysSchedule.BeginTime.Value)
.EndAt(sysSchedule.EndTime.Value)
.WithSimpleSchedule(x =>
x.WithIntervalInSeconds(sysSchedule.IntervalSecond)
.RepeatForever()).ForJob(sysSchedule.Id.ToString(), sysSchedule.JobGroup).Build();
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(sysSchedule.IntervalSecond)
.RepeatForever()
)
.EndAt(sysSchedule.EndTime.Value)
.Build();
return trigger;
}
// 触发作业立即运行然后每10秒重复一次无限循环