CaiWuXiTong/app/Business/BusinessSummaryCards.php
DoDo d0979879e7 fix: 精简店铺销量汇总卡片
店铺报表仅保留正常存续店铺数、上月销量、当月销量三个汇总框。
2026-10-26 16:44:05 +08:00

170 lines
8.5 KiB
PHP

<?php
namespace App\Business;
/**
* 经营报表页面顶部的小格子指标。
*
* 汇总卡片只描述当前表本身,不把其他目录的数据拼成跨表大看板。
*/
class BusinessSummaryCards
{
/**
* @param array<string,mixed> $summary
* @return list<array{label:string,value:mixed,hint:string,format:string,query:array<string,mixed>,tone:string}>
*/
public function forPage(string $key, array $summary = []): array
{
return match ($key) {
'store-management/store-report' => $summary === [] ? [] : $this->storeReportCards($summary),
'company-management/subject-operating-report' => $summary === [] ? [] : $this->subjectOperatingReportCards($summary),
'store-management/internal-flow-report' => $summary === [] ? [] : $this->internalFlowReportCards($summary),
'company-management/company-cost-arrangement' => $this->companyCostArrangementCards(),
'company-management/tax-forecast' => $this->taxForecastCards(),
'company-management/personnel-inventory' => $this->personnelInventoryCards(),
default => [],
};
}
/** @param array<string,mixed> $summary */
private function subjectOperatingReportCards(array $summary): array
{
$ready = (bool) ($summary['company_status_ready'] ?? false);
$previousLabel = (string) ($summary['previous_month_label'] ?? '上月');
$currentLabel = (string) ($summary['current_month_label'] ?? '当月');
$previousStores = (int) ($summary['previous_income_entities'] ?? 0);
$currentStores = (int) ($summary['current_income_entities'] ?? 0);
if (! $ready) {
return [
$this->card('正常存续主体', '—', '公司资料镜像未就绪,暂时无法剔除注销主体', [], 'text', 'warning'),
$this->card('上月收入', '—', '公司资料镜像未就绪', [], 'text', 'warning'),
$this->card('当月收入', '—', '公司资料镜像未就绪', [], 'text', 'warning'),
$this->card('小规模纳税人', '—', '公司资料镜像未就绪', [], 'text'),
$this->card('一般纳税人', '—', '公司资料镜像未就绪', [], 'text'),
];
}
return [
$this->card('正常存续主体', $summary['normal'] ?? 0, '只统计公司台账标签为保留的主体', ['company_status' => '正常'], 'integer', 'accent'),
$this->card($previousLabel . '收入', $summary['previous_income'] ?? 0, $previousStores . ' 个存续主体有收入', [
'company_status' => '正常',
'sort' => $summary['previous_month_key'] ?? null,
'direction' => 'desc',
], 'amount', 'success'),
$this->card($currentLabel . '收入', $summary['current_month_income'] ?? 0, $currentStores . ' 个存续主体有收入', [
'company_status' => '正常',
'sort' => $summary['current_month_key'] ?? null,
'direction' => 'desc',
], 'amount', 'warning'),
$this->card('小规模纳税人', $summary['small_taxpayer'] ?? 0, '正常存续主体中的小规模纳税人', [
'company_status' => '正常',
'tax_type' => '小规模纳税人',
]),
$this->card('一般纳税人', $summary['general_taxpayer'] ?? 0, '正常存续主体中的一般纳税人', [
'company_status' => '正常',
'tax_type' => '一般纳税人',
]),
];
}
/** @param array<string,mixed> $summary */
private function storeReportCards(array $summary): array
{
$previousLabel = (string) ($summary['previous_month_label'] ?? '上月');
$currentLabel = (string) ($summary['current_month_label'] ?? '当月');
$normalStores = (int) ($summary['normal_stores'] ?? 0);
$previousStores = (int) ($summary['previous_month_stores'] ?? 0);
$currentStores = (int) ($summary['current_month_stores'] ?? 0);
return [
$this->card('正常存续店铺', $normalStores, '只统计开店中店铺,不含关店和已注销', ['status' => '0'], 'integer', 'accent'),
$this->card($previousLabel . '销量', $summary['previous_month_sales'] ?? 0, $previousStores . ' 家存续店铺有销量', [
'status' => '0',
'sort' => $summary['previous_month_key'] ?? null,
'direction' => 'desc',
], 'amount', 'success'),
$this->card($currentLabel . '销量', $summary['current_month_sales'] ?? 0, $currentStores . ' 家存续店铺有销量', [
'status' => '0',
'sort' => $summary['current_month_key'] ?? null,
'direction' => 'desc',
], 'amount', 'warning'),
];
}
/** @param array<string,mixed> $summary */
private function internalFlowReportCards(array $summary): array
{
return [
$this->card('公司数', $summary['companies'] ?? 0, '当前筛选内内部流转公司', [], 'integer', 'accent'),
$this->card('预计销量合计', $summary['projected_sales'] ?? 0, '当前筛选内预计销量合计', [
'sort' => 'projected_sales',
'direction' => 'desc',
], 'amount'),
$this->card('已收票合计', $summary['receipt_total'] ?? 0, '供应商、关联公司与内部流转收票合计', [
'sort' => 'receipt_total',
'direction' => 'desc',
], 'amount', 'success'),
$this->card('剩余缺口合计', $summary['remaining_gap'] ?? 0, '金额越大越应优先处理', [
'sort' => 'remaining_gap',
'direction' => 'desc',
], 'amount', 'warning'),
$this->card('平均开票比例', $summary['average_invoicing_ratio'] ?? 0, '按有比例的公司简单平均', [], 'percent'),
];
}
private function companyCostArrangementCards(): array
{
return [
$this->card('数据状态', '待接入', '当前表尚无业务数据', [], 'text', 'warning'),
$this->card('完整表头', '11 列', '包含序号,收入、成本、税金、人工等字段全部保留', [], 'text'),
$this->card('核心结果', '预计结余 / 缺口', '当月收入预测减去成本与费用', [], 'text'),
$this->card('缺口提示', '负值标红', '成本或费用未覆盖收入时提醒', [], 'text', 'danger'),
$this->card('配平提示', '零或正结余标绿', '表示当月预算已覆盖', [], 'text', 'success'),
];
}
private function taxForecastCards(): array
{
return [
$this->card('数据状态', '待取数', '规则已定义,业务数据尚未接入', [], 'text', 'warning'),
$this->card('完整表头', '22 列', '包含序号、征管口径、收入、税额与备注', [], 'text'),
$this->card('计算税种', '4 类', '增值税、附加税、印花税、所得税', [], 'text'),
$this->card('计税口径', '3 项', '公司税务类型、工商类型和征收方式', [], 'text'),
$this->card('当前记录', '0 条', '数据接入后按完整字段展示', [], 'text'),
];
}
private function personnelInventoryCards(): array
{
return [
$this->card('数据状态', '待接入', '当前表尚无人员数据', [], 'text', 'warning'),
$this->card('完整表头', '17 列', '包含序号和全部人员、容量字段', [], 'text'),
$this->card('敏感字段', '4 项', '密码、身份证、实名手机和身份证地址只显示维护状态', [], 'text', 'danger'),
$this->card('容量规则', '3 档', '可担任公司数量按风险档位提示', [], 'text'),
$this->card('当前记录', '0 条', '接入后按正常在职人员汇总', [], 'text'),
];
}
/**
* @return array{label:string,value:mixed,hint:string,format:string,query:array<string,mixed>,tone:string}
*/
private function card(
string $label,
mixed $value,
string $hint,
array $query = [],
string $format = 'integer',
string $tone = 'neutral',
): array {
return [
'label' => $label,
'value' => $value,
'hint' => $hint,
'format' => $format,
'query' => ['page' => null, ...$query],
'tone' => $tone,
];
}
}