| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- <?php
- namespace App\Services;
- use App\Support\LocalizedContent;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Validator;
- use Illuminate\Validation\Rule;
- class LocalizedAuditService
- {
- public static function listing(string $type, array $input, ?callable $scope = null): array
- {
- $params = Validator::make($input, [
- 'page' => ['nullable', 'integer', 'min:1'], 'limit' => ['nullable', 'integer', 'min:1', 'max:200'],
- 'language' => ['nullable', Rule::in(array_keys(LocalizedContent::LANGUAGES))],
- 'operator_name' => ['nullable', 'string', 'max:100'], 'resource_id' => ['nullable', 'integer', 'min:1'],
- 'start_date' => ['nullable', 'required_with:end_date', 'date_format:Y-m-d'],
- 'end_date' => ['nullable', 'required_with:start_date', 'date_format:Y-m-d', 'after_or_equal:start_date'],
- ])->validate();
- $query = DB::table('operation_audits as a')->where('a.resource_type', $type);
- if ($scope) $scope($query);
- if (isset($params['operator_name']) && $params['operator_name'] !== '') $query->where('a.operator_name', 'like', '%' . $params['operator_name'] . '%');
- if (!empty($params['resource_id'])) $query->where('a.resource_id', $params['resource_id']);
- if (!empty($params['start_date'])) $query->where('a.created_at', '>=', $params['start_date'] . ' 00:00:00')->where('a.created_at', '<=', $params['end_date'] . ' 23:59:59');
- if (!empty($params['language'])) {
- $language = $params['language'];
- $query->where(function ($q) use ($language) {
- $q->whereNotNull('a.changes->before->translations->' . $language)->orWhereNotNull('a.changes->after->translations->' . $language);
- });
- }
- $total = (clone $query)->count();
- $rows = $query->select('a.*')->orderByDesc('a.created_at')->orderByDesc('a.id')
- ->forPage((int) ($params['page'] ?? 1), (int) ($params['limit'] ?? 20))->get();
- $items = [];
- foreach ($rows as $row) {
- $change = json_decode($row->changes, true, 512, JSON_THROW_ON_ERROR);
- $before = $change['before'] ?? []; $after = $change['after'] ?? [];
- $translations = array_replace($before['translations'] ?? [], $after['translations'] ?? []);
- $titles = array_map(fn ($block) => $block['title'], $translations);
- $old = []; $new = [];
- foreach (array_unique(array_merge(array_keys($before), array_keys($after))) as $field) {
- if (in_array($field, ['id', 'created_at', 'updated_at', 'request_hash', 'request_id'], true)) continue;
- $a = $before[$field] ?? null; $b = $after[$field] ?? null;
- if ($field === 'translations' && !empty($params['language'])) {
- $a = isset($a[$params['language']]) ? [$params['language'] => $a[$params['language']]] : null;
- $b = isset($b[$params['language']]) ? [$params['language'] => $b[$params['language']]] : null;
- }
- if ($a !== $b) { $old[$field] = $a; $new[$field] = $b; }
- }
- $recipientType = $after['recipient_type'] ?? $before['recipient_type'] ?? 'all_users';
- $items[] = ['id' => (int) $row->id, 'resource_id' => (int) $row->resource_id,
- 'created_at' => $row->created_at, 'operator_name' => $row->operator_name, 'action' => $row->action,
- 'languages' => array_keys($translations), 'titles' => (object) $titles,
- 'recipient_type' => $recipientType,
- 'recipient_label' => $type === 'announcement' ? '所有人' : (SiteMessageService::TARGETS[$recipientType] ?? ''),
- 'old_values' => (object) $old, 'new_values' => (object) $new];
- }
- return ['total' => $total, 'data' => $items];
- }
- }
|