From 16ad80f2a84dc39b931a81579854fad0c8bd186c Mon Sep 17 00:00:00 2001
From: glz <694770232@qq.com>
Date: Tue, 23 Jun 2026 16:53:18 +0800
Subject: [PATCH] =?UTF-8?q?refactor(work-service):=20=E9=87=8D=E6=9E=84?=
=?UTF-8?q?=E8=87=AA=E5=8A=A8=E9=93=BA=E7=A0=81=E6=B6=88=E8=B4=B9=E8=80=85?=
=?UTF-8?q?=EF=BC=8C=E6=96=B0=E5=A2=9E=E5=BE=AE=E4=BF=A1=E7=99=BB=E5=BD=95?=
=?UTF-8?q?=E9=80=BB=E8=BE=91=E4=B8=8E=E9=85=8D=E7=BD=AE=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
1. 更新微信公众号配置AppId和AppSecret
2. 修复微信授权控制器临时返回逻辑,启用真实登录流程
3. 新增期刊打印DTO类,定义铺码数据结构
4. 重构AutoDotCodeConsumer,新增依赖注入与完整铺码业务逻辑
5. 调整队列消费者接口与实现,添加取消令牌参数
6. 新增铺码回调响应实体类,完善异常处理与事务管理
---
.../Dto/Journal/JournalPagePrintDto.cs | 42 +++
.../WeChat/WeChatAuthController.cs | 5 +-
.../appsettings.json | 4 +-
.../Consumers/AutoDotCodeConsumer.cs | 324 +++++++++++++++++-
.../Consumers/IQueueConsumer.cs | 2 +-
.../Consumers/JournalTaskReceiveConsumer.cs | 2 +-
.../Consumers/RabbitMQHostedService.cs | 2 +-
7 files changed, 361 insertions(+), 20 deletions(-)
create mode 100644 QYZH.InteractiveMagazine.Models/Dto/Journal/JournalPagePrintDto.cs
diff --git a/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalPagePrintDto.cs b/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalPagePrintDto.cs
new file mode 100644
index 0000000..22b8e0a
--- /dev/null
+++ b/QYZH.InteractiveMagazine.Models/Dto/Journal/JournalPagePrintDto.cs
@@ -0,0 +1,42 @@
+using QYZH.InteractiveMagazine.Models.Enum;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace QYZH.InteractiveMagazine.Models.Dto.Journal
+{
+ public class JournalPagePrintDto
+ {
+ ///
+ /// 书Id
+ ///
+ public long JournalId { get; set; }
+
+ ///
+ /// 状态
+ ///
+ public JournalStatusEnum? Status { get; set; }
+
+ ///
+ /// 书PDF URL(这里带有 OSS 域名 https://oss.qyzhjy.com/)
+ ///
+ public string? JournalPdfUrl { get; set; }
+
+ ///
+ /// 页码数组
+ ///
+ public int[] PageNum { get; set; } = [];
+
+ ///
+ /// 点阵码打印页面数组
+ ///
+ public string[] PageNo { get; set; } = [];
+
+ ///
+ /// 下载书页PDF的文件名,铺码程序已经添加好(这里带有 OSS 域名 https://oss.qyzhjy.com/)
+ ///
+ public string? DownloadJournalPagePdfName { get; set; }
+ }
+}
diff --git a/QYZH.InteractiveMagazine.WebApi/Controllers/WeChat/WeChatAuthController.cs b/QYZH.InteractiveMagazine.WebApi/Controllers/WeChat/WeChatAuthController.cs
index 3c82d15..3e0bcae 100644
--- a/QYZH.InteractiveMagazine.WebApi/Controllers/WeChat/WeChatAuthController.cs
+++ b/QYZH.InteractiveMagazine.WebApi/Controllers/WeChat/WeChatAuthController.cs
@@ -33,9 +33,8 @@ public class WeChatAuthController : WeChatBaseController
{
try
{
- //var result = await _weChatAuthService.LoginAsync(input);
- //return Success(result);
- return BaseResponse.Fail("微信登录失败,请稍后重试");
+ var result = await _weChatAuthService.LoginAsync(input);
+ return Success(result);
}
catch (BusinessException ex)
{
diff --git a/QYZH.InteractiveMagazine.WebApi/appsettings.json b/QYZH.InteractiveMagazine.WebApi/appsettings.json
index daf9305..c2f66a5 100644
--- a/QYZH.InteractiveMagazine.WebApi/appsettings.json
+++ b/QYZH.InteractiveMagazine.WebApi/appsettings.json
@@ -22,8 +22,8 @@
"ClientProvidedName": "Custom connection name"
},
"WeChatSettings": {
- "AppId": "wx7922cc9b6023f3ac",
- "AppSecret": "95a1d61b7be03d1dab81fe19b7483dcf"
+ "AppId": "wx5d8f281c2fd6594c",
+ "AppSecret": "974f45e4a0aaa075278db0477d0bd8b6"
},
"Serilog": {
"MinimumLevel": {
diff --git a/QYZH.InteractiveMagazine.WorkService/Consumers/AutoDotCodeConsumer.cs b/QYZH.InteractiveMagazine.WorkService/Consumers/AutoDotCodeConsumer.cs
index 46da0a2..19f5126 100644
--- a/QYZH.InteractiveMagazine.WorkService/Consumers/AutoDotCodeConsumer.cs
+++ b/QYZH.InteractiveMagazine.WorkService/Consumers/AutoDotCodeConsumer.cs
@@ -1,18 +1,26 @@
+using Newtonsoft.Json;
+using QYZH.InteractiveMagazine.Infrastructure.OSS;
+using QYZH.InteractiveMagazine.Models.Dto.Journal;
+using QYZH.InteractiveMagazine.Models.Entity;
+using QYZH.InteractiveMagazine.Models.Enum;
+using SqlSugar;
+using System.Diagnostics;
+using System.Net;
using System.Text;
+using System.Threading.Channels;
namespace QYZH.InteractiveMagazine.WorkService.Consumers;
///
/// 自动铺码消费者
///
-public class AutoDotCodeConsumer : IQueueConsumer
+public class AutoDotCodeConsumer(IConfiguration configuration,
+ IServiceScopeFactory scopeFactory,
+ ILogger logger,
+ IHttpClientFactory httpClientFactory,
+ OssService ossService
+ ) : IQueueConsumer
{
- private readonly ILogger _logger;
-
- public AutoDotCodeConsumer(ILogger logger)
- {
- _logger = logger;
- }
public string Exchange => "ex.journal";
@@ -20,20 +28,312 @@ public class AutoDotCodeConsumer : IQueueConsumer
public string RoutingKey => "rk.journal.dotcode.auto";
- public async Task HandleAsync(byte[] message)
+ public async Task HandleAsync(byte[] body, CancellationToken cancellationToken = default)
{
- var body = Encoding.UTF8.GetString(message);
- _logger.LogInformation("收到自动铺码消息: {Message}", body);
+ var message = Encoding.UTF8.GetString(body);
+ logger.LogInformation("收到自动铺码消息: {Message}", message);
// TODO: 在此编写具体的铺码处理逻辑
+ using var scope = scopeFactory.CreateScope();
+ var dBContext = scope.ServiceProvider.GetRequiredService();
+ try
+ {
+ var journalPagePrintDtoMessage = JsonConvert.DeserializeObject(message);
+ if (journalPagePrintDtoMessage == null)
+ return;
+
+ await dBContext.Ado.BeginTranAsync();
+
+ #region 创建文件夹以及下载PDF文件
+
+ var currentDomainDic = AppDomain.CurrentDomain.BaseDirectory + "JournalPagePdf";
+ if (!Directory.Exists(currentDomainDic))
+ Directory.CreateDirectory(currentDomainDic);
+
+ var uploadPdfDic = currentDomainDic + "/upload/";
+ if (!Directory.Exists(uploadPdfDic))
+ Directory.CreateDirectory(uploadPdfDic);
+
+ var downloadDic = currentDomainDic + "/download/";
+ if (!Directory.Exists(downloadDic))
+ Directory.CreateDirectory(downloadDic);
+
+ var uploadFileName = $"upload_{journalPagePrintDtoMessage.JournalId}_{DateTime.Now:yyyyMMddHHmmssffffff}{Random.Shared.Next(1000, 9999)}.pdf";
+
+ var uploadFilePath = uploadPdfDic + uploadFileName;
+
+ // 获取上传成功的书籍页码pdf文件
+ var pdfSteam = await httpClientFactory.CreateClient().GetStreamAsync(journalPagePrintDtoMessage.JournalPdfUrl, cancellationToken);
+
+ await using (var fs = new FileStream(uploadFilePath, FileMode.CreateNew, FileAccess.Write))
+ {
+ await pdfSteam.CopyToAsync(fs, cancellationToken);
+ logger.LogInformation($" 获取书籍上传的PDF文件成功下载到本地,长度为:{fs.Length}");
+ }
+
+ #endregion
+
+
+ #region 调用铺码程序
+
+ // 从配置中获取点阵文件Id
+ var dotId = configuration.GetValue("PrintConfig:DotId", 683790963662917);
+
+ var dotfile = await dBContext.Queryable().FirstAsync(x => x.Id == dotId, cancellationToken);
+ if (dotfile == null)
+ {
+ logger.LogError($"配置打印数据错误,点阵文件不存在,dotId: {dotId}");
+ return;
+ }
+
+ var exePath = AppDomain.CurrentDomain.BaseDirectory + "PrintToolV2.7\\PrintTool.exe";
+
+ var xmlPath = AppDomain.CurrentDomain.BaseDirectory + $"PrintToolV2.7\\{dotfile.FileName}";
+
+
+ #region 注释说明
+
+ //1、-sMode = Generate (必须)
+ //2、-sPDF = 源文件pdf格式的完整路径(必须)
+ //3、-sLIC = 铺码资源文件完整路径(必须)
+ //4、-oPDF = 生成pdf文件的完整路径(必须)
+ //5、-dType = 点阵形状,0:方点,1:圆点,默认为0(可选)
+ //6、-dPrint = 打印场景,0:普通激光打印机,1:工业印刷,默认为0(可选)
+ //7、-pStart = 数字,整数,可以制定资源文件从第几个编号开始铺码(非必须,默认0,表示从资源的剩余页码开始,每次铺码成功后点阵资源会相应减少;大于0时点阵资源不会减少,pStart = 1时表示从第一页开始铺码)
+ //8、-dPageAddr = 是否显示点阵页码地址,0:不显示,1:显示,默认为0(可选)
+ //9、-sPrinter = 打印机名称(必须)
+ //10、-dPageStart = 数字,设置打印起始页码,1表示从第一页开始打印,0:全部打印,默认0(可选)
+ //11、-dPageEnd = 数字,设置打印结束页码,0:全部打印,默认0(可选)
+ //12、-dCopy = 数字,设置打印份数,默认1(可选)
+ //13、-dKValue = 数字,设置码点颜色深度,取值范围50 - 100,默认100,比如取值90表示k值为90 %(可选)
+ //14、-dDotSize = 数字,设置码点大小,取值范围30 - 50,默认40(可选),方点仅支持40
+ //15、-dOutFile = 数字,0:只生成带点阵pdf文件,1:只生成纯点阵文件,2:既生成纯点阵文件也生成带点阵pdf文件,默认为0(可选)
+
+ //16、-dControlPageNum ={ [页地址, 连续数量],[页地址, 连续数量]...}
+ //可一个pdf有多段页码段,默认从第一页开始(可选)(最后一段若是不想数pdf剩下多少页,可直接放0默认用最后字段铺完剩下的页)
+
+ //说明:
+ //当 -dOutFile = 2时,纯点阵文件名为输入的 - oPDF参数,带点阵pdf文件名为在 - oPDF参数后加上"_dp",即"D:\pdf\28_dot_dp.pdf"。
+
+ //示例:
+ //制作点阵:
+ //-sMode=Generate -sPDF="D:\pdf\28.pdf" -sLIC="D:\Root licnese segment 70_70.0.0.0_100.xml" -oPDF="D:\pdf\28_dot.pdf" -pStart=1
+
+ //制作纯点阵文件:
+ //-sMode=Generate -sPDF="D:\pdf\28.pdf" -sLIC="D:\Root licnese segment 70_70.0.0.0_100.xml" -oPDF="D:\pdf\28_dot.pdf" -dOutFile=1
+
+ //打印:
+ //-sMode=Print -sPDF="D:\pdf\28_dot.pdf" -sPrinter="HP LaserJet Professional M1216nfh MFP (副本 1)" -dPageStart=2 -dPageEnd=3 -dCopy=5
+
+ #endregion
+
+ var downloadFileName = $"download_{journalPagePrintDtoMessage.JournalId}_{DateTime.Now:yyyyMMddHHmmssffffff}{Random.Shared.Next(1000, 9999)}_dot.pdf";
+
+ // 生成成功的PDF文件路径
+ var downloadFilePath = downloadDic + downloadFileName;
+
+ // -dPrint = 打印场景,0:普通激光打印机,1:工业印刷,默认为0(可选)
+ var dPrint = configuration.GetValue("PrintConfig:DPrint", 0);
+
+ // 获取书籍页码中的最大页数,作为铺码程序需要铺的页数(连续数量)
+ var pageNumMax = journalPagePrintDtoMessage.PageNum.Max(x => x);
+
+ // 根据点阵文件Id获取对应的页码详情列表,按照Id升序排序,取前N条(N为书籍页数)
+ var dotFileDetailList = await dBContext.Queryable().Where(x => x.DotId == dotId && !x.IsUse).OrderBy(x => x.Id).Take(pageNumMax).ToListAsync(cancellationToken);
+
+ // 获取页码详情列表中的页地址,组成一个数组
+ var dotFileDetailPageName = dotFileDetailList.Select(x => x.PageName).OrderBy(x => x).ToArray();
+
+ // -dControlPageNum ={ [页地址, 连续数量],[页地址, 连续数量]...}
+ // string pageStr = "{" + string.Join(",", item.Pages.Select(s => $"[{s.PageAddress},{s.PageNum}]")) + "}";
+
+ // 从第一个开始执行,连续铺码N条(N为书籍页数)
+ string pageStr = "{" + $"[{dotFileDetailList[0].PageName},{pageNumMax}]" + "}";
+
+ var cmd = $"PrintTool.exe -sMode=Generate -sPDF={uploadFilePath} -sLIC={xmlPath} -pStart=1 -oPDF={downloadFilePath} -dPageAddr=1 -dPrint={dPrint} -dDotSize=40 -dType=0 -dOutFile=0 -dControlPageNum={pageStr}";
+
+ logger.LogInformation($"执行PrintTool.exe 的命令: {cmd}");
+
+ string output;
+ using (var p = new Process())
+ {
+ p.StartInfo = new ProcessStartInfo
+ {
+ WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory + "PrintToolV2.7",
+ FileName = "cmd.exe",
+ Arguments = "/c " + cmd, // /c参数表示执行后关闭
+ UseShellExecute = false, //是否使用操作系统shell启动
+ RedirectStandardInput = true, //接受来自调用程序的输入信息
+ RedirectStandardOutput = true, //由调用程序获取输出信息
+ RedirectStandardError = true, //重定向标准错误输出
+ CreateNoWindow = true, //不显示程序窗口
+ };
+
+ p.Start();
+ output = await p.StandardOutput.ReadToEndAsync(cancellationToken);
+
+ logger.LogInformation("执行 ProcessStartInfo 执行命令后,output 输出值:{Output}", output);
+
+ var exeErrorMsg = await p.StandardError.ReadToEndAsync(cancellationToken);
+ if (!string.IsNullOrWhiteSpace(exeErrorMsg))
+ {
+ logger.LogInformation($"执行 ProcessStartInfo 执行命令后,返回的错误信息为:{exeErrorMsg}");
+ }
+
+ await p.WaitForExitAsync(cancellationToken);
+ p.Kill();
+ }
+ logger.LogInformation("执行 PrintTool.exe 文件成功");
+
+ #endregion
+
+ var journalPagePrintDtoModel = new JournalPagePrintDto
+ {
+ JournalId = journalPagePrintDtoMessage.JournalId,
+ PageNo = dotFileDetailPageName,
+ };
+
+ #region 根据配置的dPrint 验证铺码程序执行的结果 output数据
+
+ if (string.IsNullOrWhiteSpace(output))
+ {
+ logger.LogInformation("执行铺码程序没有任何输出,请联系管理员");
+ journalPagePrintDtoModel.Status = JournalStatusEnum.CodeFail;
+ await ExecuteUpdateJournalStatus(journalPagePrintDtoModel, dBContext);
+ return;
+ }
+
+ // 如果是激光打印场景,output肯定和 dotFileDetailPageName 是一一对应的关系,如果是工业印刷场景,output可能会有其他信息,所以需要验证output中是否包含dotFileDetailPageName中的页码
+ if (dPrint == 0)
+ {
+ var pageNoList = JsonConvert.DeserializeObject(output) ?? [];
+ var isequalArray = pageNoList.OrderBy(x => x).SequenceEqual(dotFileDetailPageName.OrderBy(x => x), StringComparer.Ordinal);
+ if (!isequalArray)
+ {
+ logger.LogInformation("执行铺码程序输出的页码与期望的页码不一致,请联系管理员");
+ journalPagePrintDtoModel.Status = JournalStatusEnum.CodeFail;
+ await ExecuteUpdateJournalStatus(journalPagePrintDtoModel, dBContext);
+ return;
+ }
+
+ }
+ else if (dPrint == 1)// 如果是工业印刷场景,验证页码是否打印过,如果打印过则直接使用原来的页码,不再执行铺码程序
+ {
+ // 并行验证页码是否存在于铺码程序的输出中,存在则说明打印过,不存在则说明没有打印过,说明铺码程序没有执行成功
+ var existPageNo = dotFileDetailPageName.AsParallel().Any(ip => output.Contains(ip, StringComparison.Ordinal));
+ if (!existPageNo)
+ {
+ logger.LogInformation("执行铺码程序没有任何输出,请联系管理员");
+ journalPagePrintDtoModel.Status = JournalStatusEnum.CodeFail;
+ await ExecuteUpdateJournalStatus(journalPagePrintDtoModel, dBContext);
+ return;
+ }
+ }
+
+ #endregion
+
+ #region 把本地文集上传到OOS上
+
+ var tempOssDownloadKey = "BookPagePdf/download/" + downloadFileName;
+
+ const int bufferSize = 1 * 1024 * 1024; // 1MB
+
+ await using var downloadFs = new FileStream(downloadFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize, FileOptions.SequentialScan | FileOptions.Asynchronous);
+
+ //把本地文件上传到OOS上
+ var downloadBookPagePdfName = ossService.PutObject(tempOssDownloadKey, downloadFs);
+
+ var ossDomain = configuration.GetSection("AliyunOSSConfigs:Domain").Get() ?? string.Empty;
+
+ journalPagePrintDtoModel.DownloadJournalPagePdfName = ossDomain + downloadBookPagePdfName;
+
+ // 这里一定要释放上面的流,否则下面无法删除文件
+ await downloadFs.DisposeAsync();
+
+ #endregion
+
+ ////删除临时文件
+ File.Delete(uploadFilePath);
+
+ File.Delete(downloadFilePath);
+
+ #region 调用API,成功后修改页码状态为已使用
+
+ journalPagePrintDtoModel.Status = JournalStatusEnum.CodeSuccess;
+
+ // 调用回调接口修改书籍状态为铺码成功
+ var callbackResponse = await ExecuteUpdateJournalStatus(journalPagePrintDtoModel, dBContext);
+
+ if (callbackResponse != null && callbackResponse.IsSuccess)
+ {
+ logger.LogInformation($"回调接口成功修改书籍状态为铺码成功,书籍ID:{journalPagePrintDtoModel.JournalId}");
+
+ foreach (var dotFileDetail in dotFileDetailList)
+ {
+ dotFileDetail.IsUse = true;
+ dotFileDetail.UpdatedAt = DateTime.Now;
+ }
+
+ await dBContext.Updateable(dotFileDetailList).ExecuteCommandAsync();
+
+ await dBContext.Updateable()
+ .SetColumns(x => x.TotalUse == x.TotalUse + dotFileDetailList.Count)
+ .SetColumns(x => x.UpdatedAt == DateTime.Now)
+ .Where(x => x.Id == dotId).ExecuteCommandAsync();
+
+ ////手动确认消息已处理(由于下方 autoAck 设为 false)
+ //await channel.BasicAckAsync(deliveryTag: ea.DeliveryTag, multiple: false, cancellationToken: cancellationToken);
+ }
+ else
+ {
+ logger.LogError($"回调接口修改书籍状态为铺码成功没有成功,书籍ID:{journalPagePrintDtoModel.JournalId},接口返回消息:{callbackResponse?.Message}");
+ }
+
+ #endregion
+
+
+ await dBContext.Ado.CommitTranAsync();
+
+ }
+ catch (Exception ex)
+ {
+ await dBContext.Ado.RollbackTranAsync();
+ logger.LogError(ex, "铺码错误,回调接口修改书籍状态为铺码失败没有成功");
+ }
await Task.CompletedTask;
}
-
+ private async Task ExecuteUpdateJournalStatus(JournalPagePrintDto request, ISqlSugarClient dBContext)
+ {
+ var client = httpClientFactory.CreateClient();
+ var callbackUrl = configuration.GetValue("PrintConfig:CallBackApiUrl");
+ var callbackRequest = new HttpRequestMessage(HttpMethod.Post, callbackUrl)
+ {
+ Content = new StringContent(JsonConvert.SerializeObject(request), Encoding.UTF8, "application/json")
+ };
+ var response = await client.SendAsync(callbackRequest);
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ var responseContent = await response.Content.ReadAsStringAsync();
+ logger.LogInformation($"回调接口成功修改书籍状态为铺码失败,接口返回内容:{responseContent}");
+ return JsonConvert.DeserializeObject(responseContent) ?? new CallbackUpdateJournalStatusResponse();
+ }
+ return new CallbackUpdateJournalStatusResponse();
+ }
public Task OnErrorAsync(byte[] message, Exception exception)
{
var body = Encoding.UTF8.GetString(message);
- _logger.LogError(exception, "处理自动铺码消息失败: {Message}", body);
+ logger.LogError(exception, "处理自动铺码消息失败: {Message}", body);
return Task.CompletedTask;
}
}
+internal class CallbackUpdateJournalStatusResponse
+{
+ public string? Message { get; set; }
+
+ public string? Code { get; set; }
+
+ public bool Result { get; set; }
+
+ public bool IsSuccess { get; set; }
+}
\ No newline at end of file
diff --git a/QYZH.InteractiveMagazine.WorkService/Consumers/IQueueConsumer.cs b/QYZH.InteractiveMagazine.WorkService/Consumers/IQueueConsumer.cs
index 974474c..d047f51 100644
--- a/QYZH.InteractiveMagazine.WorkService/Consumers/IQueueConsumer.cs
+++ b/QYZH.InteractiveMagazine.WorkService/Consumers/IQueueConsumer.cs
@@ -23,7 +23,7 @@ public interface IQueueConsumer
///
/// 处理消息
///
- Task HandleAsync(byte[] message);
+ Task HandleAsync(byte[] message, CancellationToken cancellationToken = default);
///
/// 处理消费异常
diff --git a/QYZH.InteractiveMagazine.WorkService/Consumers/JournalTaskReceiveConsumer.cs b/QYZH.InteractiveMagazine.WorkService/Consumers/JournalTaskReceiveConsumer.cs
index 8dff60e..5f76e8d 100644
--- a/QYZH.InteractiveMagazine.WorkService/Consumers/JournalTaskReceiveConsumer.cs
+++ b/QYZH.InteractiveMagazine.WorkService/Consumers/JournalTaskReceiveConsumer.cs
@@ -20,7 +20,7 @@ public class JournalTaskReceiveConsumer : IQueueConsumer
public string RoutingKey => "rk.journal.task.receive";
- public async Task HandleAsync(byte[] message)
+ public async Task HandleAsync(byte[] message, CancellationToken cancellationToken = default)
{
var body = Encoding.UTF8.GetString(message);
_logger.LogInformation("收到期刊任务消息: {Message}", body);
diff --git a/QYZH.InteractiveMagazine.WorkService/Consumers/RabbitMQHostedService.cs b/QYZH.InteractiveMagazine.WorkService/Consumers/RabbitMQHostedService.cs
index 3aef0a4..12ec068 100644
--- a/QYZH.InteractiveMagazine.WorkService/Consumers/RabbitMQHostedService.cs
+++ b/QYZH.InteractiveMagazine.WorkService/Consumers/RabbitMQHostedService.cs
@@ -60,7 +60,7 @@ public class RabbitMQHostedService : BackgroundService
try
{
- await consumer.HandleAsync(ea.Body.ToArray());
+ await consumer.HandleAsync(ea.Body.ToArray(), stoppingToken);
await channel.BasicAckAsync(ea.DeliveryTag, false, stoppingToken);
}
catch (Exception ex)