feat: 新增打印任务相关功能并完善服务配置

1. 调整回调响应的Code字段类型为object以兼容更多返回值
2. 为JournalDto新增Url和QuestionNo属性
3. 为JournalPageTaskOutput新增Task字段并完善注释
4. 新增打印工作服务的发布、安装卸载脚本与README文档
5. 调整项目配置,添加运行时标识与资源拷贝配置
6. 优化程序启动逻辑,修复工作目录与日志路径问题
7. 简化日志配置,移除多余的Hangfire与AI配置项
8. 完善期刊删除逻辑,关联删除相关子数据
9. 新增期刊发布时的书页任务排序与回调地址补全逻辑
This commit is contained in:
glz
2026-07-01 10:56:18 +08:00
parent 87bc5c0e0c
commit eb4f09e391
12 changed files with 193 additions and 49 deletions

View File

@ -330,7 +330,7 @@ internal class CallbackUpdateJournalStatusResponse
{
public string? Message { get; set; }
public string? Code { get; set; }
public object? Code { get; set; }
public bool Result { get; set; }

View File

@ -5,21 +5,34 @@ using QYZH.InteractiveMagazine.PrintWorker.Consumers;
using Serilog;
using SqlSugar;
using SqlSugar.IOC;
using System.Text;
using Yitter.IdGenerator;
var builder = Host.CreateApplicationBuilder(args);
Directory.SetCurrentDirectory(AppContext.BaseDirectory);
var builder = Host.CreateApplicationBuilder(new HostApplicationBuilderSettings
{
Args = args,
ContentRootPath = AppContext.BaseDirectory
});
const string serviceName = "QYZH.InteractiveMagazine.PrintWorker";
builder.Configuration
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true, reloadOnChange: true);
var logDirectory = Path.Combine(AppContext.BaseDirectory, "logs");
Directory.CreateDirectory(logDirectory);
var logFilePath = Path.Combine(logDirectory, "printworker-log-.txt");
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(builder.Configuration)
.WriteTo.File(logFilePath, rollingInterval: RollingInterval.Day, encoding: Encoding.UTF8)
.Enrich.FromLogContext()
.CreateLogger();
builder.Services.AddSerilog();
builder.Services.AddWindowsService(options => options.ServiceName = "QYZH InteractiveMagazine PrintWorker");
builder.Services.AddWindowsService(options => options.ServiceName = serviceName);
YitIdHelper.SetIdGenerator(new IdGeneratorOptions { WorkerId = 3 });
@ -54,6 +67,6 @@ builder.Services.AddHostedService<RabbitMQHostedService>();
var app = builder.Build();
Log.Information("PrintWorker 已启动,仅消费自动铺码队列");
Log.Information("{ServiceName} 已启动,仅消费自动铺码队列", serviceName);
await app.RunAsync();

View File

@ -1,7 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<RuntimeIdentifiers>win-x64</RuntimeIdentifiers>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
@ -28,6 +30,12 @@
<None Include="PrintToolV2.7\**\*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="scripts\**\*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="README.md">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,30 @@
# PrintWorker Windows Service
## 发布
```powershell
cd C:\项目\QYZH.InteractiveMagazine\QYZH.InteractiveMagazine.PrintWorker
.\scripts\publish-win-x64.ps1
```
发布目录默认是 `.\publish\win-x64`,其中包含 `PrintToolV2.7``appsettings.json``QYZH.InteractiveMagazine.PrintWorker.exe`
## 安装服务
用管理员 PowerShell 执行:
```powershell
cd C:\Web\QYZH.InteractiveMagazine.PrintWorker
.\scripts\install-service.ps1
```
默认服务名:`QYZH.InteractiveMagazine.PrintWorker`
## 卸载服务
用管理员 PowerShell 执行:
```powershell
cd C:\项目\QYZH.InteractiveMagazine\QYZH.InteractiveMagazine.PrintWorker
.\scripts\uninstall-service.ps1
```

View File

@ -19,48 +19,15 @@
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning",
"Hangfire": "Information"
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "Console"
},
{
"Name": "File",
"Args": {
"path": "logs/worker-log-.txt",
"rollingInterval": "Day"
}
}
]
},
"HangfireJobs": {
"_说明": "定时任务配置。新增任务只需在 Jobs 数组中追加一项。Cron格式分 时 日 月 星期5位。常用* * * * * 每分钟 | */5 * * * * 每5分钟 | 0 * * * * 每小时 | 0 9 * * * 每天9点 | 0 0 * * 1 每周一午夜",
"Jobs": [
{
"Name": "sample-job",
"JobType": "QYZH.InteractiveMagazine.WorkService.Jobs.SampleJob",
"MethodName": "ExecuteAsync",
"Cron": "* * * * *",
"Enabled": false,
"Description": "示例任务(默认关闭,仅用于验证框架运行)"
}
]
},
"AiChat": {
"ApiKey": "Ollama",
"BaseUrl": "http://172.16.10.130:11434/v1/",
"Model": "qwen2.5vl:7b",
"TimeoutSeconds": 300,
"MaxTokens": 2000,
"Temperature": 0.5,
"ScoreMaxRetryCount": 3,
"ScoreRetryDelayMilliseconds": 1000,
"MaxImageBytes": 10485760
},
"AllowedHosts": "*",
"AliyunOSSConfigs": {
"AccessKeyID": "LTAI5tEBXGewpHSLiSxyx6Bf",
"AccessKeySecret": "w29b8wkw6XQVL8GWXgp3ZesgYeDKvf",
@ -68,18 +35,15 @@
"BucketName": "qyzh2025test",
"Region": "beijing",
"RoleArn": "acs:ram::1064745380176636:role/aliyunosstokengeneratorrole",
"DurationSeconds": 3600, //过期时间(秒)
"DurationSeconds": 3600,
"Endpoint": "oss-cn-beijing.aliyuncs.com",
"ProjectName": "InteractiveMagazine",
"Domain": "http://oss-test.qyzhjy.com/"
},
"PrintConfig": {
"TimeoutSeconds": 300,
"DPrint": 0, //打印场景0普通激光打印机1工业印刷默认为0可选
"CallBackApiUrl": "http://localhost:8080/api/page/callbackupdatepageno", // 开发环境 打印成功回调API地址修改打印状态
//"CallBackApiUrl": "http://192.168.20.150:8000/api/icr/page/callbackupdatepageno", // 测试环境 打印成功回调API地址修改打印状态
//"CallBackApiUrl": "https://zyb.qyzhjy.com/zybback/api/icr/page/callbackupdatepageno", // 正式环境 打印成功回调API地址修改打印状态
//这个ID执行的xml文件是sublic_license_1761.172.8.16_1000.xml如果想执行sublic_license_1761.211.21.48_10000.xml 换成 765837655859269 ---暂时没有导入页码
"DPrint": 0,
"CallBackApiUrl": "http://localhost:8080/api/page/callbackupdatepageno",
"DotId": 765837655859269
}
}

View File

@ -0,0 +1,35 @@
param(
[string]$ServiceName = "QYZH.InteractiveMagazine.PrintWorker",
[string]$DisplayName = "QYZH InteractiveMagazine PrintWorker",
[string]$Description = "InteractiveMagazine automatic dot-code print worker.",
[string]$PublishPath = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path
)
$ErrorActionPreference = "Stop"
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
throw "Please run this script in an elevated PowerShell window."
}
$exePath = Resolve-Path (Join-Path $PublishPath "QYZH.InteractiveMagazine.PrintWorker.exe")
$existing = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($existing) {
if ($existing.Status -ne "Stopped") {
Stop-Service -Name $ServiceName -Force
$existing.WaitForStatus("Stopped", "00:00:30")
}
sc.exe delete $ServiceName | Out-Null
Start-Sleep -Seconds 2
}
New-Service `
-Name $ServiceName `
-BinaryPathName "`"$exePath`"" `
-DisplayName $DisplayName `
-Description $Description `
-StartupType Automatic
Start-Service -Name $ServiceName
Get-Service -Name $ServiceName

View File

@ -0,0 +1,28 @@
param(
[string]$Configuration = "Release",
[string]$Output = ".\publish\win-x64",
[switch]$SelfContained
)
$ErrorActionPreference = "Stop"
$projectPath = Join-Path $PSScriptRoot "..\QYZH.InteractiveMagazine.PrintWorker.csproj"
$publishArgs = @(
"publish",
$projectPath,
"-c", $Configuration,
"-r", "win-x64",
"-o", $Output
)
if ($SelfContained) {
$publishArgs += "--self-contained"
$publishArgs += "true"
} else {
$publishArgs += "--self-contained"
$publishArgs += "false"
}
dotnet @publishArgs
Write-Host "PrintWorker published to: $Output"

View File

@ -0,0 +1,23 @@
param(
[string]$ServiceName = "QYZH.InteractiveMagazine.PrintWorker"
)
$ErrorActionPreference = "Stop"
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
throw "Please run this script in an elevated PowerShell window."
}
$existing = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if (-not $existing) {
Write-Host "Service not found: $ServiceName"
return
}
if ($existing.Status -ne "Stopped") {
Stop-Service -Name $ServiceName -Force
$existing.WaitForStatus("Stopped", "00:00:30")
}
sc.exe delete $ServiceName | Out-Null
Write-Host "Service deleted: $ServiceName"