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

232 lines
12 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="muted muted-xs">提示:点击数字可进入对应集合(成功=可抽样复核)。</div>
<div class="metric-number">
@if($hasSummary)
@php
$successLink = (string) ($governanceLinks['success'] ?? ($governanceLinks['all'] ?? ''));
@endphp
@if($successLink !== '')
<a class="link" data-role="batch-success-count-link" href="{{ $successLink }}">{{ $success }}</a>
@else
{{ $success }}
@endif
<span class="muted"> / </span>
@if(($governanceLinks['failed'] ?? '') !== '')
<a class="link text-danger" data-role="batch-failed-count-link" href="{{ $governanceLinks['failed'] }}">{{ $failed }}</a>
@else
{{ $failed }}
@endif
@else
<span class="muted">- / </span>
@if(($governanceLinks['failed'] ?? '') !== '')
<a class="link text-danger" data-role="batch-failed-count-link" href="{{ $governanceLinks['failed'] }}">{{ $fallbackFailed }}</a>
@else
{{ $fallbackFailed }}
@endif
@endif
</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" data-role="platform-batch-spot-check">
<h3>抽样复核</h3>
@if(($spotCheck['url'] ?? '') !== '')
<div class="actions gap-10">
<a class="btn btn-secondary btn-sm" data-role="batch-spot-check-link" href="{{ $spotCheck['url'] }}">{{ $spotCheck['label'] ?? '抽样复核' }}</a>
<button type="button" class="btn btn-secondary btn-xs" data-action="copy-link" data-role="copy-spot-check-link" data-label="{{ $spotCheck['label'] ?? '抽样复核' }}" data-href="{{ $spotCheck['url'] }}">复制链接</button>
<span class="muted muted-xs">(从本批次成功集合抽一单,用于 spot-check</span>
</div>
@else
<div class="muted">暂无可抽样订单(可能暂无成功单,或 last_result 尚未补齐)。</div>
@endif
</div>
<div class="card mb-20">
<h3>一键治理入口</h3>
<div class="inline-links">
@if(($governanceLinks['all'] ?? '') !== '')
<a class="link" href="{{ $governanceLinks['all'] }}">本批次全部</a>
<button type="button" class="btn btn-secondary btn-xs" data-action="copy-link" data-role="copy-all-link" data-label="本批次全部" data-href="{{ $governanceLinks['all'] }}">复制链接</button>
@endif
@if(($governanceLinks['success'] ?? '') !== '')
<span class="muted"></span>
<a class="link" href="{{ $governanceLinks['success'] }}">本批次成功</a>
<button type="button" class="btn btn-secondary btn-xs" data-action="copy-link" data-role="copy-success-link" data-label="本批次成功" data-href="{{ $governanceLinks['success'] }}">复制链接</button>
@endif
@if(($governanceLinks['failed'] ?? '') !== '')
<span class="muted"></span>
<a class="link" href="{{ $governanceLinks['failed'] }}">本批次失败</a>
<button type="button" class="btn btn-secondary btn-xs" data-action="copy-link" data-role="copy-failed-link" data-label="本批次失败" data-href="{{ $governanceLinks['failed'] }}">复制链接</button>
@endif
@if(($governanceLinks['top_reason'] ?? '') !== '')
<span class="muted"></span>
<a class="link" href="{{ $governanceLinks['top_reason'] }}">按Top原因</a>
<button type="button" class="btn btn-secondary btn-xs" data-action="copy-link" data-role="copy-top-reason-link" data-label="按Top原因" data-href="{{ $governanceLinks['top_reason'] }}">复制链接</button>
@endif
@if(($governanceLinks['retry_syncable'] ?? '') !== '')
<span class="muted"></span>
<a class="link" href="{{ $governanceLinks['retry_syncable'] }}">本批次可同步重试</a>
<button type="button" class="btn btn-secondary btn-xs" data-action="copy-link" data-role="copy-retry-syncable-link" data-label="本批次可同步重试" data-href="{{ $governanceLinks['retry_syncable'] }}">复制链接</button>
@endif
@if(($governanceLinks['retry_processable'] ?? '') !== '')
<span class="muted"></span>
<a class="link" href="{{ $governanceLinks['retry_processable'] }}">本批次可再次尝试可BMPA处理</a>
<button type="button" class="btn btn-secondary btn-xs" data-action="copy-link" data-role="copy-retry-processable-link" data-label="本批次可再次尝试" data-href="{{ $governanceLinks['retry_processable'] }}">复制链接</button>
@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