fix: 流程明细恢复真实镜像数据 (#630)

This commit is contained in:
yueyang 2026-10-26 18:44:33 +08:00
parent a8c2169134
commit eda75f96a9
3 changed files with 159 additions and 4 deletions

View File

@ -0,0 +1,86 @@
<?php
namespace Modules\EcommerceFinance\View;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Modules\EcommerceFinance\Repositories\DingProcessDetailMirrorRepository;
use Throwable;
class ProcessDetailsPageData
{
public function __construct(
private readonly DingProcessDetailMirrorRepository $repository,
) {}
/** @return array<string,mixed> */
public function page(Request $request): array
{
$filters = $this->filters($request);
$page = max((int) $request->query('page', 1), 1);
$perPage = 50;
try {
$result = $this->repository->paginate($filters, $page, $perPage);
$options = $this->repository->filterOptions();
return [
'processRows' => new LengthAwarePaginator(
$result['data'],
$result['total'],
$perPage,
$page,
['path' => $request->url(), 'query' => $request->except('page')],
),
'filters' => $filters,
'summary' => $result['summary'],
'months' => $options['months'],
'documentTypes' => $options['document_types'],
'statuses' => $options['statuses'],
'mirrorStatus' => $result['status'],
'mirrorSyncedAt' => $result['last_synced_at'],
'scope' => $result['scope'],
'error' => null,
];
} catch (Throwable $exception) {
report($exception);
return [
'processRows' => new LengthAwarePaginator([], 0, $perPage, $page, [
'path' => $request->url(),
'query' => $request->except('page'),
]),
'filters' => $filters,
'summary' => [
'rows' => 0,
'approvals' => 0,
'amount_total' => 0.0,
'bank_amount_total' => 0.0,
],
'months' => [],
'documentTypes' => [],
'statuses' => [],
'mirrorStatus' => 'unavailable',
'mirrorSyncedAt' => null,
'scope' => $this->repository->scope(),
'error' => '流程明细镜像尚未完成导入,请稍后重试。',
];
}
}
/** @return array<string,string> */
private function filters(Request $request): array
{
$month = trim((string) $request->query('month', ''));
$status = trim((string) $request->query('status', ''));
return [
'month' => preg_match('/^\d{4}-\d{2}$/', $month) === 1 ? $month : '',
'document_type' => mb_substr(trim((string) $request->query('document_type', '')), 0, 100),
'status' => mb_substr($status, 0, 20),
'business_id' => mb_substr(trim((string) $request->query('business_id', '')), 0, 32),
'originator_name' => mb_substr(trim((string) $request->query('originator_name', '')), 0, 100),
'keyword' => mb_substr(trim((string) $request->query('keyword', '')), 0, 100),
];
}
}

View File

@ -1,10 +1,17 @@
@php
$processRows = $processRows ?? null;
if (! $processRows instanceof \Illuminate\Contracts\Pagination\LengthAwarePaginator) {
$fallbackRows = $rows ?? null;
$processRows = $fallbackRows instanceof \Illuminate\Contracts\Pagination\LengthAwarePaginator
? $fallbackRows
: new \Illuminate\Pagination\LengthAwarePaginator([], 0, 50);
$pageData = app(\Modules\EcommerceFinance\View\ProcessDetailsPageData::class)->page(request());
$processRows = $pageData['processRows'];
$filters = $pageData['filters'];
$summary = $pageData['summary'];
$months = $pageData['months'];
$documentTypes = $pageData['documentTypes'];
$statuses = $pageData['statuses'];
$mirrorStatus = $pageData['mirrorStatus'];
$mirrorSyncedAt = $pageData['mirrorSyncedAt'];
$scope = $pageData['scope'];
$error = $pageData['error'];
}
$filters = $filters ?? [];
$summary = $summary ?? [];

View File

@ -0,0 +1,62 @@
<?php
namespace Tests\Unit\EcommerceFinance;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Modules\EcommerceFinance\Repositories\DingProcessDetailMirrorRepository;
use Modules\EcommerceFinance\View\ProcessDetailsPageData;
use PHPUnit\Framework\TestCase;
class ProcessDetailsPageDataTest extends TestCase
{
public function test_page_data_contains_real_paginator_filters_and_summary(): void
{
$row = (object) [
'business_id' => '202610241052000241951',
'line_no' => 1,
'status' => '审批中',
];
$repository = $this->createMock(DingProcessDetailMirrorRepository::class);
$repository->expects($this->once())
->method('paginate')
->with($this->callback(static fn (array $filters): bool => $filters['month'] === '2026-10'), 2, 50)
->willReturn([
'data' => [$row],
'total' => 11331,
'summary' => [
'rows' => 11331,
'approvals' => 4775,
'amount_total' => 225953332.98,
'bank_amount_total' => 225862410.66,
],
'status' => 'succeeded',
'last_synced_at' => '2026-10-26 16:55:11',
'scope' => 'personal_permission',
]);
$repository->expects($this->once())
->method('filterOptions')
->willReturn([
'months' => ['2026-10'],
'document_types' => ['种菜核销/种菜报销'],
'statuses' => ['审批中'],
]);
$data = (new ProcessDetailsPageData($repository))->page(Request::create(
'/1/workspace/financial-operations/process-details',
'GET',
['month' => '2026-10', 'page' => 2],
));
$this->assertInstanceOf(LengthAwarePaginator::class, $data['processRows']);
$this->assertSame(11331, $data['processRows']->total());
$this->assertSame(50, $data['processRows']->perPage());
$this->assertSame(2, $data['processRows']->currentPage());
$this->assertSame($row, $data['processRows']->items()[0]);
$this->assertSame('succeeded', $data['mirrorStatus']);
$this->assertSame(11331, $data['summary']['rows']);
$this->assertSame(['2026-10'], $data['months']);
$this->assertNull($data['error']);
}
}