feat: 主体维度经营报表无数据月份列默认隐藏 (#280)
This commit is contained in:
parent
5d7bc3f2c4
commit
5ef4119a3d
@ -296,6 +296,12 @@ SQL);
|
||||
}
|
||||
unset($row);
|
||||
|
||||
// 所有主体该月收入均为空时,该月份列在页面上默认隐藏;「筛选字段」中仍保留勾选项,可手动选出来。
|
||||
request()->attributes->set(
|
||||
'subject-operating-report.default_hidden_columns',
|
||||
$this->subjectReportColumnsWithoutData($rows),
|
||||
);
|
||||
|
||||
$rows = array_values(array_filter($rows, fn (array $row): bool => $this->subjectMatchesFilters($row, $filters)));
|
||||
$this->sortSubjectRows($rows, $filters);
|
||||
$offset = ($page - 1) * $perPage;
|
||||
@ -304,6 +310,34 @@ SQL);
|
||||
return ['data' => $pageRows, 'total' => count($rows)];
|
||||
}
|
||||
|
||||
/**
|
||||
* 没有数据的月份列:全部主体该月收入都为空(null/空字符串)时才视为没有数据。
|
||||
* 金额为 0 的月份代表当月有账单,不隐藏。
|
||||
*
|
||||
* @param array<int,array<string,mixed>> $rows
|
||||
* @return array<int,string>
|
||||
*/
|
||||
private function subjectReportColumnsWithoutData(array $rows): array
|
||||
{
|
||||
$columns = [];
|
||||
|
||||
for ($month = 1; $month <= 12; $month++) {
|
||||
$key = sprintf('income_%02d', $month);
|
||||
foreach ($rows as $row) {
|
||||
$value = $row[$key] ?? null;
|
||||
if ($value === null || $value === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
continue 2;
|
||||
}
|
||||
|
||||
$columns[] = $key;
|
||||
}
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/** @param array<string,mixed> $row @param array<string,string> $filters */
|
||||
private function subjectMatchesFilters(array $row, array $filters): bool
|
||||
{
|
||||
|
||||
@ -1125,7 +1125,15 @@
|
||||
array_filter(explode(',', (string) request('columns', ''))),
|
||||
$directoryColumnNames,
|
||||
));
|
||||
$visibleDirectoryColumns = request()->has('columns') ? $requestedDirectoryColumns : $directoryColumnNames;
|
||||
// 主体维度经营报表:没有数据的月份列默认隐藏,仍保留在「筛选字段」中供手动勾选显示。
|
||||
$directoryDefaultColumns = $directoryColumnNames;
|
||||
if ($directoryPageKey === 'company-management/subject-operating-report') {
|
||||
$directoryDefaultColumns = array_values(array_diff(
|
||||
$directoryColumnNames,
|
||||
(array) request()->attributes->get('subject-operating-report.default_hidden_columns', []),
|
||||
));
|
||||
}
|
||||
$visibleDirectoryColumns = request()->has('columns') ? $requestedDirectoryColumns : $directoryDefaultColumns;
|
||||
$directoryQueryFormId = 'directory-query-form-' . ($page['slug'] ?? 'page');
|
||||
@endphp
|
||||
@if ($directoryUsesFieldQuery)
|
||||
@ -1251,7 +1259,7 @@
|
||||
@endif
|
||||
<div class="directory-query-actions">
|
||||
<details class="directory-query-picker" data-directory-query-picker>
|
||||
<summary>筛选字段</summary>
|
||||
<summary>筛选字段{{ count($visibleDirectoryColumns) < count($directoryFields) ? ' ' . count($visibleDirectoryColumns) . '/' . count($directoryFields) : '' }}</summary>
|
||||
<div class="directory-query-picker__panel" role="group" aria-label="勾选展示字段">
|
||||
<span class="directory-query-picker__hint">勾选需要显示的表头,可重复调整。</span>
|
||||
@foreach ($directoryFields as $field)
|
||||
|
||||
@ -530,8 +530,10 @@
|
||||
label.draggable = true;
|
||||
const key = header.dataset.financeColumnKey;
|
||||
const fixed = Boolean(header.dataset.financeFixed);
|
||||
// 服务端按业务规则默认隐藏的列(如无数据的月份)保持取消勾选,可在这里手动选出来。
|
||||
const visible = fixed || !header.classList.contains('is-column-hidden');
|
||||
label.dataset.financeOptionKey = key;
|
||||
label.innerHTML = `<input type="checkbox" value="${key.replaceAll('"', '"')}" data-finance-field-check ${fixed ? 'checked disabled' : 'checked'}><span>${header.textContent.trim() || '未命名字段'}</span>`;
|
||||
label.innerHTML = `<input type="checkbox" value="${key.replaceAll('"', '"')}" data-finance-field-check ${fixed ? 'checked disabled' : (visible ? 'checked' : '')}><span>${header.textContent.trim() || '未命名字段'}</span>`;
|
||||
panel.appendChild(label);
|
||||
});
|
||||
const actions = document.createElement('div');
|
||||
|
||||
@ -142,4 +142,60 @@ class PrototypePageTest extends FeatureTestCase
|
||||
->assertOk()
|
||||
->assertSeeTextInOrder(['最近12个月累计收入', '1月收入', '12月收入']);
|
||||
}
|
||||
|
||||
public function testSubjectOperatingReportHidesMonthsWithoutDataAndKeepsThemSelectable(): void
|
||||
{
|
||||
$service = Mockery::mock(UpstreamBusinessInformation::class);
|
||||
$service->shouldReceive('paginate')->with('company-management', 'subject-operating-report', 50)
|
||||
->andReturnUsing(function (): LengthAwarePaginator {
|
||||
request()->attributes->set(
|
||||
'subject-operating-report.default_hidden_columns',
|
||||
['income_01', 'income_02'],
|
||||
);
|
||||
|
||||
return new LengthAwarePaginator([(object) [
|
||||
'entity' => '测试主体',
|
||||
'city' => '常州市',
|
||||
'company_type' => '有限公司',
|
||||
'rolling_12m_income' => 100,
|
||||
'income_01' => null,
|
||||
'income_02' => null,
|
||||
'income_03' => 50,
|
||||
'can_change_entity' => null,
|
||||
'plan' => null,
|
||||
'new_entity' => null,
|
||||
]], 1, 50, 1, ['path' => '/']);
|
||||
});
|
||||
$this->app->instance(UpstreamBusinessInformation::class, $service);
|
||||
|
||||
$response = $this->loginAs()->get(route('business.pages.show', [
|
||||
'section' => 'company-management',
|
||||
'page' => 'subject-operating-report',
|
||||
]));
|
||||
|
||||
$response->assertOk();
|
||||
$html = $response->getContent();
|
||||
|
||||
// 没有数据的月份默认隐藏,但表头和「筛选字段」勾选项仍在页面中。
|
||||
$this->assertMatchesRegularExpression('/data-column-key="income_01"[^>]*is-column-hidden/', $html);
|
||||
$this->assertMatchesRegularExpression('/data-column-key="income_02"[^>]*is-column-hidden/', $html);
|
||||
$this->assertDoesNotMatchRegularExpression('/data-column-key="income_03"[^>]*is-column-hidden/', $html);
|
||||
$this->assertStringContainsString('value="income_01" data-directory-query-column', $html);
|
||||
$this->assertStringNotContainsString('value="income_01" data-directory-query-column checked', $html);
|
||||
$this->assertStringContainsString('value="income_03" data-directory-query-column checked', $html);
|
||||
$this->assertStringContainsString('筛选字段 17/19', $html);
|
||||
|
||||
// 手动勾选(columns 参数)后,对应月份列恢复显示。
|
||||
$restored = $this->get(route('business.pages.show', [
|
||||
'section' => 'company-management',
|
||||
'page' => 'subject-operating-report',
|
||||
'columns' => 'city,entity,company_type,rolling_12m_income,income_01,income_03',
|
||||
]));
|
||||
|
||||
$restored->assertOk();
|
||||
$restoredHtml = $restored->getContent();
|
||||
$this->assertDoesNotMatchRegularExpression('/data-column-key="income_01"[^>]*is-column-hidden/', $restoredHtml);
|
||||
$this->assertDoesNotMatchRegularExpression('/data-column-key="income_03"[^>]*is-column-hidden/', $restoredHtml);
|
||||
$this->assertMatchesRegularExpression('/data-column-key="income_04"[^>]*is-column-hidden/', $restoredHtml);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,8 @@ use Closure;
|
||||
use Mockery;
|
||||
use Modules\EcommerceFinance\Repositories\BusinessInformationMirrorRepository;
|
||||
use Modules\EcommerceFinance\Repositories\InstallationDetailMirrorRepository;
|
||||
use Modules\EcommerceFinance\Repositories\StoreAccountMirrorRepository;
|
||||
use Modules\EcommerceFinance\Repositories\StoreReportRepository;
|
||||
use Modules\EcommerceFinance\Services\UpstreamQueryCache;
|
||||
use Modules\EcommerceFinance\Services\UpstreamQueryCacheFactory;
|
||||
use Tests\TestCase;
|
||||
@ -123,6 +125,54 @@ class UpstreamBusinessInformationTest extends TestCase
|
||||
->paginate('store-management', 'basic-information');
|
||||
}
|
||||
|
||||
public function test_subject_operating_report_hides_income_months_without_data_by_default(): void
|
||||
{
|
||||
$mirror = Mockery::mock(BusinessInformationMirrorRepository::class);
|
||||
$mirror->shouldReceive('ready')->with('store-information.read')->andReturnTrue();
|
||||
$mirror->shouldReceive('allStores')->andReturn([['erp_store_name' => '测试店铺']]);
|
||||
$mirror->shouldReceive('ready')->with('company-information.read')->andReturnTrue();
|
||||
$mirror->shouldReceive('companiesByNames')->andReturn([]);
|
||||
|
||||
$storeReports = Mockery::mock(StoreReportRepository::class);
|
||||
$storeReports->shouldReceive('rows')->andReturn([[
|
||||
'entity' => '测试主体',
|
||||
'company_type' => '店铺-普通公司',
|
||||
'rolling_12m_income' => 188.5,
|
||||
'income_01' => null,
|
||||
'income_02' => 88.5,
|
||||
'income_03' => 0.0,
|
||||
'income_04' => null,
|
||||
'income_05' => null,
|
||||
'income_06' => null,
|
||||
'income_07' => null,
|
||||
'income_08' => null,
|
||||
'income_09' => null,
|
||||
'income_10' => null,
|
||||
'income_11' => null,
|
||||
'income_12' => null,
|
||||
]]);
|
||||
$storeAccounts = Mockery::mock(StoreAccountMirrorRepository::class);
|
||||
$storeAccounts->shouldReceive('ownershipByStoreName')->andReturn([]);
|
||||
|
||||
$information = new UpstreamBusinessInformation(
|
||||
Mockery::mock(UpstreamQueryCacheFactory::class),
|
||||
$mirror,
|
||||
Mockery::mock(InstallationDetailMirrorRepository::class),
|
||||
$storeReports,
|
||||
$storeAccounts,
|
||||
);
|
||||
|
||||
$paginator = $information->paginate('company-management', 'subject-operating-report', 50);
|
||||
|
||||
// income_02 有金额、income_03 为 0 都算有数据,其余空月份默认隐藏。
|
||||
$this->assertSame(
|
||||
['income_01', 'income_04', 'income_05', 'income_06', 'income_07', 'income_08', 'income_09', 'income_10', 'income_11', 'income_12'],
|
||||
$this->app['request']->attributes->get('subject-operating-report.default_hidden_columns'),
|
||||
);
|
||||
$this->assertSame(1, $paginator->total());
|
||||
$this->assertSame('测试主体', $paginator->items()[0]->entity);
|
||||
}
|
||||
|
||||
public static function businessInformationPages(): array
|
||||
{
|
||||
return [
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user