CaiWuXiTong/app/Business/CourierSurchargeAuditLogRepository.php

152 lines
5.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Business;
use App\Models\Business\CourierSurchargeAuditLog;
use Illuminate\Database\QueryException;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Schema;
/**
* 快递附加费维护审计日志的固定入口。
*
* 日志只保存当前公司、操作人和报价/类型的安全字段快照,不保存密码、
* Token、连接串或原始请求内容。
*/
class CourierSurchargeAuditLogRepository
{
/** @var array<string,string> */
private const FIELD_LABELS = [
'courier' => '快递名称',
'scope' => '快递归属',
'reconciler' => '对账人',
'supplier' => '供应商',
'types' => '附加费类型',
'mode' => '结算方式',
'standard' => '计价标准',
'condition' => '生效条件',
'effective_at' => '生效日期',
'remark' => '备注',
'status' => '状态',
'name' => '类型名称',
];
/** @var array<string,string> */
private const ACTION_LABELS = [
CourierSurchargeAuditLog::ACTION_CREATED => '新增',
CourierSurchargeAuditLog::ACTION_UPDATED => '更改',
CourierSurchargeAuditLog::ACTION_ACTIVATED => '启用',
CourierSurchargeAuditLog::ACTION_DEACTIVATED => '停用',
];
/** @var array<string,string> */
private const TARGET_LABELS = [
CourierSurchargeAuditLog::TARGET_QUOTE => '报价规则',
CourierSurchargeAuditLog::TARGET_TYPE => '附加费类型',
];
public function ready(): bool
{
try {
return Schema::hasTable((new CourierSurchargeAuditLog())->getTable());
} catch (QueryException) {
return false;
}
}
/** @param array<string,mixed> $changes */
public function record(
string $action,
string $targetType,
?int $targetId,
string $targetLabel,
array $changes,
int $actorId,
): CourierSurchargeAuditLog {
abort_unless($this->ready(), 503, '附加费操作日志数据表尚未完成迁移。');
abort_unless(array_key_exists($action, self::ACTION_LABELS), 422, '附加费日志动作不合法。');
abort_unless(array_key_exists($targetType, self::TARGET_LABELS), 422, '附加费日志对象不合法。');
return CourierSurchargeAuditLog::query()->create([
'company_id' => company_id(),
'actor_id' => $actorId ?: null,
'action' => $action,
'target_type' => $targetType,
'target_id' => $targetId,
'target_label' => mb_substr(trim($targetLabel), 0, 191),
'changes' => $changes,
]);
}
/**
* @return Collection<int,array<string,mixed>>
*/
public function recent(int $limit = 50): Collection
{
if (! $this->ready()) {
return collect();
}
try {
return CourierSurchargeAuditLog::query()
->with('actor')
->orderByDesc('id')
->limit(max(1, min($limit, 200)))
->get()
->map(fn (CourierSurchargeAuditLog $log): array => [
'id' => $log->id,
'occurred_at' => optional($log->created_at)->format('Y-m-d H:i:s') ?: '',
'actor_name' => $log->actor?->name ?: '系统',
'action' => $log->action,
'action_label' => self::ACTION_LABELS[$log->action] ?? $log->action,
'target_type' => $log->target_type,
'target_id' => $log->target_id,
'target_type_label' => self::TARGET_LABELS[$log->target_type] ?? $log->target_type,
'target_label' => $log->target_label,
'changes_label' => $this->changesLabel($log),
])
->values();
} catch (QueryException) {
return collect();
}
}
private function changesLabel(CourierSurchargeAuditLog $log): string
{
$changes = (array) $log->changes;
if ($log->action === CourierSurchargeAuditLog::ACTION_CREATED) {
return '新增记录';
}
if (in_array($log->action, [CourierSurchargeAuditLog::ACTION_ACTIVATED, CourierSurchargeAuditLog::ACTION_DEACTIVATED], true)) {
$before = data_get($changes, 'before.status');
$after = data_get($changes, 'after.status');
return sprintf('状态:%s → %s', $before ?: '—', $after ?: '—');
}
$before = (array) ($changes['before'] ?? []);
$after = (array) ($changes['after'] ?? []);
$parts = [];
foreach (array_unique(array_merge(array_keys($before), array_keys($after))) as $field) {
$old = $this->valueLabel($before[$field] ?? null);
$new = $this->valueLabel($after[$field] ?? null);
if ($old !== $new) {
$parts[] = sprintf('%s:%s → %s', self::FIELD_LABELS[$field] ?? $field, $old, $new);
}
}
return $parts === [] ? '未改变字段' : implode(';', $parts);
}
private function valueLabel(mixed $value): string
{
if (is_array($value)) {
return implode('、', array_map(static fn (mixed $item): string => (string) $item, $value));
}
$value = trim((string) $value);
return $value === '' ? '—' : $value;
}
}