\App\Services\AdminLogJobService

队列日志服务

职责:td_log_sys_job 台账的唯一写入口(投递侧 JobCenter 建账,执行侧 SystemJob 包装 + QueueLogSubscriber 事件兜底共同推进状态机),读侧提供分页筛选、 单条详情(敏感掩码)、监控统计与保留期清理。

状态机:0 待处理 →(领取) 1 处理中 →(execute 成功) 2 成功 1 处理中 →(异常且未耗尽重试) 0 待处理(Laravel 退避重投) 1 处理中 →(重试耗尽/致命) 3 失败(JobFailed 事件落) 0 待处理 →(界面取消) 4 取消(删除原生队列表对应行) 崩溃兜底:worker 被杀/超时 → 任务回队,下一次领取时发现上次尝试未闭合 → 补记「异常中断」。

┌────────────────── 分区导航(按此顺序阅读)──────────────────┐ 分区 1 · 投递建账 create / setUuid 分区 2 · 状态机推进 markProcessing / markSuccess / markAttemptFailed markFinalFailed / markCancelled 分区 3 · 查询与展示 paginate / show / presentPayload 分区 4 · 重投与取消 redispatch / cancel 分区 5 · 统计与清理 stats / prune 分区 6 · 内部辅助 closeLastAttempt / maskValue / errorOf └────────────────────────────────────────────────────────────┘

Summary

Methods
Properties
Constants
create()
setUuid()
markProcessing()
markSuccess()
markAttemptFailed()
markFinalFailed()
markCancelled()
paginate()
show()
presentListItem()
presentPayload()
redispatch()
cancel()
stats()
prune()
No public properties found
No constants found
scopeToVisible()
applySearch()
No protected properties found
N/A
closeLastAttempt()
errorOf()
payloadPreview()
maskValue()
No private properties found
N/A

Methods

create()

create(array  $data) : \App\Models\LogSysJob

建账:投递前写入一行待处理记录(载荷快照 + 来源上下文)。

Parameters

array $data

Returns

\App\Models\LogSysJob —

setUuid()

setUuid(int  $logId, string  $uuid) : void

回填 Laravel Job UUID(dispatch 后由队列层生成,关联原生队列表)

Parameters

int $logId
string $uuid

markProcessing()

markProcessing(int  $logId, int  $attempt) : void

标记处理中:领取时刻由 SystemJob 包装调用,JobProcessing 事件兜底重复调用。

幂等约定:最后一次尝试条目 attempt 相同且未闭合 → 已标记,跳过(包装与事件双路径防重复); 上次尝试未闭合(worker 崩溃/超时被杀)→ 补记「worker 异常中断」并闭合(崩溃兜底)。

Parameters

int $logId
int $attempt

markSuccess()

markSuccess(int  $logId, array  $result, float  $startedAtMicro) : void

标记成功:execute() 正常返回时由 SystemJob 包装调用;JobProcessed 事件兜底。 仅 0/1 态可推进(已失败/取消/成功的行不覆写)。

Parameters

int $logId
array $result
float $startedAtMicro

markAttemptFailed()

markAttemptFailed(int  $logId, \Throwable  $e, float  $startedAtMicro) : void

标记单次尝试失败:execute() 抛异常时由 SystemJob 包装调用。 未耗尽重试 → 状态回 0 等退避重投(Laravel release);耗尽 → 交 JobFailed 事件落终态。

Parameters

int $logId
\Throwable $e
float $startedAtMicro

markFinalFailed()

markFinalFailed(int  $logId, \Throwable  $e) : void

标记最终失败:Laravel 重试耗尽触发 JobFailed 事件时调用(Laravel 仅在最终失败时触发, 逐次失败由 markAttemptFailed 记录)。

Parameters

int $logId
\Throwable $e

markCancelled()

markCancelled(int  $logId) : void

标记取消:仅待处理可取消——删除原生队列表对应行(未领取才删得到)+ 台账落终态。

Parameters

int $logId

Throws

\InvalidArgumentException

非待处理状态不可取消

paginate()

paginate(array  $filters, int  $perPage) : \Illuminate\Contracts\Pagination\LengthAwarePaginator

分页查询(列表轻载荷:不含 payload/attempt_log 全量,含掩码后的内容摘要)。

Parameters

array $filters
int $perPage

Returns

\Illuminate\Contracts\Pagination\LengthAwarePaginator —

show()

show(int  $id, bool  $raw = false) : array

单条详情(含载荷内容,敏感字段按队列 schema 掩码;$raw=true 超管明文)

Parameters

int $id
bool $raw

Returns

array —

presentListItem()

presentListItem(\App\Models\LogSysJob  $log, ?\App\Models\SysJobType  $type, bool  $raw) : array

列表轻载荷行(不含全量 payload/attempt_log;载荷摘要按敏感掩码截断)

Parameters

\App\Models\LogSysJob $log
?\App\Models\SysJobType $type
bool $raw

Returns

array —

presentPayload()

presentPayload(?\App\Models\SysJobType  $type, array  $payload, bool  $raw = false) : array

载荷内容按队列 schema 敏感标记掩码(接口下发层;库内快照恒明文,审计不掩)。 $raw=true(超管)原样下发。

Parameters

?\App\Models\SysJobType $type
array $payload
bool $raw

Returns

array —

redispatch()

redispatch(int  $logId, ?int  $operatorId = null, ?string  $operatorName = null) : array

重新投递:复用载荷快照经 JobCenter 另立新行(parent_id 审计链,历史永不覆写)。

Parameters

int $logId
?int $operatorId
?string $operatorName

Returns

array —

cancel()

cancel(int  $logId) : void

取消待处理任务(状态机约束在 markCancelled 内)

Parameters

int $logId

stats()

stats() : array

监控页聚合:今日各状态计数 / 积压 / 各队列今日明细 / 近 7 日趋势 / 最近失败

Returns

array —

prune()

prune() : array

保留期清理:成功/失败(含取消)各按配置天数,界面「清理历史」与定时命令共用

Returns

array —

scopeToVisible()

scopeToVisible(\Illuminate\Database\Eloquent\Builder  $query, bool  $ownOnly = false) : void

日志数据范围(单源:登录/操作/拒绝/错误/队列五服务共用): ownOnly=true 恒为本人行(个人中心语义,超管同规,匿名行亦不可见); 否则非超管仅见本人行(user_id 为空的匿名行仅超管可见)。

Parameters

\Illuminate\Database\Eloquent\Builder $query
bool $ownOnly

applySearch()

applySearch(\Illuminate\Database\Eloquent\Builder  $query, mixed  $search, string[]  $columns) : void

多列模糊搜索(单源:日志分页 search 参数同构)。 空 search 直接跳过;命中任一列即返回(OR 语义,与既有行为一致)。

Parameters

\Illuminate\Database\Eloquent\Builder $query
mixed $search
string[] $columns

参与模糊匹配的列名

closeLastAttempt()

closeLastAttempt(array  $attemptLog, ?string  $error, ?array  $result, \Illuminate\Support\Carbon  $now, ?int  $durationMs) : array

闭合最后一条尝试(finished_at/duration/result/error),返回新数组

Parameters

array $attemptLog
?string $error
?array $result
\Illuminate\Support\Carbon $now
?int $durationMs

Returns

array —

errorOf()

errorOf(\Throwable  $e) : string

异常可读摘要(500 字符截断,超长仅作界面展示)

Parameters

\Throwable $e

Returns

string —

payloadPreview()

payloadPreview(\App\Models\LogSysJob  $log, ?\App\Models\SysJobType  $type, bool  $raw) : string

载荷摘要:掩码后 JSON 压缩截断(列表「内容摘要」列,详情见 show;截断读配置)

Parameters

\App\Models\LogSysJob $log
?\App\Models\SysJobType $type
bool $raw

Returns

string —

maskValue()

maskValue(string  $fieldType, string  $value) : string

敏感值掩码:邮箱/手机号部分可见,其余全掩(界面可辨类型不泄内容)

Parameters

string $fieldType
string $value

Returns

string —