补齐源快照、资料预演、正式导入及工资核算的依赖链路。 新增版本化输入、逐段 FIFO、生成锁和结构化当月调整, 并提供默认关闭的周期采集、有限重试及 Windows 托管。 原始客户资料、私有配置及首页改动不纳入本次提交。 BREAKING CHANGE: 升级前需应用新增迁移,并通过 PAYROLL_MAKER_USER_ID 绑定实际工资制作人,否则业务只读。 旧单批次核算默认关闭;历史兼容需显式启用 PAYROLL_ALLOW_LEGACY_CALCULATION。生产启用和真实金额待验收。
64 lines
4.1 KiB
PowerShell
64 lines
4.1 KiB
PowerShell
[CmdletBinding(SupportsShouldProcess = $true)]
|
||
param(
|
||
[Parameter(Mandatory = $true)][ValidateSet('Check', 'Start', 'Stop')][string]$Action,
|
||
[Parameter(Mandatory = $true)][string]$RuntimeDirectory,
|
||
[switch]$Apply,
|
||
[switch]$Force,
|
||
[ValidateRange(0, 600)][int]$GraceSeconds = 30
|
||
)
|
||
. (Join-Path $PSScriptRoot 'TaskHost.Common.ps1')
|
||
$runtime = [IO.Path]::GetFullPath($RuntimeDirectory)
|
||
$manifest = Join-Path $runtime 'task-manifest.json'
|
||
if (-not (Test-Path -LiteralPath $manifest -PathType Leaf)) { throw '未找到项目安装清单,拒绝管理其他任务。' }
|
||
$saved = Get-Content -LiteralPath $manifest -Raw | ConvertFrom-Json
|
||
if (-not $saved.PSObject.Properties['ServiceSid'] -or -not $saved.PSObject.Properties['LogonType']) {
|
||
throw '安装清单缺少账号核验信息,请管理员核对后重新准备安装。'
|
||
}
|
||
$plan = Get-PayrollTaskPlan -ProjectRoot $saved.ProjectRoot -PythonPath $saved.PythonPath -RuntimeDirectory $runtime `
|
||
-ConnectionFile $saved.ConnectionFile -TaskPath $saved.TaskPath -ApiPort $saved.ApiPort
|
||
$tasks = foreach ($expected in $plan.Tasks) {
|
||
$actual = Get-ScheduledTask -TaskPath $plan.TaskPath -TaskName $expected.Name -ErrorAction Stop
|
||
Assert-PayrollTaskPrincipal -Actual $actual.Principal -Expected $saved
|
||
if (@($actual.Actions).Count -ne 1 -or $actual.Actions[0].Execute -ne $expected.Execute -or
|
||
$actual.Actions[0].Arguments -ne $expected.Arguments -or $actual.Actions[0].WorkingDirectory -ne $expected.WorkingDirectory) {
|
||
throw '任务动作与项目清单不一致,拒绝启动或停止。'
|
||
}
|
||
$info = Get-ScheduledTaskInfo -TaskPath $plan.TaskPath -TaskName $expected.Name
|
||
[pscustomobject]@{ Name = $expected.Name; State = [string]$actual.State;
|
||
LastTaskResult = $info.LastTaskResult; LastRunTime = $info.LastRunTime; NextRunTime = $info.NextRunTime;
|
||
SettingsValid = ($actual.Settings.MultipleInstances -eq 'IgnoreNew' -and $actual.Settings.RestartCount -eq 3 -and
|
||
$actual.Settings.RestartInterval -eq 'PT1M' -and $actual.Settings.ExecutionTimeLimit -eq 'PT0S') }
|
||
}
|
||
if ($Action -eq 'Check') {
|
||
[pscustomobject]@{ TaskPath = $plan.TaskPath; StopRequested = (Test-Path -LiteralPath $plan.StopFile); Tasks = @($tasks) } | ConvertTo-Json -Depth 4
|
||
if (@($tasks | Where-Object { -not $_.SettingsValid }).Count) { exit 1 }
|
||
exit 0
|
||
}
|
||
if (-not $Apply -or -not $PSCmdlet.ShouldProcess($plan.TaskPath, $Action)) {
|
||
[pscustomobject]@{ Preview = $true; Action = $Action; TaskPath = $plan.TaskPath; Names = @($tasks.Name) } | ConvertTo-Json
|
||
return
|
||
}
|
||
if (@($tasks | Where-Object { -not $_.SettingsValid }).Count) { throw '任务恢复设置不符合交付约定,拒绝改变运行状态。' }
|
||
if ($Action -eq 'Start') {
|
||
Assert-PayrollHostAccess -Plan $plan -ServiceSid $saved.ServiceSid
|
||
if (Test-Path -LiteralPath $plan.StopFile) { Remove-Item -LiteralPath $plan.StopFile }
|
||
foreach ($task in $tasks) { Enable-ScheduledTask -TaskPath $plan.TaskPath -TaskName $task.Name | Out-Null; Start-ScheduledTask -TaskPath $plan.TaskPath -TaskName $task.Name }
|
||
Write-Output '托管任务已启动;是否自动排队仍由T_PLUS_AUTOMATION_ENABLED决定。'
|
||
} else {
|
||
'运维请求停止领取任务' | Set-Content -LiteralPath $plan.StopFile -Encoding UTF8
|
||
foreach ($task in $tasks) { Disable-ScheduledTask -TaskPath $plan.TaskPath -TaskName $task.Name | Out-Null }
|
||
$deadline = (Get-Date).AddSeconds($GraceSeconds)
|
||
do {
|
||
$running = @($tasks | Where-Object { (Get-ScheduledTask -TaskPath $plan.TaskPath -TaskName $_.Name).State -eq 'Running' })
|
||
if (-not $running.Count) { break }
|
||
Start-Sleep -Seconds 1
|
||
} while ((Get-Date) -lt $deadline)
|
||
if ($running.Count -and $Force) {
|
||
foreach ($task in $running) { Stop-ScheduledTask -TaskPath $plan.TaskPath -TaskName $task.Name }
|
||
Write-Output '已强制停止明确的项目任务;未结束的采集需在重启后人工核对中断记录。'
|
||
} elseif ($running.Count) {
|
||
Write-Output '已停止领取新任务,现有长采集尚在退出;未强制终止,可稍后Check。'
|
||
exit 2
|
||
} else { Write-Output '项目托管任务已停止。' }
|
||
}
|