Files
saasshop/resources/views/admin/platform_batches/show.blade.php

184 lines
8.8 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.
@extends('admin.layouts.app')
@section('title', '批次详情')
@section('page_title', '批次详情')
@section('content')
@php
$typeText = $type === 'bas' ? 'BAS批量同步订阅' : ($type === 'bmpa' ? 'BMPA批量标记支付并生效' : '未知');
$selfWithoutBack = \App\Support\BackUrl::selfWithoutBack();
$backToListUrl = $safeBackForLinks !== '' ? $safeBackForLinks : '/admin/platform-orders';
$hasSummary = $summary !== null;
$success = (int) (data_get($summary, 'success') ?? 0);
$failed = (int) (data_get($summary, 'failed') ?? 0);
$matched = (int) (data_get($summary, 'matched') ?? 0);
$processed = (int) (data_get($summary, 'processed') ?? 0);
$at = (string) (data_get($summary, 'at') ?? '');
$topReasons = (array) (data_get($summary, 'top_reasons', []) ?? []);
$fallbackMatched = (int) (data_get($fallbackCounts, 'matched') ?? 0);
$fallbackFailed = (int) (data_get($fallbackCounts, 'failed') ?? 0);
$matchedForRatio = $hasSummary ? $matched : $fallbackMatched;
$failedForRatio = $hasSummary ? $failed : $fallbackFailed;
$failedRatioPct = $matchedForRatio > 0 ? round(($failedForRatio / $matchedForRatio) * 100, 1) : 0.0;
$SYNC_ERROR_KEYWORD_LINK_MAX_LEN = (int) config('saasshop.platform_orders.sync_error_keyword_link_max_len', 200);
$SYNC_ERROR_KEYWORD_LINK_MAX_LEN = max(50, min(1000, $SYNC_ERROR_KEYWORD_LINK_MAX_LEN));
$SYNC_FAILED_REASON_TRUNCATE_LEN = (int) config('saasshop.platform_orders.sync_failed_reason_display_truncate_len', 60);
$SYNC_FAILED_REASON_TRUNCATE_LEN = max(20, min(200, $SYNC_FAILED_REASON_TRUNCATE_LEN));
@endphp
<div class="card mb-20">
<div class="actions-spread">
<div>
<h2 class="mb-6">{{ $typeText }} 批次详情</h2>
<div class="muted">run_id<strong>{{ $runId ?: '-' }}</strong></div>
@if($at !== '')
<div class="muted muted-xs">更新时间:{{ $at }}</div>
@endif
</div>
<div class="actions gap-10">
<a class="btn btn-secondary btn-sm" href="{{ $backToListUrl }}">返回上一页</a>
@if($runId !== '')
<button type="button" class="btn btn-secondary btn-sm" data-action="copy-run-id" data-run-id="{{ $runId }}">复制 run_id</button>
@endif
<a class="btn btn-secondary btn-sm" href="/admin/platform-batches/show?type={{ $type }}&run_id={{ urlencode($runId) }}&back={{ urlencode($selfWithoutBack) }}">刷新</a>
</div>
</div>
</div>
@if(($error ?? '') !== '')
<div class="warning">{{ $error }}</div>
@else
@if(! $hasSummary)
<div class="warning mb-20">
本批次尚未生成 last_result 汇总(可能队列任务仍在执行,或历史数据未补齐)。
当前页面展示的是基于同批次订单的<strong>粗略统计</strong>,供运营先行定位。
</div>
@endif
<div class="grid-3 mb-20">
<div class="card">
<h3>命中</h3>
<div class="metric-number">
@if(($governanceLinks['all'] ?? '') !== '')
<a class="link" data-role="batch-matched-link" href="{{ $governanceLinks['all'] }}">{{ $hasSummary ? $matched : $fallbackMatched }}</a>
@else
{{ $hasSummary ? $matched : $fallbackMatched }}
@endif
</div>
</div>
<div class="card">
<h3>本次处理</h3>
<div class="metric-number">
@if($hasSummary && ($governanceLinks['all'] ?? '') !== '')
<a class="link" data-role="batch-processed-link" href="{{ $governanceLinks['all'] }}">{{ $processed }}</a>
@else
{{ $hasSummary ? $processed : '-' }}
@endif
</div>
</div>
<div class="card">
<h3>成功 / 失败</h3>
<div class="metric-number">{{ $hasSummary ? ($success . ' / ' . $failed) : ('- / ' . $fallbackFailed) }}</div>
@if(($governanceLinks['failed'] ?? '') !== '' && $matchedForRatio > 0)
<div class="muted muted-xs">失败占比:
<a class="link" data-role="batch-failed-ratio-link" href="{{ $governanceLinks['failed'] }}">{{ $failedRatioPct }}%</a>
<span class="muted">{{ $failedForRatio }}/{{ $matchedForRatio }}</span>
</div>
@endif
</div>
</div>
<div class="card mb-20">
<h3>一键治理入口</h3>
<div class="inline-links">
@if(($governanceLinks['all'] ?? '') !== '')
<a class="link" href="{{ $governanceLinks['all'] }}">本批次全部</a>
@endif
@if(($governanceLinks['failed'] ?? '') !== '')
<span class="muted"></span>
<a class="link" href="{{ $governanceLinks['failed'] }}">本批次失败</a>
@endif
@if(($governanceLinks['top_reason'] ?? '') !== '')
<span class="muted"></span>
<a class="link" href="{{ $governanceLinks['top_reason'] }}">按Top原因</a>
@endif
@if(($governanceLinks['retry_syncable'] ?? '') !== '')
<span class="muted"></span>
<a class="link" href="{{ $governanceLinks['retry_syncable'] }}">本批次可同步重试</a>
@endif
@if(($governanceLinks['retry_processable'] ?? '') !== '')
<span class="muted"></span>
<a class="link" href="{{ $governanceLinks['retry_processable'] }}">本批次可再次尝试pending+unpaid</a>
@endif
</div>
<div class="muted muted-xs mt-6">说明:当前批次为“冗余写入到每条订单 meta.last_result”的模式后续可演进为独立批次表。</div>
</div>
<div class="card">
<h3>Top 失败原因</h3>
@if(! $hasSummary)
<div class="muted">暂无last_result 未写入时不做原因聚合,以免在页面侧引入重查询)。</div>
@elseif(count($topReasons) === 0)
<div class="muted">暂无。</div>
@else
<table class="table">
<thead>
<tr>
<th>原因</th>
<th style="width: 120px;">次数</th>
</tr>
</thead>
<tbody>
@foreach($topReasons as $r)
@php
$reason = (string) (data_get($r, 'reason') ?? '');
$cnt = (int) (data_get($r, 'count') ?? 0);
$reasonTooLong = mb_strlen($reason) > $SYNC_ERROR_KEYWORD_LINK_MAX_LEN;
$reasonDisplay = $reasonTooLong ? (mb_substr($reason, 0, $SYNC_FAILED_REASON_TRUNCATE_LEN) . '...') : $reason;
$reasonGovUrl = '';
if (! $reasonTooLong && $reason !== '') {
if ($type === 'bas') {
$reasonGovUrl = \App\Support\BackUrl::withBackAndFragment('/admin/platform-orders?' . \Illuminate\Support\Arr::query([
'batch_activation_run_id' => $runId,
'sync_status' => 'failed',
'sync_error_keyword' => $reason,
]), $safeBackForLinks, 'filters');
}
if ($type === 'bmpa') {
$reasonGovUrl = \App\Support\BackUrl::withBackAndFragment('/admin/platform-orders?' . \Illuminate\Support\Arr::query([
'batch_bmpa_run_id' => $runId,
'bmpa_failed_only' => '1',
'bmpa_error_keyword' => $reason,
]), $safeBackForLinks, 'filters');
}
}
@endphp
<tr>
<td>
@if($reasonGovUrl !== '')
<a class="link" data-role="batch-top-reason-link" href="{{ $reasonGovUrl }}" title="按该原因筛选">{{ $reasonDisplay }}</a>
@else
<span title="{{ $reason }}">{{ $reasonDisplay !== '' ? $reasonDisplay : '-' }}</span>
@if($reasonTooLong)
<div class="muted muted-xs text-danger">原因过长,请复制到列表页筛选框</div>
@endif
@endif
</td>
<td>{{ $cnt }}</td>
</tr>
@endforeach
</tbody>
</table>
@endif
</div>
@endif
@endsection